summaryrefslogtreecommitdiffstats
path: root/core/safe_refcount.h
diff options
context:
space:
mode:
Diffstat (limited to 'core/safe_refcount.h')
-rw-r--r--core/safe_refcount.h312
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