make inline
[enigma2.git] / lib / base / object.h
index 17178457a6bea914767d13a0cd332ff3589d5d35..adb5d67cbb0304a8bb85b3d0efc81fe9c14eec6d 100644 (file)
@@ -25,30 +25,144 @@ public:
        virtual void Release()=0;
 };
 
-class oRefCount
+struct oRefCount
 {
-       int ref;
-public:
-       oRefCount(): ref(0) { }
-       operator int&() { return ref; }
+       volatile int count;
+       oRefCount(): count(0) { }
+       operator volatile int&() { return count; }
        ~oRefCount() { 
 #ifdef OBJECT_DEBUG
-               if (ref) eDebug("OBJECT_DEBUG FATAL: %p has %d references!", this, ref); else eDebug("OBJECT_DEBUG refcount ok! (%p)", this); 
+               if (count) eDebug("OBJECT_DEBUG FATAL: %p has %d references!", this, ref); else eDebug("OBJECT_DEBUG refcount ok! (%p)", this); 
 #endif
        }
 };
 
 #ifndef SWIG
-#define DECLARE_REF(x) private: eSingleLock ref_lock; oRefCount ref; public: void AddRef(); void Release();
-#ifdef OBJECT_DEBUG
-extern int object_total_remaining;
-#define DEFINE_REF(c) void c::AddRef() { eSingleLocker l(ref_lock); ++object_total_remaining; ++ref; eDebug("OBJECT_DEBUG " #c "+%p now %d", this, (int)ref); } void c::Release() { { eSingleLocker l(ref_lock); --object_total_remaining; --ref; eDebug("OBJECT_DEBUG " #c "-%p now %d", this, ref); } if (!ref) delete this; }
-#error fix locking for debug
-#else
-#define DEFINE_REF(c) void c::AddRef() { eSingleLocker l(ref_lock); ++ref; } void c::Release() { { eSingleLocker l(ref_lock); --ref; } if (!ref) delete this; }
-#endif
+       #if defined(__mips__)
+               #define DECLARE_REF(x)                  \
+                       private: oRefCount ref;         \
+                       public: void AddRef();          \
+                                       void Release();
+               #define DEFINE_REF(c) \
+                       void c::AddRef() \
+                       { \
+                               unsigned long temp; \
+                               __asm__ __volatile__( \
+                               "               .set    mips3                                                                                   \n" \
+                               "1:             ll              %0, %1  # load counter                                                  \n" \
+                               "               .set    mips0                                                                                   \n" \
+                               "               addu    %0, 1   # increment                                                             \n" \
+                               "               .set    mips3                                                                                   \n" \
+                               "               sc              %0, %1  # try to store, checking for atomicity  \n" \
+                               "               .set    mips0                                                                                   \n" \
+                               "               beqz    %0, 1b  # if not atomic (0), try again                  \n" \
+                               : "=&r" (temp), "=m" (ref.count) \
+                               : "m" (ref.count) \
+                               : ); \
+                       } \
+                       void c::Release() \
+                       { \
+                               unsigned long temp; \
+                               __asm__ __volatile__( \
+                               "               .set    mips3                           \n" \
+                               "1:             ll              %0, %1                          \n" \
+                               "               .set    mips0                           \n" \
+                               "               subu    %0, 1   # decrement     \n" \
+                               "               .set    mips3                           \n" \
+                               "               sc              %0, %1                          \n" \
+                               "               .set    mips0                           \n" \
+                               "               beqz    %0, 1b                          \n" \
+                               : "=&r" (temp), "=m" (ref.count) \
+                               : "m" (ref.count) \
+                               : ); \
+                               if (!ref) \
+                                       delete this; \
+                       }
+       #elif defined(__ppc__)
+               #define DECLARE_REF(x)                  \
+                       private: oRefCount ref;         \
+                       public: void AddRef();          \
+                                       void Release();
+               #define DEFINE_REF(c) \
+                       void c::AddRef() \
+                       { \
+                               int temp; \
+                               __asm__ __volatile__( \
+                               "1:             lwarx   %0, 0, %3       \n" \
+                               "               add             %0, %2, %0      \n" \
+                               "               dcbt    0, %3           # workaround for PPC405CR Errata\n" \
+                               "               stwcx.  %0, 0, %3       \n" \
+                               "               bne-    1b                      \n" \
+                               : "=&r" (temp), "=m" (ref.count) \
+                               : "r" (1), "r" (&ref.count), "m" (ref.count) \
+                               : "cc"); \
+                       } \
+                       void c::Release() \
+                       { \
+                               int temp; \
+                               __asm__ __volatile__( \
+                               "1:             lwarx   %0, 0, %3       \n" \
+                               "               subf    %0, %2, %0      \n" \
+                               "               dcbt    0, %3           # workaround for PPC405CR Errata\n" \
+                               "               stwcx.  %0, 0, %3       \n" \
+                               "               bne-    1b                      \n" \
+                               : "=&r" (temp), "=m" (ref.count) \
+                               : "r" (1), "r" (&ref.count), "m" (ref.count) \
+                               : "cc"); \
+                               if (!ref) \
+                                       delete this; \
+                       }
+       #else
+               #define DECLARE_REF(x)                  \
+                       private:oRefCount ref;  \
+                                       eSingleLock ref_lock; \
+                       public: void AddRef();          \
+                                       void Release();
+               #ifdef OBJECT_DEBUG
+                       extern int object_total_remaining;
+                       #define DEFINE_REF(c) \
+                               void c::AddRef() \
+                               { \
+                                       eSingleLocker l(ref_lock); \
+                                       ++object_total_remaining; \
+                                       ++ref; \
+                                       eDebug("OBJECT_DEBUG " #c "+%p now %d", this, ref.count); \
+                               } \
+                               void c::Release() \
+                               { \
+                                       { \
+                                               eSingleLocker l(ref_lock); \
+                                               --object_total_remaining; \
+                                               --ref; \
+                                               eDebug("OBJECT_DEBUG " #c "-%p now %d", this, ref); \
+                                       } \
+                                       if (!ref) \
+                                               delete this; \
+                               }
+                               #error fix locking for debug
+               #else
+                       #define DEFINE_REF(c) \
+                               void c::AddRef() \
+                               { \
+                                       eSingleLocker l(ref_lock); \
+                                       ++ref; \
+                               } \
+                               void c::Release() \
+                               { \
+                                       { \
+                                               eSingleLocker l(ref_lock); \
+                                               --ref; \
+                                       } \
+                                       if (!ref) \
+                                               delete this; \
+                               }
+               #endif
+       #endif
 #else
-#define DECLARE_REF(x) private: void AddRef(); void Release();
+       #define DECLARE_REF(x) \
+               private: \
+                       void AddRef(); \
+                       void Release();
 #endif
 
 #ifdef SWIG