cleanup
[enigma2.git] / lib / base / object.h
1 #ifndef __base_object_h
2 #define __base_object_h
3
4 #include <assert.h>
5 #include <lib/base/smartptr.h>
6 #include <lib/base/elock.h>
7
8 //#define OBJECT_DEBUG
9
10 #ifdef OBJECT_DEBUG
11         #include <lib/base/eerror.h>
12 #endif
13
14 typedef int RESULT;
15
16 class iObject
17 {
18 private:
19                 /* we don't allow the default operator here, as it would break the refcount. */
20         void operator=(const iObject &);
21 protected:
22         virtual ~iObject() { }
23 public:
24         virtual void AddRef()=0;
25         virtual void Release()=0;
26 };
27
28 #ifndef SWIG
29         struct oRefCount
30         {
31                 volatile int count;
32                 oRefCount(): count(0) { }
33                 operator volatile int&() { return count; }
34                 ~oRefCount() { 
35         #ifdef OBJECT_DEBUG
36                         if (count) eDebug("OBJECT_DEBUG FATAL: %p has %d references!", this, count); else eDebug("OBJECT_DEBUG refcount ok! (%p)", this); 
37         #endif
38                 }
39         };
40
41         #if defined(OBJECT_DEBUG)
42                 extern int object_total_remaining;
43                 #define DECLARE_REF(x)                  \
44                         private:oRefCount ref;  \
45                                         eSingleLock ref_lock; \
46                         public: void AddRef();          \
47                                         void Release();
48                 #define DEFINE_REF(c) \
49                         void c::AddRef() \
50                         { \
51                                 eSingleLocker l(ref_lock); \
52                                 ++object_total_remaining; \
53                                 ++ref; \
54                                 eDebug("OBJECT_DEBUG " #c "+%p now %d", this, (int)ref); \
55                         } \
56                         void c::Release() \
57                         { \
58                                 { \
59                                         eSingleLocker l(ref_lock); \
60                                         --object_total_remaining; \
61                                         --ref; \
62                                         eDebug("OBJECT_DEBUG " #c "-%p now %d", this, (int)ref); \
63                                 } \
64                                 if (!ref) \
65                                         delete this; \
66                         }
67         #elif defined(__mips__)
68                 #define DECLARE_REF(x)                  \
69                         private: oRefCount ref;         \
70                         public: void AddRef();          \
71                                         void Release();
72                 #define DEFINE_REF(c) \
73                         void c::AddRef() \
74                         { \
75                                 unsigned long temp; \
76                                 __asm__ __volatile__( \
77                                 "               .set    mips3                                                                                   \n" \
78                                 "1:             ll              %0, %1  # load counter                                                  \n" \
79                                 "               .set    mips0                                                                                   \n" \
80                                 "               addu    %0, 1   # increment                                                             \n" \
81                                 "               .set    mips3                                                                                   \n" \
82                                 "               sc              %0, %1  # try to store, checking for atomicity  \n" \
83                                 "               .set    mips0                                                                                   \n" \
84                                 "               beqz    %0, 1b  # if not atomic (0), try again                  \n" \
85                                 : "=&r" (temp), "=m" (ref.count) \
86                                 : "m" (ref.count) \
87                                 : ); \
88                         } \
89                         void c::Release() \
90                         { \
91                                 unsigned long temp; \
92                                 __asm__ __volatile__( \
93                                 "               .set    mips3                           \n" \
94                                 "1:             ll              %0, %1                          \n" \
95                                 "               .set    mips0                           \n" \
96                                 "               subu    %0, 1   # decrement     \n" \
97                                 "               .set    mips3                           \n" \
98                                 "               sc              %0, %1                          \n" \
99                                 "               .set    mips0                           \n" \
100                                 "               beqz    %0, 1b                          \n" \
101                                 : "=&r" (temp), "=m" (ref.count) \
102                                 : "m" (ref.count) \
103                                 : ); \
104                                 if (!ref) \
105                                         delete this; \
106                         }
107         #elif defined(__ppc__)
108                 #define DECLARE_REF(x)                  \
109                         private: oRefCount ref;         \
110                         public: void AddRef();          \
111                                         void Release();
112                 #define DEFINE_REF(c) \
113                         void c::AddRef() \
114                         { \
115                                 int temp; \
116                                 __asm__ __volatile__( \
117                                 "1:             lwarx   %0, 0, %3       \n" \
118                                 "               add             %0, %2, %0      \n" \
119                                 "               dcbt    0, %3           # workaround for PPC405CR Errata\n" \
120                                 "               stwcx.  %0, 0, %3       \n" \
121                                 "               bne-    1b                      \n" \
122                                 : "=&r" (temp), "=m" (ref.count) \
123                                 : "r" (1), "r" (&ref.count), "m" (ref.count) \
124                                 : "cc"); \
125                         } \
126                         void c::Release() \
127                         { \
128                                 int temp; \
129                                 __asm__ __volatile__( \
130                                 "1:             lwarx   %0, 0, %3       \n" \
131                                 "               subf    %0, %2, %0      \n" \
132                                 "               dcbt    0, %3           # workaround for PPC405CR Errata\n" \
133                                 "               stwcx.  %0, 0, %3       \n" \
134                                 "               bne-    1b                      \n" \
135                                 : "=&r" (temp), "=m" (ref.count) \
136                                 : "r" (1), "r" (&ref.count), "m" (ref.count) \
137                                 : "cc"); \
138                                 if (!ref) \
139                                         delete this; \
140                         }
141         #else
142                 #define DECLARE_REF(x)                  \
143                         private:oRefCount ref;  \
144                                         eSingleLock ref_lock; \
145                         public: void AddRef();          \
146                                         void Release();
147                 #define DEFINE_REF(c) \
148                         void c::AddRef() \
149                         { \
150                                 eSingleLocker l(ref_lock); \
151                                 ++ref; \
152                         } \
153                         void c::Release() \
154                         { \
155                                 { \
156                                         eSingleLocker l(ref_lock); \
157                                         --ref; \
158                                 } \
159                                 if (!ref) \
160                                         delete this; \
161                         }
162         #endif
163 #else  // SWIG
164         #define DECLARE_REF(x) \
165                 private: \
166                         void AddRef(); \
167                         void Release();
168         class Object
169         {
170         };
171 #endif  // SWIG
172
173 #endif  // __base_object_h