From: Ivan Maidanski Date: Mon, 8 Oct 2012 09:33:30 +0000 (+0400) Subject: Implement char/short/int_fetch_and_add for msftc/x86[_64] (Win32) X-Git-Tag: libatomic_ops-7_4_0~74 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=46425e19b4b0c84d0eb88313cdee9aa0d3a2fb89;p=platform%2Fupstream%2Flibatomic_ops.git Implement char/short/int_fetch_and_add for msftc/x86[_64] (Win32) * src/atomic_ops/sysdeps/msftc/x86.h (AO_NO_ASM_XADD): Recognize new macro. * src/atomic_ops/sysdeps/msftc/x86.h (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): New primitive implemented using __asm (only unless AO_NO_ASM_XADD). * src/atomic_ops/sysdeps/msftc/x86.h (AO_HAVE_char_fetch_and_add_full, AO_HAVE_short_fetch_and_add_full): New macro (accompanying the corresponding primitive). * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_HAVE_int_fetch_and_add_full, AO_HAVE_char_fetch_and_add_full, AO_HAVE_short_fetch_and_add_full): Likewise. * src/atomic_ops/sysdeps/msftc/x86_64.h (_InterlockedExchangeAdd): Add pragma to specify the intrinsic. * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_int_fetch_and_add_full): New primitive (implemented using 32-bit InterlockedExchangeAdd). * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_char_fetch_and_add_full, AO_short_fetch_and_add_full): New primitive implemented using 64-bit __asm (only if AO_ASM_X64_AVAILABLE). --- diff --git a/src/atomic_ops/sysdeps/msftc/x86.h b/src/atomic_ops/sysdeps/msftc/x86.h index af5bf71..f6b2a1b 100644 --- a/src/atomic_ops/sysdeps/msftc/x86.h +++ b/src/atomic_ops/sysdeps/msftc/x86.h @@ -71,6 +71,34 @@ AO_nop_full(void) #endif +#ifndef AO_NO_ASM_XADD + AO_INLINE unsigned char + AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) + { + __asm + { + mov al, incr + mov ebx, p + lock xadd byte ptr [ebx], al + } + /* Ignore possible "missing return value" warning here. */ + } +# define AO_HAVE_char_fetch_and_add_full + + AO_INLINE unsigned short + AO_short_fetch_and_add_full(volatile unsigned short *p, unsigned short incr) + { + __asm + { + mov ax, incr + mov ebx, p + lock xadd word ptr [ebx], ax + } + /* Ignore possible "missing return value" warning here. */ + } +# define AO_HAVE_short_fetch_and_add_full +#endif /* !AO_NO_ASM_XADD */ + AO_INLINE AO_TS_VAL_t AO_test_and_set_full(volatile AO_TS_t *addr) { diff --git a/src/atomic_ops/sysdeps/msftc/x86_64.h b/src/atomic_ops/sysdeps/msftc/x86_64.h index e7f9c32..269a7a2 100644 --- a/src/atomic_ops/sysdeps/msftc/x86_64.h +++ b/src/atomic_ops/sysdeps/msftc/x86_64.h @@ -44,6 +44,7 @@ /* Assume _MSC_VER >= 1400 */ #include +#pragma intrinsic (_InterlockedExchangeAdd) #pragma intrinsic (_InterlockedCompareExchange64) #ifndef AO_PREFER_GENERALIZED @@ -83,30 +84,61 @@ AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, } #define AO_HAVE_fetch_compare_and_swap_full -/* As far as we can tell, the lfence and sfence instructions are not */ -/* currently needed or useful for cached memory accesses. */ +AO_INLINE unsigned int +AO_int_fetch_and_add_full(volatile unsigned int *p, unsigned int incr) +{ + return _InterlockedExchangeAdd((LONG volatile *)p, incr); +} +#define AO_HAVE_int_fetch_and_add_full #ifdef AO_ASM_X64_AVAILABLE -AO_INLINE void -AO_nop_full(void) -{ - /* Note: "mfence" (SSE2) is supported on all x86_64/amd64 chips. */ - __asm { mfence } -} -#define AO_HAVE_nop_full + AO_INLINE unsigned char + AO_char_fetch_and_add_full(volatile unsigned char *p, unsigned char incr) + { + __asm + { + mov al, incr + mov rbx, p + lock xadd byte ptr [rbx], al + } + } +# define AO_HAVE_char_fetch_and_add_full -AO_INLINE AO_TS_VAL_t -AO_test_and_set_full(volatile AO_TS_t *addr) -{ + AO_INLINE unsigned short + AO_short_fetch_and_add_full(volatile unsigned short *p, unsigned short incr) + { + __asm + { + mov ax, incr + mov rbx, p + lock xadd word ptr [rbx], ax + } + } +# define AO_HAVE_short_fetch_and_add_full + +/* As far as we can tell, the lfence and sfence instructions are not */ +/* currently needed or useful for cached memory accesses. */ + + AO_INLINE void + AO_nop_full(void) + { + /* Note: "mfence" (SSE2) is supported on all x86_64/amd64 chips. */ + __asm { mfence } + } +# define AO_HAVE_nop_full + + AO_INLINE AO_TS_VAL_t + AO_test_and_set_full(volatile AO_TS_t *addr) + { __asm { mov rax,AO_TS_SET ; mov rbx,addr ; xchg byte ptr [rbx],al ; } -} -#define AO_HAVE_test_and_set_full + } +# define AO_HAVE_test_and_set_full #endif /* AO_ASM_X64_AVAILABLE */