Add mono_gc_wbarrier_generic_store_atomic () function.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Mon, 21 Oct 2013 15:53:28 +0000 (17:53 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Mon, 21 Oct 2013 16:08:16 +0000 (18:08 +0200)
This is used in place of mono_gc_wbarrier_generic_store () when
we need the store to be atomic with release semantics.

docs/current-api
docs/public-api
mono/metadata/boehm-gc.c
mono/metadata/null-gc.c
mono/metadata/object.h
mono/metadata/sgen-gc.c
mono/metadata/threads.c
msvc/mono.def
msvc/monosgen.def

index d0efffcaba0b76d760a543e303f2ef6f94d5200d..1bbddca612314f610d3ad92de92757182d325d9f 100644 (file)
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
index 082bfd9fdd13a7ba75f056ffd3cfc0b86936f180..231ecf171a990dddb49057c375be48cb19ecc7bc 100644 (file)
@@ -307,6 +307,7 @@ mono_gc_out_of_memory
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
index bbfaa8df97f44b22b2db3b43aaaa3ed6dbf1c066..a97b950969f58fca8e29260a1dc15e76db10f0ef 100644 (file)
@@ -22,6 +22,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/runtime.h>
 #include <mono/utils/mono-logger-internal.h>
+#include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/dtrace.h>
@@ -623,6 +624,12 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
        *(void**)ptr = value;
 }
 
+void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+       mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
 void
 mono_gc_wbarrier_generic_nostore (gpointer ptr)
 {
index 13446ee0ecd627f90e82238d4401d33bcb8e0bdb..0430dd5cbf62ce76f4d905d116a71c4216e8b19a 100644 (file)
@@ -192,6 +192,12 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
        *(void**)ptr = value;
 }
 
+void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+       mono_atomic_store_release ((volatile MonoObject **) ptr, value);
+}
+
 void
 mono_gc_wbarrier_generic_nostore (gpointer ptr)
 {
index 70ff5814b323cb37e50fcdb9d870b2798bf17eef..959c09e49c6314e54e6e0c3be2daf0fc0adc2423 100644 (file)
@@ -316,6 +316,7 @@ MONO_API void mono_gc_wbarrier_set_field     (MonoObject *obj, void* field_ptr,
 MONO_API void mono_gc_wbarrier_set_arrayref  (MonoArray *arr, void* slot_ptr, MonoObject* value);
 MONO_API void mono_gc_wbarrier_arrayref_copy (void* dest_ptr, void* src_ptr, int count);
 MONO_API void mono_gc_wbarrier_generic_store (void* ptr, MonoObject* value);
+MONO_API void mono_gc_wbarrier_generic_store_atomic (void *ptr, MonoObject *value);
 MONO_API void mono_gc_wbarrier_generic_nostore (void* ptr);
 MONO_API void mono_gc_wbarrier_value_copy    (void* dest, void* src, int count, MonoClass *klass);
 MONO_API void mono_gc_wbarrier_object_copy   (MonoObject* obj, MonoObject *src);
index b88a4dd5d8bc15a2ff532fa1d1368e32b953d891..2afe16a68c21589a9339e91d2a7bf7a11efc5f3d 100644 (file)
@@ -317,6 +317,7 @@ static int stat_wbarrier_set_field = 0;
 static int stat_wbarrier_set_arrayref = 0;
 static int stat_wbarrier_arrayref_copy = 0;
 static int stat_wbarrier_generic_store = 0;
+static int stat_wbarrier_generic_store_atomic = 0;
 static int stat_wbarrier_set_root = 0;
 static int stat_wbarrier_value_copy = 0;
 static int stat_wbarrier_object_copy = 0;
@@ -2234,6 +2235,7 @@ init_stats (void)
        mono_counters_register ("WBarrier set arrayref", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_arrayref);
        mono_counters_register ("WBarrier arrayref copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_arrayref_copy);
        mono_counters_register ("WBarrier generic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store);
+       mono_counters_register ("WBarrier generic atomic store called", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_generic_store_atomic);
        mono_counters_register ("WBarrier set root", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_set_root);
        mono_counters_register ("WBarrier value copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_value_copy);
        mono_counters_register ("WBarrier object copy", MONO_COUNTER_GC | MONO_COUNTER_INT, &stat_wbarrier_object_copy);
@@ -4388,6 +4390,24 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* value)
        sgen_dummy_use (value);
 }
 
+/* Same as mono_gc_wbarrier_generic_store () but performs the store
+ * as an atomic operation with release semantics.
+ */
+void
+mono_gc_wbarrier_generic_store_atomic (gpointer ptr, MonoObject *value)
+{
+       HEAVY_STAT (++stat_wbarrier_generic_store_atomic);
+
+       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);
+
+       if (ptr_in_nursery (value))
+               mono_gc_wbarrier_generic_nostore (ptr);
+
+       sgen_dummy_use (value);
+}
+
 void mono_gc_wbarrier_value_copy_bitmap (gpointer _dest, gpointer _src, int size, unsigned bitmap)
 {
        mword *dest = _dest;
index 808c1a4254cb986b749c37ccc962bbadb02a3d93..294aa735ca336fd134b6b3ba668d919e58dba72c 100755 (executable)
@@ -2490,8 +2490,7 @@ ves_icall_System_Threading_Thread_VolatileWriteIntPtr (void *ptr, void *value)
 void
 ves_icall_System_Threading_Thread_VolatileWriteObject (void *ptr, void *value)
 {
-       mono_atomic_store_release ((volatile MonoObject **) ptr, value);
-       mono_gc_wbarrier_generic_nostore (ptr);
+       mono_gc_wbarrier_generic_store_atomic (ptr, value);
 }
 
 void
@@ -2509,8 +2508,7 @@ ves_icall_System_Threading_Thread_VolatileWriteFloat (void *ptr, float value)
 void
 ves_icall_System_Threading_Volatile_Write_T (void *ptr, MonoObject *value)
 {
-       mono_atomic_store_release ((volatile MonoObject **) ptr, value);
-       mono_gc_wbarrier_generic_nostore (ptr);
+       mono_gc_wbarrier_generic_store_atomic (ptr, value);
 }
 
 void
index 345a71e08b8bffb3b47846a5b9b7df61da98a927..7a264b225fb53512fe9c135939e897111567cf50 100644 (file)
@@ -331,6 +331,7 @@ mono_gc_walk_heap
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field
index 6cb88477680f26283fce68974379902528fb19d7..d176f9520a79a1d42c7f92c15841470d589a4457 100644 (file)
@@ -331,6 +331,7 @@ mono_gc_walk_heap
 mono_gc_wbarrier_arrayref_copy
 mono_gc_wbarrier_generic_nostore
 mono_gc_wbarrier_generic_store
+mono_gc_wbarrier_generic_store_atomic
 mono_gc_wbarrier_object_copy
 mono_gc_wbarrier_set_arrayref
 mono_gc_wbarrier_set_field