123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- // Copyright (c) rAthena Project (www.rathena.org) - Licensed under GNU GPL
- // For more information, see LICENCE in the main folder
- #ifndef _rA_ATOMIC_H_
- #define _rA_ATOMIC_H_
- // Atomic Operations
- // (Interlocked CompareExchange, Add .. and so on ..)
- //
- // Implementation varies / depends on:
- // - Architecture
- // - Compiler
- // - Operating System
- //
- // our Abstraction is fully API-Compatible to Microsofts implementation @ NT5.0+
- //
- #include "../common/cbasetypes.h"
- #if defined(_MSC_VER)
- #include "../common/winapi.h"
- #if !defined(_M_X64)
- // When compiling for windows 32bit, the 8byte interlocked operations are not provided by microsoft
- // (because they need at least i586 so its not generic enough.. ... )
- forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 _cmp){
- _asm{
- lea esi,_cmp;
- lea edi,exch;
-
- mov eax,[esi];
- mov edx,4[esi];
- mov ebx,[edi];
- mov ecx,4[edi];
- mov esi,dest;
-
- lock CMPXCHG8B [esi];
- }
- }
- forceinline volatile int64 InterlockedIncrement64(volatile int64 *addend){
- __int64 old;
- do{
- old = *addend;
- }while(InterlockedCompareExchange64(addend, (old+1), old) != old);
- return (old + 1);
- }
- forceinline volatile int64 InterlockedDecrement64(volatile int64 *addend){
- __int64 old;
- do{
- old = *addend;
- }while(InterlockedCompareExchange64(addend, (old-1), old) != old);
- return (old - 1);
- }
- forceinline volatile int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment){
- __int64 old;
- do{
- old = *addend;
- }while(InterlockedCompareExchange64(addend, (old + increment), old) != old);
- return old;
- }
- forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 val){
- __int64 old;
- do{
- old = *target;
- }while(InterlockedCompareExchange64(target, val, old) != old);
- return old;
- }
- #endif //endif 32bit windows
- #elif defined(__GNUC__)
- #if !defined(__x86_64__) && !defined(__i386__)
- #error Your Target Platfrom is not supported
- #endif
- static forceinline int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment){
- return __sync_fetch_and_add(addend, increment);
- }//end: InterlockedExchangeAdd64()
- static forceinline int32 InterlockedExchangeAdd(volatile int32 *addend, int32 increment){
- return __sync_fetch_and_add(addend, increment);
- }//end: InterlockedExchangeAdd()
- static forceinline int64 InterlockedIncrement64(volatile int64 *addend){
- return __sync_add_and_fetch(addend, 1);
- }//end: InterlockedIncrement64()
- static forceinline int32 InterlockedIncrement(volatile int32 *addend){
- return __sync_add_and_fetch(addend, 1);
- }//end: InterlockedIncrement()
- static forceinline int64 InterlockedDecrement64(volatile int64 *addend){
- return __sync_sub_and_fetch(addend, 1);
- }//end: InterlockedDecrement64()
- static forceinline int32 InterlockedDecrement(volatile int32 *addend){
- return __sync_sub_and_fetch(addend, 1);
- }//end: InterlockedDecrement()
- static forceinline int64 InterlockedCompareExchange64(volatile int64 *dest, int64 exch, int64 cmp){
- return __sync_val_compare_and_swap(dest, cmp, exch);
- }//end: InterlockedCompareExchange64()
- static forceinline int32 InterlockedCompareExchange(volatile int32 *dest, int32 exch, int32 cmp){
- return __sync_val_compare_and_swap(dest, cmp, exch);
- }//end: InterlockedCompareExchnage()
- static forceinline int64 InterlockedExchange64(volatile int64 *target, int64 val){
- return __sync_lock_test_and_set(target, val);
- }//end: InterlockedExchange64()
- static forceinline int32 InterlockedExchange(volatile int32 *target, int32 val){
- return __sync_lock_test_and_set(target, val);
- }//end: InterlockedExchange()
- #endif //endif compiler decission
- #endif
|