X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/d075c31a89b86975cc2d50d6612252ff3abca566..a6f7c725e21a4b6ed064e92b453331837d12f267:/lib/base/object.h diff --git a/lib/base/object.h b/lib/base/object.h index ed7dda8d..a3268d4f 100644 --- a/lib/base/object.h +++ b/lib/base/object.h @@ -2,14 +2,12 @@ #define __base_object_h #include +#include +#include -// #define OBJECT_DEBUG +//#define OBJECT_DEBUG -#include -#ifdef OBJECT_DEBUG #include -#endif -#include typedef int RESULT; @@ -19,31 +17,67 @@ private: /* we don't allow the default operator here, as it would break the refcount. */ void operator=(const iObject &); protected: + void operator delete(void *p) { ::operator delete(p); } virtual ~iObject() { } -public: +#ifdef SWIG virtual void AddRef()=0; virtual void Release()=0; -}; - -class oRefCount -{ - int ref; +#endif public: - oRefCount(): ref(0) { } - operator int&() { return ref; } - ~oRefCount() { -#ifdef OBJECT_DEBUG - if (ref) eDebug("OBJECT_DEBUG FATAL: %p has %d references!", this, ref); else eDebug("OBJECT_DEBUG refcount ok! (%p)", this); +#ifndef SWIG + virtual void AddRef()=0; + virtual void Release()=0; #endif - } }; #ifndef SWIG - #if defined(__mips__) + struct oRefCount + { + volatile int count; + oRefCount(): count(0) { } + operator volatile int&() { return count; } + ~oRefCount() + { + #ifdef OBJECT_DEBUG + if (count) + eDebug("OBJECT_DEBUG FATAL: %p has %d references!", this, count); + else + eDebug("OBJECT_DEBUG refcount ok! (%p)", this); + #endif + } + }; + + #if defined(OBJECT_DEBUG) + extern int object_total_remaining; #define DECLARE_REF(x) \ - private: oRefCount ref; \ public: void AddRef(); \ - void Release(); + void Release(); \ + private:oRefCount ref; \ + eSingleLock ref_lock; + #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, (int)ref); \ + } \ + if (!ref) \ + delete this; \ + } + #elif defined(__mips__) + #define DECLARE_REF(x) \ + public: void AddRef(); \ + void Release(); \ + private: oRefCount ref; #define DEFINE_REF(c) \ void c::AddRef() \ { \ @@ -57,10 +91,9 @@ public: " sc %0, %1 # try to store, checking for atomicity \n" \ " .set mips0 \n" \ " beqz %0, 1b # if not atomic (0), try again \n" \ - " nop # branch-delay slot \n" \ - : "=&r" (temp), "=m" ((int)ref) \ - : "m" ((int)ref) \ - : "memory"); \ + : "=&r" (temp), "=m" (ref.count) \ + : "m" (ref.count) \ + : ); \ } \ void c::Release() \ { \ @@ -74,18 +107,17 @@ public: " sc %0, %1 \n" \ " .set mips0 \n" \ " beqz %0, 1b \n" \ - " nop \n" \ - : "=&r" (temp), "=m" ((int)ref) \ - : "m" ((int)ref) \ - : "memory"); \ + : "=&r" (temp), "=m" (ref.count) \ + : "m" (ref.count) \ + : ); \ if (!ref) \ delete this; \ } - #elif defined(__ppc__) + #elif defined(__ppc__) || defined(__powerpc__) #define DECLARE_REF(x) \ - private: oRefCount ref; \ public: void AddRef(); \ - void Release(); + void Release(); \ + private: oRefCount ref; #define DEFINE_REF(c) \ void c::AddRef() \ { \ @@ -93,11 +125,11 @@ public: __asm__ __volatile__( \ "1: lwarx %0, 0, %3 \n" \ " add %0, %2, %0 \n" \ - " dcbt 0, %3 \n" \ + " dcbt 0, %3 # workaround for PPC405CR Errata\n" \ " stwcx. %0, 0, %3 \n" \ " bne- 1b \n" \ - : "=&r" (temp), "=m" ((int)ref) \ - : "r" (1), "r" (&((int)ref)), "m" ((int)ref) \ + : "=&r" (temp), "=m" (ref.count) \ + : "r" (1), "r" (&ref.count), "m" (ref.count) \ : "cc"); \ } \ void c::Release() \ @@ -106,72 +138,65 @@ public: __asm__ __volatile__( \ "1: lwarx %0, 0, %3 \n" \ " subf %0, %2, %0 \n" \ - " dcbt 0, %3 \n" \ + " dcbt 0, %3 # workaround for PPC405CR Errata\n" \ " stwcx. %0, 0, %3 \n" \ " bne- 1b \n" \ - : "=&r" (temp), "=m" ((int)ref) \ - : "r" (1), "r" (&((int)ref)), "m" ((int)ref) \ + : "=&r" (temp), "=m" (ref.count) \ + : "r" (1), "r" (&ref.count), "m" (ref.count) \ : "cc"); \ if (!ref) \ delete this; \ } + #elif defined(__i386__) || defined(__x86_64__) + #define DECLARE_REF(x) \ + public: void AddRef(); \ + void Release(); \ + private: oRefCount ref; + #define DEFINE_REF(c) \ + void c::AddRef() \ + { \ + __asm__ __volatile__( \ + " lock ; incl %0 \n" \ + : "=m" (ref.count) \ + : "m" (ref.count)); \ + } \ + void c::Release() \ + { \ + __asm__ __volatile__( \ + " lock ; decl %0 \n" \ + : "=m" (ref.count) \ + : "m" (ref.count)); \ + if (!ref) \ + delete this; \ + } #else + #warning use non optimized implementation of refcounting. #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, (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() \ + void Release(); \ + private:oRefCount ref; \ + eSingleLock ref_lock; + #define DEFINE_REF(c) \ + void c::AddRef() \ + { \ + eSingleLocker l(ref_lock); \ + ++ref; \ + } \ + void c::Release() \ + { \ { \ eSingleLocker l(ref_lock); \ - ++ref; \ + --ref; \ } \ - void c::Release() \ - { \ - { \ - eSingleLocker l(ref_lock); \ - --ref; \ - } \ - if (!ref) \ - delete this; \ - } - #endif + if (!ref) \ + delete this; \ + } #endif -#else +#else // SWIG #define DECLARE_REF(x) \ private: \ void AddRef(); \ void Release(); -#endif - -#ifdef SWIG -class Object -{ -}; -#endif +#endif // SWIG -#endif +#endif // __base_object_h