summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alexrp@xamarin.com>2013-10-21 17:53:28 +0200
committerJo Shields <directhex@apebox.org>2013-10-23 15:17:33 +0100
commit771e7142b80317eb2a95bbf711433c34a2770b1f (patch)
tree7e0315afdcdb2b0341b1c2bf60f314dee382b0d7
parent3c16fd282b6f364f83833cacc66a443ef8462fc6 (diff)
downloadmono-771e7142b80317eb2a95bbf711433c34a2770b1f.tar.gz
Add mono_gc_wbarrier_generic_store_atomic () function.
This is used in place of mono_gc_wbarrier_generic_store () when we need the store to be atomic with release semantics. (cherry picked from commit e4d2cc49a03b2cb7b31cddfd630e319bc4d344a1) Conflicts: msvc/monosgen.def
-rw-r--r--docs/current-api1
-rw-r--r--docs/public-api1
-rw-r--r--mono/metadata/boehm-gc.c7
-rw-r--r--mono/metadata/null-gc.c6
-rw-r--r--mono/metadata/object.h1
-rw-r--r--mono/metadata/sgen-gc.c20
-rwxr-xr-xmono/metadata/threads.c6
-rw-r--r--msvc/mono.def1
8 files changed, 39 insertions, 4 deletions
diff --git a/docs/current-api b/docs/current-api
index d0efffcaba..1bbddca612 100644
--- a/docs/current-api
+++ b/docs/current-api
@@ -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
diff --git a/docs/public-api b/docs/public-api
index 082bfd9fdd..231ecf171a 100644
--- a/docs/public-api
+++ b/docs/public-api
@@ -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
diff --git a/mono/metadata/boehm-gc.c b/mono/metadata/boehm-gc.c
index 26665e50f5..0cb8292dcb 100644
--- a/mono/metadata/boehm-gc.c
+++ b/mono/metadata/boehm-gc.c
@@ -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>
@@ -624,6 +625,12 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* 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)
{
}
diff --git a/mono/metadata/null-gc.c b/mono/metadata/null-gc.c
index 13446ee0ec..0430dd5cbf 100644
--- a/mono/metadata/null-gc.c
+++ b/mono/metadata/null-gc.c
@@ -193,6 +193,12 @@ mono_gc_wbarrier_generic_store (gpointer ptr, MonoObject* 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)
{
}
diff --git a/mono/metadata/object.h b/mono/metadata/object.h
index 70ff5814b3..959c09e49c 100644
--- a/mono/metadata/object.h
+++ b/mono/metadata/object.h
@@ -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);
diff --git a/mono/metadata/sgen-gc.c b/mono/metadata/sgen-gc.c
index 8ce0994b50..2b6d1e3963 100644
--- a/mono/metadata/sgen-gc.c
+++ b/mono/metadata/sgen-gc.c
@@ -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;
@@ -2217,6 +2218,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);
@@ -4424,6 +4426,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;
diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c
index 7a00d1fbb9..59f8293f86 100755
--- a/mono/metadata/threads.c
+++ b/mono/metadata/threads.c
@@ -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
diff --git a/msvc/mono.def b/msvc/mono.def
index 345a71e08b..7a264b225f 100644
--- a/msvc/mono.def
+++ b/msvc/mono.def
@@ -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