[mono/mono] [3 commits] 41d1358f: Add Interlocked{Read, Write}{8, 16, Pointer} functions.
"alexrp (
[email protected] )" <
[email protected] >
Wed, 23 Oct 2013 22:10:24 +0000
Newsgroups
gmane.comp.gnome.mono.patches
Message-ID
<00000141e75e6110-f51c7953-0766-4f4f-8358-d27a05905585-000000@email.amazonses.com>
Branch: refs/heads/master
Home: https://github.com/mono/mono
Compare: https://github.com/mono/mono/compare/9bcda222deab...04a90dcbb0e1
Commit: 41d1358f098ccabcc82632c000b6bc200dcd447d
Author: Alex Rønne Petersen <[email protected] >
Date: 2013-10-23 22:06:23 GMT
URL: https://github.com/mono/mono/commit/41d1358f098ccabcc82632c000b6bc200dcd447d
Add Interlocked{Read,Write}{8,16,Pointer} functions.
Changed paths:
M mono/utils/atomic.c
M mono/utils/atomic.h
Modified: mono/utils/atomic.c
===================================================================
@@ -337,6 +337,50 @@ gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add)
return(ret);
}
+gint8 InterlockedRead8(volatile gint8 *src)
+{
+ gint8 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *src;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+gint16 InterlockedRead16(volatile gint16 *src)
+{
+ gint16 ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *src;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
gint32 InterlockedRead(volatile gint32 *src)
{
gint32 ret;
@@ -381,6 +425,66 @@ gint64 InterlockedRead64(volatile gint64 *src)
return(ret);
}
+gpointer InterlockedReadPointer(volatile gpointer *src)
+{
+ gpointer ret;
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ ret= *src;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+
+ return(ret);
+}
+
+void InterlockedWrite(volatile gint8 *dst, gint8 val)
+{
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dst=val;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+}
+
+void InterlockedWrite16(volatile gint16 *dst, gint16 val)
+{
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dst=val;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+}
+
void InterlockedWrite(volatile gint32 *dst, gint32 val)
{
int thr_ret;
@@ -419,6 +523,25 @@ void InterlockedWrite64(volatile gint64 *dst, gint64 val)
pthread_cleanup_pop (0);
}
+void InterlockedWritePointer(volatile gpointer *dst, gpointer val)
+{
+ int thr_ret;
+
+ mono_once(&spin_once, spin_init);
+
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&spin);
+ thr_ret = pthread_mutex_lock(&spin);
+ g_assert (thr_ret == 0);
+
+ *dst=val;
+
+ thr_ret = pthread_mutex_unlock(&spin);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+}
+
#endif
#if defined (NEED_64BIT_CMPXCHG_FALLBACK)
Modified: mono/utils/atomic.h
===================================================================
@@ -22,6 +22,7 @@
#if defined(__WIN32__) || defined(_WIN32)
#include <windows.h>
+#include <mono/utils/mono-membar.h>
/* mingw is missing InterlockedCompareExchange64 () from winbase.h */
#if HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64==0
@@ -89,6 +90,11 @@ static inline gint64 InterlockedRead64(volatile gint64 *src)
return InterlockedCompareExchange64 (src, 0, 0);
}
+static inline gpointer InterlockedReadPointer(volatile gpointer *src)
+{
+ return InterlockedCompareExchangePointer (src, NULL, NULL);
+}
+
static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
{
InterlockedExchange (dst, val);
@@ -99,6 +105,36 @@ static inline void InterlockedWrite64(volatile gint64 *dst, gint64 val)
InterlockedExchange64 (dst, val);
}
+static inline void InterlockedWritePointer(volatile gpointer *dst, gpointer val)
+{
+ InterlockedExchangePointer (dst, val);
+}
+
+/* We can't even use CAS for these, so write them out
+ * explicitly according to x86(_64) semantics... */
+
+static inline gint8 InterlockedRead8(volatile gint8 *src)
+{
+ return *src;
+}
+
+static inline gint16 InterlockedRead16(volatile gint16 *src)
+{
+ return *src;
+}
+
+static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
+{
+ *dst = val;
+ mono_memory_barrier ();
+}
+
+static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
+{
+ *dst = val;
+ mono_memory_barrier ();
+}
+
/* Prefer GCC atomic ops if the target supports it (see configure.in). */
#elif defined(USE_GCC_ATOMIC_OPS)
@@ -152,17 +188,47 @@ static inline gint32 InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
return __sync_fetch_and_add (val, add);
}
-static inline gint32 InterlockedRead(volatile gint32 *src)
+static inline gint8 InterlockedRead8(volatile gint8 *src)
{
/* Kind of a hack, but GCC doesn't give us anything better, and it's
- certainly not as bad as using a CAS loop. */
+ * certainly not as bad as using a CAS loop. */
+ return __sync_fetch_and_add (src, 0);
+}
+
+static inline gint16 InterlockedRead16(volatile gint16 *src)
+{
return __sync_fetch_and_add (src, 0);
}
+static inline gint32 InterlockedRead(volatile gint32 *src)
+{
+ return __sync_fetch_and_add (src, 0);
+}
+
+static inline void InterlockedWrite8(volatile gint8 *dst, gint8 val)
+{
+ /* Nothing useful from GCC at all, so fall back to CAS. */
+ gint8 old_val;
+ do {
+ old_val = *dst;
+ } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+}
+
+static inline void InterlockedWrite16(volatile gint16 *dst, gint16 val)
+{
+ gint16 old_val;
+ do {
+ old_val = *dst;
+ } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
+}
+
static inline void InterlockedWrite(volatile gint32 *dst, gint32 val)
{
/* Nothing useful from GCC at all, so fall back to CAS. */
- InterlockedExchange (dst, val);
+ gint32 old_val;
+ do {
+ old_val = *dst;
+ } while (__sync_val_compare_and_swap (dst, old_val, val) != old_val);
}
#if defined (TARGET_OSX) || defined (__arm__) || (defined (__mips__) && !defined (__mips64)) || (defined (__powerpc__) && !defined (__powerpc64__))
@@ -258,6 +324,16 @@ static inline gint64 InterlockedRead64(volatile gint64 *src)
#endif
+static inline gpointer InterlockedReadPointer(volatile gpointer *src)
+{
+ return InterlockedCompareExchangePointer (src, NULL, NULL);
+}
+
+static inline void InterlockedWritePointer(volatile gpointer *dst, gpointer val)
+{
+ InterlockedExchangePointer (dst, val);
+}
+
/* We always implement this in terms of a 64-bit cmpxchg since
* GCC doesn't have an intrisic to model it anyway. */
static inline gint64 InterlockedExchange64(volatile gint64 *val, gint64 new_val)
@@ -569,10 +645,16 @@ static inline gint32 InterlockedExchangeAdd(gint32 volatile *val, gint32 add)
extern gpointer InterlockedExchangePointer(volatile gpointer *dest, gpointer exch);
extern gint32 InterlockedExchangeAdd(volatile gint32 *dest, gint32 add);
extern gint64 InterlockedExchangeAdd64(volatile gint64 *dest, gint64 add);
+extern gint8 InterlockedRead8(volatile gint8 *src);
+extern gint16 InterlockedRead16(volatile gint16 *src);
extern gint32 InterlockedRead(volatile gint32 *src);
extern gint64 InterlockedRead64(volatile gint64 *src);
+extern gpointer InterlockedReadPointer(volatile gpointer *src);
+extern void InterlockedWrite8(volatile gint8 *dst, gint8 val);
+extern void InterlockedWrite16(volatile gint16 *dst, gint16 val);
extern void InterlockedWrite(volatile gint32 *dst, gint32 val);
extern void InterlockedWrite64(volatile gint64 *dst, gint64 val);
+extern void InterlockedWritePointer(volatile gpointer *dst, gpointer val);
#endif
Commit: 3f6b4e4fea5f93cd1d16581ebacebb578e98e887
Author: Alex Rønne Petersen <[email protected] >
Date: 2013-10-23 22:06:23 GMT
URL: https://github.com/mono/mono/commit/3f6b4e4fea5f93cd1d16581ebacebb578e98e887
Fix the semantics for System.Threading.Volatile methods.
This is a bit tricky. The System.Threading.Thread.Volatile* methods
don't actually guarantee atomicity; all they guarantee is that the
runtime will insert acquire barriers for loads and release barriers
for stores. The methods in the System.Threading.Volatile class,
however, require both barriers *and* atomicity.
So, we need an entirely separate set of icalls for the Volatile
class in order to get the right semantics there.
These APIs are insane.
Changed paths:
M mono/metadata/icall-def.h
M mono/metadata/threads-types.h
M mono/metadata/threads.c
Modified: mono/metadata/icall-def.h
===================================================================
@@ -923,33 +923,33 @@
ICALL_TYPE(VOLATILE, "System.Threading.Volatile", VOLATILE_28)
ICALL(VOLATILE_28, "Read(T&)", ves_icall_System_Threading_Volatile_Read_T)
-ICALL(VOLATILE_1, "Read(bool&)", ves_icall_System_Threading_Thread_VolatileRead1)
-ICALL(VOLATILE_2, "Read(byte&)", ves_icall_System_Threading_Thread_VolatileRead1)
-ICALL(VOLATILE_3, "Read(double&)", ves_icall_System_Threading_Thread_VolatileReadDouble)
-ICALL(VOLATILE_4, "Read(int&)", ves_icall_System_Threading_Thread_VolatileRead4)
-ICALL(VOLATILE_5, "Read(int16&)", ves_icall_System_Threading_Thread_VolatileRead2)
-ICALL(VOLATILE_6, "Read(intptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr)
-ICALL(VOLATILE_7, "Read(long&)", ves_icall_System_Threading_Thread_VolatileRead8)
-ICALL(VOLATILE_8, "Read(sbyte&)", ves_icall_System_Threading_Thread_VolatileRead1)
-ICALL(VOLATILE_9, "Read(single&)", ves_icall_System_Threading_Thread_VolatileReadFloat)
-ICALL(VOLATILE_10, "Read(uint&)", ves_icall_System_Threading_Thread_VolatileRead4)
-ICALL(VOLATILE_11, "Read(uint16&)", ves_icall_System_Threading_Thread_VolatileRead2)
-ICALL(VOLATILE_12, "Read(uintptr&)", ves_icall_System_Threading_Thread_VolatileReadIntPtr)
-ICALL(VOLATILE_13, "Read(ulong&)", ves_icall_System_Threading_Thread_VolatileRead8)
+ICALL(VOLATILE_1, "Read(bool&)", ves_icall_System_Threading_Volatile_Read1)
+ICALL(VOLATILE_2, "Read(byte&)", ves_icall_System_Threading_Volatile_Read1)
+ICALL(VOLATILE_3, "Read(double&)", ves_icall_System_Threading_Volatile_ReadDouble)
+ICALL(VOLATILE_4, "Read(int&)", ves_icall_System_Threading_Volatile_Read4)
+ICALL(VOLATILE_5, "Read(int16&)", ves_icall_System_Threading_Volatile_Read2)
+ICALL(VOLATILE_6, "Read(intptr&)", ves_icall_System_Threading_Volatile_ReadIntPtr)
+ICALL(VOLATILE_7, "Read(long&)", ves_icall_System_Threading_Volatile_Read8)
+ICALL(VOLATILE_8, "Read(sbyte&)", ves_icall_System_Threading_Volatile_Read1)
+ICALL(VOLATILE_9, "Read(single&)", ves_icall_System_Threading_Volatile_ReadFloat)
+ICALL(VOLATILE_10, "Read(uint&)", ves_icall_System_Threading_Volatile_Read4)
+ICALL(VOLATILE_11, "Read(uint16&)", ves_icall_System_Threading_Volatile_Read2)
+ICALL(VOLATILE_12, "Read(uintptr&)", ves_icall_System_Threading_Volatile_ReadIntPtr)
+ICALL(VOLATILE_13, "Read(ulong&)", ves_icall_System_Threading_Volatile_Read8)
ICALL(VOLATILE_27, "Write(T&,T)", ves_icall_System_Threading_Volatile_Write_T)
-ICALL(VOLATILE_14, "Write(bool&,bool)", ves_icall_System_Threading_Thread_VolatileWrite1)
-ICALL(VOLATILE_15, "Write(byte&,byte)", ves_icall_System_Threading_Thread_VolatileWrite1)
-ICALL(VOLATILE_16, "Write(double&,double)", ves_icall_System_Threading_Thread_VolatileWriteDouble)
-ICALL(VOLATILE_17, "Write(int&,int)", ves_icall_System_Threading_Thread_VolatileWrite4)
-ICALL(VOLATILE_18, "Write(int16&,int16)", ves_icall_System_Threading_Thread_VolatileWrite2)
-ICALL(VOLATILE_19, "Write(intptr&,intptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr)
-ICALL(VOLATILE_20, "Write(long&,long)", ves_icall_System_Threading_Thread_VolatileWrite8)
-ICALL(VOLATILE_21, "Write(sbyte&,sbyte)", ves_icall_System_Threading_Thread_VolatileWrite1)
-ICALL(VOLATILE_22, "Write(single&,single)", ves_icall_System_Threading_Thread_VolatileWriteFloat)
-ICALL(VOLATILE_23, "Write(uint&,uint)", ves_icall_System_Threading_Thread_VolatileWrite4)
-ICALL(VOLATILE_24, "Write(uint16&,uint16)", ves_icall_System_Threading_Thread_VolatileWrite2)
-ICALL(VOLATILE_25, "Write(uintptr&,uintptr)", ves_icall_System_Threading_Thread_VolatileWriteIntPtr)
-ICALL(VOLATILE_26, "Write(ulong&,ulong)", ves_icall_System_Threading_Thread_VolatileWrite8)
+ICALL(VOLATILE_14, "Write(bool&,bool)", ves_icall_System_Threading_Volatile_Write1)
+ICALL(VOLATILE_15, "Write(byte&,byte)", ves_icall_System_Threading_Volatile_Write1)
+ICALL(VOLATILE_16, "Write(double&,double)", ves_icall_System_Threading_Volatile_WriteDouble)
+ICALL(VOLATILE_17, "Write(int&,int)", ves_icall_System_Threading_Volatile_Write4)
+ICALL(VOLATILE_18, "Write(int16&,int16)", ves_icall_System_Threading_Volatile_Write2)
+ICALL(VOLATILE_19, "Write(intptr&,intptr)", ves_icall_System_Threading_Volatile_WriteIntPtr)
+ICALL(VOLATILE_20, "Write(long&,long)", ves_icall_System_Threading_Volatile_Write8)
+ICALL(VOLATILE_21, "Write(sbyte&,sbyte)", ves_icall_System_Threading_Volatile_Write1)
+ICALL(VOLATILE_22, "Write(single&,single)", ves_icall_System_Threading_Volatile_WriteFloat)
+ICALL(VOLATILE_23, "Write(uint&,uint)", ves_icall_System_Threading_Volatile_Write4)
+ICALL(VOLATILE_24, "Write(uint16&,uint16)", ves_icall_System_Threading_Volatile_Write2)
+ICALL(VOLATILE_25, "Write(uintptr&,uintptr)", ves_icall_System_Threading_Volatile_WriteIntPtr)
+ICALL(VOLATILE_26, "Write(ulong&,ulong)", ves_icall_System_Threading_Volatile_Write8)
ICALL_TYPE(WAITH, "System.Threading.WaitHandle", WAITH_1)
ICALL(WAITH_1, "SignalAndWait_Internal", ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal)
Modified: mono/metadata/threads-types.h
===================================================================
@@ -153,7 +153,22 @@ gpointer mono_create_thread (WapiSecurityAttributes *security,
void ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float) MONO_INTERNAL;
void ves_icall_System_Threading_Thread_VolatileWriteDouble (void *ptr, double) MONO_INTERNAL;
+gint8 ves_icall_System_Threading_Volatile_Read1 (void *ptr) MONO_INTERNAL;
+gint16 ves_icall_System_Threading_Volatile_Read2 (void *ptr) MONO_INTERNAL;
+gint32 ves_icall_System_Threading_Volatile_Read4 (void *ptr) MONO_INTERNAL;
+gint64 ves_icall_System_Threading_Volatile_Read8 (void *ptr) MONO_INTERNAL;
+void * ves_icall_System_Threading_Volatile_ReadIntPtr (void *ptr) MONO_INTERNAL;
+double ves_icall_System_Threading_Volatile_ReadDouble (void *ptr) MONO_INTERNAL;
+float ves_icall_System_Threading_Volatile_ReadFloat (void *ptr) MONO_INTERNAL;
MonoObject* ves_icall_System_Threading_Volatile_Read_T (void *ptr) MONO_INTERNAL;
+
+void ves_icall_System_Threading_Volatile_Write1 (void *ptr, gint8) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_Write2 (void *ptr, gint16) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_Write4 (void *ptr, gint32) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_Write8 (void *ptr, gint64) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_WriteIntPtr (void *ptr, void *) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_WriteFloat (void *ptr, float) MONO_INTERNAL;
+void ves_icall_System_Threading_Volatile_WriteDouble (void *ptr, double) MONO_INTERNAL;
void ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value) MONO_INTERNAL;
void ves_icall_System_Threading_Thread_MemoryBarrier (void) MONO_INTERNAL;
Modified: mono/metadata/threads.c
===================================================================
@@ -2457,12 +2457,60 @@ void mono_thread_stop (MonoThread *thread)
return tmp;
}
+gint8
+ves_icall_System_Threading_Volatile_Read1 (void *ptr)
+{
+ return InterlockedRead8 (ptr);
+}
+
+gint16
+ves_icall_System_Threading_Volatile_Read2 (void *ptr)
+{
+ return InterlockedRead16 (ptr);
+}
+
+gint32
+ves_icall_System_Threading_Volatile_Read4 (void *ptr)
+{
+ return InterlockedRead (ptr);
+}
+
+gint64
+ves_icall_System_Threading_Volatile_Read8 (void *ptr)
+{
+ return InterlockedRead64 (ptr);
+}
+
+void *
+ves_icall_System_Threading_Volatile_ReadIntPtr (void *ptr)
+{
+ return InterlockedReadPointer (ptr);
+}
+
+double
+ves_icall_System_Threading_Volatile_ReadDouble (void *ptr)
+{
+ LongDoubleUnion u;
+
+ u.ival = InterlockedRead64 (ptr);
+
+ return u.fval;
+}
+
+float
+ves_icall_System_Threading_Volatile_ReadFloat (void *ptr)
+{
+ IntFloatUnion u;
+
+ u.ival = InterlockedRead (ptr);
+
+ return u.fval;
+}
+
MonoObject*
ves_icall_System_Threading_Volatile_Read_T (void *ptr)
{
- volatile MonoObject *tmp;
- mono_atomic_load_acquire (tmp, volatile MonoObject *, (volatile MonoObject **) ptr);
- return (MonoObject *) tmp;
+ return InterlockedReadPointer (ptr);
}
void
@@ -2514,6 +2562,56 @@ void mono_thread_stop (MonoThread *thread)
}
void
+ves_icall_System_Threading_Volatile_Write1 (void *ptr, gint8 value)
+{
+ InterlockedWrite8 (ptr, value);
+}
+
+void
+ves_icall_System_Threading_Volatile_Write2 (void *ptr, gint16 value)
+{
+ InterlockedWrite16 (ptr, value);
+}
+
+void
+ves_icall_System_Threading_Volatile_Write4 (void *ptr, gint32 value)
+{
+ InterlockedWrite (ptr, value);
+}
+
+void
+ves_icall_System_Threading_Volatile_Write8 (void *ptr, gint64 value)
+{
+ InterlockedWrite64 (ptr, value);
+}
+
+void
+ves_icall_System_Threading_Volatile_WriteIntPtr (void *ptr, void *value)
+{
+ InterlockedWritePointer (ptr, value);
+}
+
+void
+ves_icall_System_Threading_Volatile_WriteDouble (void *ptr, double value)
+{
+ LongDoubleUnion u;
+
+ u.fval = value;
+
+ InterlockedWrite64 (ptr, u.ival);
+}
+
+void
+ves_icall_System_Threading_Volatile_WriteFloat (void *ptr, float value)
+{
+ IntFloatUnion u;
+
+ u.fval = value;
+
+ InterlockedWrite (ptr, u.ival);
+}
+
+void
ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value)
{
mono_gc_wbarrier_generic_store_atomic (ptr, value);
Commit: 04a90dcbb0e1ceea50731553f24800edef85e1fa
Author: Alex Rønne Petersen <[email protected] >
Date: 2013-10-23 22:06:23 GMT
URL: https://github.com/mono/mono/commit/04a90dcbb0e1ceea50731553f24800edef85e1fa
Fix mono_gc_wbarrier_generic_store_atomic semantics.
It should ensure that stores are fully atomic with barriers.
Changed paths:
M mono/metadata/boehm-gc.c
M mono/metadata/null-gc.c
M mono/metadata/sgen-gc.c
Modified: mono/metadata/boehm-gc.c
===================================================================
@@ -21,6 +21,7 @@
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/runtime.h>
+#include <mono/utils/atomic.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/mono-time.h>
@@ -627,7 +628,7 @@
void
mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
{
- mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+ InterlockedWritePointer (ptr, value);
}
void
Modified: mono/metadata/null-gc.c
===================================================================
@@ -195,7 +195,7 @@
void
mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
{
- mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+ InterlockedWritePointer (ptr, value);
}
void
Modified: mono/metadata/sgen-gc.c
===================================================================
@@ -4400,7 +4400,7 @@ struct _EphemeronLinkNode {
SGEN_LOG (8, "Wbarrier atomic store at %p to %p (%s)", ptr, value, value ? safe_name (value) : "null");
- mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+ InterlockedWritePointer (ptr, value);
if (ptr_in_nursery (value))
mono_gc_wbarrier_generic_nostore (ptr);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches