From: Jinoh Kang jinoh.kang.kr@gmail.com
64-bit volatile accesses are not atomic on i386. Both i686-w64-mingw32-gcc and x86 MSVC splits 64-bit loads into a pair of load/store ops.
Fix this by using a FILD/FISTP pair, which is also used to implement C11 atomics by i686-w64-mingw32-gcc.
Fixes: f82b1c1fcf770a5d6fa02c3f286282be79a201b8 --- include/winnt.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/include/winnt.h b/include/winnt.h index 2547f841b7c..f93c27bb4a4 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -7122,7 +7122,15 @@ static FORCEINLINE LONG ReadNoFence( LONG const volatile *src )
static FORCEINLINE LONG64 ReadNoFence64( LONG64 const volatile *src ) { - LONG64 value = __WINE_LOAD64_NO_FENCE( (__int64 const volatile *)src ); + LONG64 value; +#if defined(__i386__) && _MSC_VER < 1700 + __asm { + fild qword ptr [src] + fistp qword ptr [value] + } +#else + value = __WINE_LOAD64_NO_FENCE( (__int64 const volatile *)src ); +#endif return value; }
@@ -7315,7 +7323,11 @@ static FORCEINLINE LONG ReadNoFence( LONG const volatile *src ) static FORCEINLINE LONG64 ReadNoFence64( LONG64 const volatile *src ) { LONG64 value; +#ifdef __i386__ + __asm__ __volatile__( "fildq %1\n\tfistpq %0" : "=m" (value) : "m" (src) : "memory", "st" ); +#else __WINE_ATOMIC_LOAD_RELAXED( src, &value ); +#endif return value; }