diff options
Diffstat (limited to 'core/safe_refcount.h')
-rw-r--r-- | core/safe_refcount.h | 312 |
1 files changed, 9 insertions, 303 deletions
diff --git a/core/safe_refcount.h b/core/safe_refcount.h index 5bb2a4564b..08bea9d244 100644 --- a/core/safe_refcount.h +++ b/core/safe_refcount.h @@ -33,309 +33,17 @@ /* x86/x86_64 GCC */ #include "platform_config.h" +#include "typedefs.h" -#ifdef NO_THREADS - -struct SafeRefCount { - - int count; - -public: - - // destroy() is called when weak_count_ drops to zero. - - bool ref() { //true on success - - if (count==0) - return false; - count++; - - return true; - } - - int refval() { //true on success - - if (count==0) - return 0; - count++; - return count; - } - - bool unref() { // true if must be disposed of - - if (count>0) - count--; - - return count==0; - } - - long get() const { // nothrow - - return static_cast<int const volatile &>( count ); - } - - void init(int p_value=1) { - - count=p_value; - }; - -}; - - - - - - - - -#else - -#if defined( PLATFORM_REFCOUNT ) - -#include "platform_refcount.h" - - -#elif defined( __GNUC__ ) && ( defined( __i386__ ) || defined( __x86_64__ ) ) - -#define REFCOUNT_T volatile int -#define REFCOUNT_GET_T int const volatile& - -static inline int atomic_conditional_increment( volatile int * pw ) { - // int rv = *pw; - // if( rv != 0 ) ++*pw; - // return rv; - - int rv, tmp; - - __asm__ - ( - "movl %0, %%eax\n\t" - "0:\n\t" - "test %%eax, %%eax\n\t" - "je 1f\n\t" - "movl %%eax, %2\n\t" - "incl %2\n\t" - "lock\n\t" - "cmpxchgl %2, %0\n\t" - "jne 0b\n\t" - "1:": - "=m"( *pw ), "=&a"( rv ), "=&r"( tmp ): // outputs (%0, %1, %2) - "m"( *pw ): // input (%3) - "cc" // clobbers - ); - - return rv; -} - -static inline int atomic_decrement( volatile int *pw) { - - // return --(*pw); - - unsigned char rv; - - __asm__ - ( - "lock\n\t" - "decl %0\n\t" - "setne %1": - "=m" (*pw), "=qm" (rv): - "m" (*pw): - "memory" - ); - return static_cast<int>(rv); -} - -/* PowerPC32/64 GCC */ - -#elif ( defined( __GNUC__ ) ) && ( defined( __powerpc__ ) || defined( __ppc__ ) ) - -#define REFCOUNT_T int -#define REFCOUNT_GET_T int const volatile& - -inline int atomic_conditional_increment( int * pw ) -{ - // if( *pw != 0 ) ++*pw; - // return *pw; - - int rv; - - __asm__ - ( - "0:\n\t" - "lwarx %1, 0, %2\n\t" - "cmpwi %1, 0\n\t" - "beq 1f\n\t" - "addi %1, %1, 1\n\t" - "1:\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 0b": - - "=m"( *pw ), "=&b"( rv ): - "r"( pw ), "m"( *pw ): - "cc" - ); - - return rv; -} - - -inline int atomic_decrement( int * pw ) -{ - // return --*pw; - - int rv; - - __asm__ __volatile__ - ( - "sync\n\t" - "0:\n\t" - "lwarx %1, 0, %2\n\t" - "addi %1, %1, -1\n\t" - "stwcx. %1, 0, %2\n\t" - "bne- 0b\n\t" - "isync": - - "=m"( *pw ), "=&b"( rv ): - "r"( pw ), "m"( *pw ): - "memory", "cc" - ); - - return rv; -} - -/* CW ARM */ - -#elif defined( __GNUC__ ) && ( defined( __arm__ ) ) - -#define REFCOUNT_T int -#define REFCOUNT_GET_T int const volatile& - -inline int atomic_conditional_increment(volatile int* v) -{ - int t; - int tmp; - - __asm__ __volatile__( - "1: ldrex %0, [%2] \n" - " cmp %0, #0 \n" - " beq 2f \n" - " add %0, %0, #1 \n" - "2: \n" - " strex %1, %0, [%2] \n" - " cmp %1, #0 \n" - " bne 1b \n" - - : "=&r" (t), "=&r" (tmp) - : "r" (v) - : "cc", "memory"); - - return t; -} - - -inline int atomic_decrement(volatile int* v) -{ - int t; - int tmp; - - __asm__ __volatile__( - "1: ldrex %0, [%2] \n" - " add %0, %0, #-1 \n" - " strex %1, %0, [%2] \n" - " cmp %1, #0 \n" - " bne 1b \n" - - : "=&r" (t), "=&r" (tmp) - : "r" (v) - : "cc", "memory"); - - return t; -} - - - -/* CW PPC */ - -#elif ( defined( __MWERKS__ ) ) && defined( __POWERPC__ ) - -inline long atomic_conditional_increment( register long * pw ) -{ - register int a; - - asm - { - loop: - - lwarx a, 0, pw - cmpwi a, 0 - beq store - - addi a, a, 1 - - store: - - stwcx. a, 0, pw - bne- loop - } - - return a; -} - - -inline long atomic_decrement( register long * pw ) -{ - register int a; - - asm { - - sync - - loop: - - lwarx a, 0, pw - addi a, a, -1 - stwcx. a, 0, pw - bne- loop - - isync - } - - return a; -} - -/* Any Windows (MSVC) */ - -#elif defined( _MSC_VER ) - -// made functions to not pollute namespace.. - -#define REFCOUNT_T long -#define REFCOUNT_GET_T long const volatile& - -long atomic_conditional_increment( register long * pw ); -long atomic_decrement( register long * pw ); - -#if 0 -#elif defined( __GNUC__ ) && defined( ARMV6_ENABLED) - - -#endif - - - - -#else - -#error This platform cannot use safe refcount, compile with NO_THREADS or implement it. - -#endif +uint32_t atomic_conditional_increment( register uint32_t * counter ); +uint32_t atomic_decrement( register uint32_t * pw ); struct SafeRefCount { - REFCOUNT_T count; + uint32_t count; public: @@ -346,7 +54,7 @@ public: return atomic_conditional_increment( &count ) != 0; } - int refval() { //true on success + uint32_t refval() { //true on success return atomic_conditional_increment( &count ); } @@ -360,20 +68,18 @@ public: return false; } - long get() const { // nothrow + uint32_t get() const { // nothrow - return static_cast<REFCOUNT_GET_T>( count ); + return count; } - void init(int p_value=1) { + void init(uint32_t p_value=1) { count=p_value; - }; + } }; -#endif // no thread safe - #endif |