diff options
author | Alex Rønne Petersen <alexrp@xamarin.com> | 2013-10-21 17:53:28 +0200 |
---|---|---|
committer | Jo Shields <directhex@apebox.org> | 2013-10-23 15:17:33 +0100 |
commit | 771e7142b80317eb2a95bbf711433c34a2770b1f (patch) | |
tree | 7e0315afdcdb2b0341b1c2bf60f314dee382b0d7 | |
parent | 3c16fd282b6f364f83833cacc66a443ef8462fc6 (diff) | |
download | mono-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-api | 1 | ||||
-rw-r--r-- | docs/public-api | 1 | ||||
-rw-r--r-- | mono/metadata/boehm-gc.c | 7 | ||||
-rw-r--r-- | mono/metadata/null-gc.c | 6 | ||||
-rw-r--r-- | mono/metadata/object.h | 1 | ||||
-rw-r--r-- | mono/metadata/sgen-gc.c | 20 | ||||
-rwxr-xr-x | mono/metadata/threads.c | 6 | ||||
-rw-r--r-- | msvc/mono.def | 1 |
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 |