[mono/mono] [3 commits] 41d1358f: Add Interlocked{Read, Write}{8, 16, Pointer} functions.

"alexrp ([email protected])" <[email protected]>
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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.