diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-01-06 10:15:44 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-01-06 10:15:44 -0300 |
commit | 53ce643e520de193c085c0c23046dcbd2e5308a5 (patch) | |
tree | d8336629c4ce789eb441fc3bd428e317d8ad8e9c /core/safe_refcount.cpp | |
parent | 99ceddd11ef652a3b8e6bf5d09dcc519d957ce14 (diff) | |
download | redot-engine-53ce643e520de193c085c0c23046dcbd2e5308a5.tar.gz |
-Changed memory functions, Memory::alloc_static*, simplified them, made them aligned to 16
-Changed Vector<> template to fit this.
Diffstat (limited to 'core/safe_refcount.cpp')
-rw-r--r-- | core/safe_refcount.cpp | 61 |
1 files changed, 55 insertions, 6 deletions
diff --git a/core/safe_refcount.cpp b/core/safe_refcount.cpp index de6b688b8a..f0d4fbd610 100644 --- a/core/safe_refcount.cpp +++ b/core/safe_refcount.cpp @@ -29,27 +29,76 @@ #include "safe_refcount.h" +// Atomic functions, these are used for multithread safe reference counters! + +#ifdef NO_THREADS + + +uint32_t atomic_conditional_increment( register uint32_t * pw ) { + + if (*pw==0) + return 0; + + (*pw)++; + + return *pw; +} + +uint32_t atomic_decrement( register uint32_t * pw ) { + + (*pw)--; + + return *pw; + +} + +#else + #ifdef _MSC_VER // don't pollute my namespace! #include <windows.h> -long atomic_conditional_increment( register long * pw ) { +uint32_t atomic_conditional_increment( register uint32_t * pw ) { /* try to increment until it actually works */ // taken from boost while (true) { - long tmp = static_cast< long const volatile& >( *pw ); + uint32_t tmp = static_cast< uint32_t const volatile& >( *pw ); if( tmp == 0 ) - return 0; // if zero, can't add to it anymore - if( InterlockedCompareExchange( pw, tmp + 1, tmp ) == tmp ) + return 0; // if zero, can't add to it anymore + if( InterlockedCompareExchange( (LONG volatile*)pw, tmp + 1, tmp ) == tmp ) return tmp+1; } +} + +uint32_t atomic_decrement( register uint32_t * pw ) { + return InterlockedDecrement( (LONG volatile*)pw ); +} + +#elif defined(__GNUC__) +uint32_t atomic_conditional_increment( register uint32_t * pw ) { + + while (true) { + uint32_t tmp = static_cast< uint32_t const volatile& >( *pw ); + if( tmp == 0 ) + return 0; // if zero, can't add to it anymore + if( __sync_val_compare_and_swap( pw, tmp, tmp + 1 ) == tmp ) + return tmp+1; + } } -long atomic_decrement( register long * pw ) { - return InterlockedDecrement( pw ); +uint32_t atomic_decrement( register uint32_t * pw ) { + + return __sync_sub_and_fetch(pw,1); + } +#else + //no threads supported? +#error Must provide atomic functions for this platform or compiler! + +#endif + #endif |