Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/winbase.h | 132 ---------------------------------------------- include/winnt.h | 132 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 132 deletions(-)
diff --git a/include/winbase.h b/include/winbase.h index dc8aa081be4..0262e50d980 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -2919,138 +2919,6 @@ extern char * CDECL wine_get_unix_file_name( LPCWSTR dos ); extern WCHAR * CDECL wine_get_dos_file_name( LPCSTR str );
-/* Interlocked functions */ - -#ifdef _MSC_VER - -#pragma intrinsic(_InterlockedCompareExchange) -#pragma intrinsic(_InterlockedCompareExchange64) -#pragma intrinsic(_InterlockedExchange) -#pragma intrinsic(_InterlockedExchangeAdd) -#pragma intrinsic(_InterlockedIncrement) -#pragma intrinsic(_InterlockedDecrement) - -long _InterlockedCompareExchange(long volatile*,long,long); -long long _InterlockedCompareExchange64(long long volatile*,long long,long long); -long _InterlockedDecrement(long volatile*); -long _InterlockedExchange(long volatile*,long); -long _InterlockedExchangeAdd(long volatile*,long); -long _InterlockedIncrement(long volatile*); - -static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) -{ - return _InterlockedCompareExchange( (long volatile *)dest, xchg, compare ); -} - -static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) -{ - return _InterlockedCompareExchange64( (long long volatile *)dest, compare, xchg ); -} - -static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) -{ - return _InterlockedExchange( (long volatile *)dest, val ); -} - -static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) -{ - return _InterlockedExchangeAdd( (long volatile *)dest, incr ); -} - -static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) -{ - return _InterlockedIncrement( (long volatile *)dest ); -} - -static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) -{ - return _InterlockedDecrement( (long volatile *)dest ); -} - -#ifndef __i386__ - -#pragma intrinsic(_InterlockedCompareExchangePointer) -#pragma intrinsic(_InterlockedExchangePointer) - -#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer -#define InterlockedExchangePointer _InterlockedExchangePointer - -void *InterlockedCompareExchangePointer(void *volatile*,void*,void*); -void *InterlockedExchangePointer(void *volatile*,void*); - -#else - -static FORCEINLINE void *WINAPI InterlockedCompareExchangePointer( void *volatile *dest, void *xchg, void *compare ) -{ - return (void *)_InterlockedCompareExchange( (long volatile*)dest, (long)xchg, (long)compare ); -} - -static FORCEINLINE void *WINAPI InterlockedExchangePointer( void *volatile *dest, void *val ) -{ - return (void *)_InterlockedExchange( (long volatile*)dest, (long)val ); -} - -#endif - -#elif defined(__GNUC__) - -static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) -{ - return __sync_val_compare_and_swap( dest, compare, xchg ); -} - -static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) -{ - return __sync_val_compare_and_swap( dest, compare, xchg ); -} - -static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) -{ - return __sync_val_compare_and_swap( dest, compare, xchg ); -} - -static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) -{ - LONG ret; -#if defined(__i386__) || defined(__x86_64__) - __asm__ __volatile__( "lock; xchgl %0,(%1)" - : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); -#else - do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); -#endif - return ret; -} - -static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) -{ - return __sync_fetch_and_add( dest, incr ); -} - -static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) -{ - return __sync_add_and_fetch( dest, 1 ); -} - -static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) -{ - return __sync_add_and_fetch( dest, -1 ); -} - -static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) -{ - PVOID ret; -#ifdef __x86_64__ - __asm__ __volatile__( "lock; xchgq %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); -#elif defined(__i386__) - __asm__ __volatile__( "lock; xchgl %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); -#else - do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); -#endif - return ret; -} - -#endif /* __GNUC__ */ - #ifdef __WINESRC__
static FORCEINLINE HANDLE WINAPI GetCurrentProcess(void) diff --git a/include/winnt.h b/include/winnt.h index 83fcc67c85d..7bbe0185139 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6892,6 +6892,138 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask)
#endif
+/* Interlocked functions */ + +#ifdef _MSC_VER + +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedCompareExchange64) +#pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedIncrement) +#pragma intrinsic(_InterlockedDecrement) + +long _InterlockedCompareExchange(long volatile*,long,long); +long long _InterlockedCompareExchange64(long long volatile*,long long,long long); +long _InterlockedDecrement(long volatile*); +long _InterlockedExchange(long volatile*,long); +long _InterlockedExchangeAdd(long volatile*,long); +long _InterlockedIncrement(long volatile*); + +static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) +{ + return _InterlockedCompareExchange( (long volatile *)dest, xchg, compare ); +} + +static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) +{ + return _InterlockedCompareExchange64( (long long volatile *)dest, compare, xchg ); +} + +static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) +{ + return _InterlockedExchange( (long volatile *)dest, val ); +} + +static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) +{ + return _InterlockedExchangeAdd( (long volatile *)dest, incr ); +} + +static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) +{ + return _InterlockedIncrement( (long volatile *)dest ); +} + +static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) +{ + return _InterlockedDecrement( (long volatile *)dest ); +} + +#ifndef __i386__ + +#pragma intrinsic(_InterlockedCompareExchangePointer) +#pragma intrinsic(_InterlockedExchangePointer) + +#define InterlockedCompareExchangePointer _InterlockedCompareExchangePointer +#define InterlockedExchangePointer _InterlockedExchangePointer + +void *InterlockedCompareExchangePointer(void *volatile*,void*,void*); +void *InterlockedExchangePointer(void *volatile*,void*); + +#else + +static FORCEINLINE void * WINAPI InterlockedCompareExchangePointer( void *volatile *dest, void *xchg, void *compare ) +{ + return (void *)_InterlockedCompareExchange( (long volatile*)dest, (long)xchg, (long)compare ); +} + +static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *dest, void *val ) +{ + return (void *)_InterlockedExchange( (long volatile*)dest, (long)val ); +} + +#endif + +#elif defined(__GNUC__) + +static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) +{ + return __sync_val_compare_and_swap( dest, compare, xchg ); +} + +static FORCEINLINE void * WINAPI InterlockedCompareExchangePointer( void *volatile *dest, void *xchg, void *compare ) +{ + return __sync_val_compare_and_swap( dest, compare, xchg ); +} + +static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) +{ + return __sync_val_compare_and_swap( dest, compare, xchg ); +} + +static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) +{ + LONG ret; +#if defined(__i386__) || defined(__x86_64__) + __asm__ __volatile__( "lock; xchgl %0,(%1)" + : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); +#else + do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); +#endif + return ret; +} + +static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) +{ + return __sync_fetch_and_add( dest, incr ); +} + +static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) +{ + return __sync_add_and_fetch( dest, 1 ); +} + +static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) +{ + return __sync_add_and_fetch( dest, -1 ); +} + +static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *dest, void *val ) +{ + void *ret; +#ifdef __x86_64__ + __asm__ __volatile__( "lock; xchgq %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); +#elif defined(__i386__) + __asm__ __volatile__( "lock; xchgl %0,(%1)" : "=r" (ret) :"r" (dest), "0" (val) : "memory" ); +#else + do ret = *dest; while (!__sync_bool_compare_and_swap( dest, ret, val )); +#endif + return ret; +} + +#endif /* __GNUC__ */ + #ifdef _WIN64
#if defined(_MSC_VER)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/winnt.h | 52 +++++++++++++++++++------------------------------ 1 file changed, 20 insertions(+), 32 deletions(-)
diff --git a/include/winnt.h b/include/winnt.h index 7bbe0185139..1bb29836a3d 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6898,6 +6898,9 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask)
#pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedCompareExchange64) +#ifdef _WIN64 +#pragma intrinsic(_InterlockedCompareExchange128) +#endif #pragma intrinsic(_InterlockedExchange) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedIncrement) @@ -6905,6 +6908,9 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask)
long _InterlockedCompareExchange(long volatile*,long,long); long long _InterlockedCompareExchange64(long long volatile*,long long,long long); +#ifdef _WIN64 +unsigned char _InterlockedCompareExchange128(volatile __int64 *, __int64, __int64, __int64 *); +#endif long _InterlockedDecrement(long volatile*); long _InterlockedExchange(long volatile*,long); long _InterlockedExchangeAdd(long volatile*,long); @@ -6920,6 +6926,13 @@ static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volati return _InterlockedCompareExchange64( (long long volatile *)dest, compare, xchg ); }
+#ifdef _WIN64 +static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ + return _InterlockedCompareExchange128( dest, xchg_high, xchg_low, compare ); +} +#endif + static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) { return _InterlockedExchange( (long volatile *)dest, val ); @@ -6982,6 +6995,13 @@ static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volati return __sync_val_compare_and_swap( dest, compare, xchg ); }
+#ifdef _WIN64 +static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ + return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); +} +#endif + static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) { LONG ret; @@ -7024,38 +7044,6 @@ static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *des
#endif /* __GNUC__ */
-#ifdef _WIN64 - -#if defined(_MSC_VER) - -#define InterlockedCompareExchange128 _InterlockedCompareExchange128 -unsigned char _InterlockedCompareExchange128(volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare); -#pragma intrinsic(_InterlockedCompareExchange128) - -#elif defined(__x86_64__) - -static inline unsigned char InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare) -{ - unsigned char ret; - __asm__ __volatile__( "lock cmpxchg16b %0; setz %b2" - : "=m" (dest[0]), "=m" (dest[1]), "=r" (ret), - "=a" (compare[0]), "=d" (compare[1]) - : "m" (dest[0]), "m" (dest[1]), "3" (compare[0]), "4" (compare[1]), - "c" (xchg_high), "b" (xchg_low) ); - return ret; -} - -#elif defined(__GNUC__) - -static inline unsigned char InterlockedCompareExchange128(__int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare) -{ - return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); -} - -#endif - -#endif /* _WIN64 */ - #ifdef __cplusplus } #endif
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h index 1bb29836a3d..f2cfdcb3aa5 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6978,6 +6978,59 @@ static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *des
#endif
+#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) + +static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +static FORCEINLINE PVOID WINAPI InterlockedCompareExchangePointer( PVOID volatile *dest, PVOID xchg, PVOID compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +static FORCEINLINE LONGLONG WINAPI InterlockedCompareExchange64( LONGLONG volatile *dest, LONGLONG xchg, LONGLONG compare ) +{ + __atomic_compare_exchange_n( dest, &compare, xchg, TRUE, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST ); + return compare; +} + +#ifdef _WIN64 +static FORCEINLINE unsigned char WINAPI InterlockedCompareExchange128( volatile __int64 *dest, __int64 xchg_high, __int64 xchg_low, __int64 *compare ) +{ + /* __atomic_compare_exchange_n() generates a call to libatomic on gcc */ + return __sync_bool_compare_and_swap( (__int128 *)dest, *(__int128 *)compare, ((__int128)xchg_high << 64) | xchg_low ); +} +#endif + +static FORCEINLINE LONG WINAPI InterlockedExchange( LONG volatile *dest, LONG val ) +{ + return __atomic_exchange_n( dest, val, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedExchangeAdd( LONG volatile *dest, LONG incr ) +{ + return __atomic_fetch_add( dest, incr, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedIncrement( LONG volatile *dest ) +{ + return __atomic_add_fetch( dest, 1, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) +{ + return __atomic_add_fetch( dest, -1, __ATOMIC_SEQ_CST ); +} + +static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest, PVOID val ) +{ + return __atomic_exchange_n( dest, val, __ATOMIC_SEQ_CST ); +} + #elif defined(__GNUC__)
static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare )
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
How are these better than the __sync ones in practice?
On 1/15/21 10:34 AM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
How are these better than the __sync ones in practice?
I think the only real benefit is atomic exchange; it allows the compiler to maybe yield better code for x86 than our inline assembly (although it surely would never make a difference in practice), and presumably better code for other platforms than a compare-and-swap loop.
The actual practical benefit is probably negligible, but I figured we might as well use a proper compiler intrinsic for atomic swap if there was one available.
On 1/15/21 5:46 PM, Zebediah Figura (she/her) wrote:
On 1/15/21 10:34 AM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
How are these better than the __sync ones in practice?
I think the only real benefit is atomic exchange; it allows the compiler to maybe yield better code for x86 than our inline assembly (although it surely would never make a difference in practice), and presumably better code for other platforms than a compare-and-swap loop.
The actual practical benefit is probably negligible, but I figured we might as well use a proper compiler intrinsic for atomic swap if there was one available.
__sync GCC builtins are supposedly legacy, but I believe they may also imply a slightly stronger memory model than __atomic.
For instance, notice the additional "dmb ish" on ARM64 for __sync, and the use of "ldaxr" instead of "ldxr" for __atomic here:
https://gcc.godbolt.org/z/vq5Gzv
(Note it may also depend on the compiler, Clang generates the same code with "ldaxr" and no "dmb ish", so either GCC implementation is sub-optimal, or they have different semantics for their builtins).
On X86 of course this won't change anything, because the CPU model is already implying an even stronger model.
"Zebediah Figura (she/her)" zfigura@codeweavers.com writes:
On 1/15/21 10:34 AM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
How are these better than the __sync ones in practice?
I think the only real benefit is atomic exchange; it allows the compiler to maybe yield better code for x86 than our inline assembly (although it surely would never make a difference in practice), and presumably better code for other platforms than a compare-and-swap loop.
For other platforms it would be OK to require the atomic builtin, we only care about old compilers on x86.
It would also be OK to use it as an alternative to inline assembly for InterlockedExchange, but I don't think it's necessary to duplicate all the other interlocked functions if there's no significant benefit.
On 1/18/21 5:52 AM, Alexandre Julliard wrote:
"Zebediah Figura (she/her)" zfigura@codeweavers.com writes:
On 1/15/21 10:34 AM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Signed-off-by: Zebediah Figura z.figura12@gmail.com
v2: avoid 16-bit __atomic_compare_exchange_n()
include/winnt.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
How are these better than the __sync ones in practice?
I think the only real benefit is atomic exchange; it allows the compiler to maybe yield better code for x86 than our inline assembly (although it surely would never make a difference in practice), and presumably better code for other platforms than a compare-and-swap loop.
For other platforms it would be OK to require the atomic builtin, we only care about old compilers on x86.
It would also be OK to use it as an alternative to inline assembly for InterlockedExchange, but I don't think it's necessary to duplicate all the other interlocked functions if there's no significant benefit.
That makes sense, thanks. I'll resend without this patch, and just change InterlockedExchange instead.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- v2: replace msvcrt version
dlls/msvcrt/lock.c | 9 --------- include/winnt.h | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/dlls/msvcrt/lock.c b/dlls/msvcrt/lock.c index b6b5d4b78db..c10445becda 100644 --- a/dlls/msvcrt/lock.c +++ b/dlls/msvcrt/lock.c @@ -1157,15 +1157,6 @@ static inline void spin_wait_for_next_rwl(rwl_queue *q) SpinWait_dtor(&sw); }
-/* Remove when proper InterlockedOr implementation is added to wine */ -static LONG InterlockedOr(LONG *d, LONG v) -{ - LONG l; - while (~(l = *d) & v) - if (InterlockedCompareExchange(d, l|v, l) == l) break; - return l; -} - static LONG InterlockedAnd(LONG *d, LONG v) { LONG l = *d, old; diff --git a/include/winnt.h b/include/winnt.h index f2cfdcb3aa5..4283f354552 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6905,6 +6905,7 @@ static inline BOOLEAN BitScanReverse(DWORD *index, DWORD mask) #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedIncrement) #pragma intrinsic(_InterlockedDecrement) +#pragma intrinsic(_InterlockedOr)
long _InterlockedCompareExchange(long volatile*,long,long); long long _InterlockedCompareExchange64(long long volatile*,long long,long long); @@ -6915,6 +6916,7 @@ long _InterlockedDecrement(long volatile*); long _InterlockedExchange(long volatile*,long); long _InterlockedExchangeAdd(long volatile*,long); long _InterlockedIncrement(long volatile*); +long _InterlockedOr(long volatile *,long);
static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) { @@ -6953,6 +6955,11 @@ static FORCEINLINE LONG WINAPI InterlockedDecrement( LONG volatile *dest ) return _InterlockedDecrement( (long volatile *)dest ); }
+static FORCEINLINE LONG WINAPI InterlockedOr( LONG volatile *dest, LONG val ) +{ + return _InterlockedOr( (long volatile *)dest, val ); +} + #ifndef __i386__
#pragma intrinsic(_InterlockedCompareExchangePointer) @@ -7031,6 +7038,11 @@ static FORCEINLINE PVOID WINAPI InterlockedExchangePointer( PVOID volatile *dest return __atomic_exchange_n( dest, val, __ATOMIC_SEQ_CST ); }
+static FORCEINLINE LONG WINAPI InterlockedOr( LONG volatile *dest, LONG val ) +{ + return __atomic_fetch_or( dest, val, __ATOMIC_SEQ_CST ); +} + #elif defined(__GNUC__)
static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) @@ -7095,6 +7107,11 @@ static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *des return ret; }
+static FORCEINLINE LONG WINAPI InterlockedOr( LONG volatile *dest, LONG incr ) +{ + return __sync_fetch_and_or( dest, incr ); +} + #endif /* __GNUC__ */
#ifdef __cplusplus
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- include/winnt.h | 55 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/include/winnt.h b/include/winnt.h index 4283f354552..ba0bf15322c 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -6983,7 +6983,50 @@ static FORCEINLINE void * WINAPI InterlockedExchangePointer( void *volatile *des return (void *)_InterlockedExchange( (long volatile*)dest, (long)val ); }
-#endif +#endif /* __i386__ */ + +#ifdef __i386__ + +static FORCEINLINE void MemoryBarrier(void) +{ + LONG dummy; + InterlockedOr(&dummy, 0); +} + +#elif defined(__x86_64__) + +#pragma intrinsic(__faststorefence) + +void __faststorefence(void); + +static FORCEINLINE void MemoryBarrier(void) +{ + __faststorefence(); +} + +#elif defined(__arm__) + +#pragma intrinsic(__dmb) + +void __dmb(void); + +static FORCEINLINE void MemoryBarrier(void) +{ + __dmb(_ARM_BARRIER_SY); +} + +#elif defined(__aarch64__) + +#pragma intrinsic(__dmb) + +void __dmb(void); + +static FORCEINLINE void MemoryBarrier(void) +{ + __dmb(_ARM64_BARRIER_SY); +} + +#endif /* __i386__ */
#elif defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7)))
@@ -7043,6 +7086,11 @@ static FORCEINLINE LONG WINAPI InterlockedOr( LONG volatile *dest, LONG val ) return __atomic_fetch_or( dest, val, __ATOMIC_SEQ_CST ); }
+static FORCEINLINE void MemoryBarrier(void) +{ + __atomic_thread_fence( __ATOMIC_SEQ_CST ); +} + #elif defined(__GNUC__)
static FORCEINLINE LONG WINAPI InterlockedCompareExchange( LONG volatile *dest, LONG xchg, LONG compare ) @@ -7112,6 +7160,11 @@ static FORCEINLINE LONG WINAPI InterlockedOr( LONG volatile *dest, LONG incr ) return __sync_fetch_and_or( dest, incr ); }
+static FORCEINLINE void MemoryBarrier(void) +{ + __sync_synchronize(); +} + #endif /* __GNUC__ */
#ifdef __cplusplus