From: Marek Safar Date: Tue, 19 May 2015 20:06:27 +0000 (+0200) Subject: [corlib] LocalDataStoreSlot from reference sources X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=317c3a8efb71eaf49274c1928daee5e5b76b7767;p=mono.git [corlib] LocalDataStoreSlot from reference sources --- diff --git a/external/referencesource b/external/referencesource index b8813958c36..ce1b13e7cdf 160000 --- a/external/referencesource +++ b/external/referencesource @@ -1 +1 @@ -Subproject commit b8813958c3630d1b06d2a34d8d3b74bf3db79a38 +Subproject commit ce1b13e7cdfd610d243207faab3e7a1237d36132 diff --git a/mcs/class/corlib/System.Runtime.Remoting.Contexts/Context.cs b/mcs/class/corlib/System.Runtime.Remoting.Contexts/Context.cs index e184e3b9762..35dd8f5858a 100644 --- a/mcs/class/corlib/System.Runtime.Remoting.Contexts/Context.cs +++ b/mcs/class/corlib/System.Runtime.Remoting.Contexts/Context.cs @@ -62,8 +62,6 @@ namespace System.Runtime.Remoting.Contexts { [ContextStatic] static object[] local_slots; - static NamedDataSlot namedDataSlot; - // Default server context sink chain static IMessageSink default_server_context_sink; @@ -78,6 +76,10 @@ namespace System.Runtime.Remoting.Contexts { static int global_count; + volatile LocalDataStoreHolder _localDataStore; + + static LocalDataStoreMgr _localDataStoreMgr = new LocalDataStoreMgr(); + static DynamicPropertyCollection global_dynamic_properties; DynamicPropertyCollection context_dynamic_properties; ContextCallbackObject callback_object = null; @@ -368,60 +370,55 @@ namespace System.Runtime.Remoting.Contexts { callback_object.DoCallBack (deleg); } - static NamedDataSlot NamedDataSlot { - get { - if (namedDataSlot == null) - Interlocked.CompareExchange (ref namedDataSlot, new NamedDataSlot (false), null); - - return namedDataSlot; + private LocalDataStore MyLocalStore + { + get + { + if (_localDataStore == null) + { + // It's OK to lock the manager here because it is going to lock + // itself anyway. + lock (_localDataStoreMgr) + { + if (_localDataStore == null) + { + // The local store has not yet been created for this thread. + _localDataStore = _localDataStoreMgr.CreateLocalDataStore(); + } + } + } + return _localDataStore.Store; } } public static LocalDataStoreSlot AllocateDataSlot () { - return new LocalDataStoreSlot (false); + return _localDataStoreMgr.AllocateDataSlot (); } public static LocalDataStoreSlot AllocateNamedDataSlot (string name) { - return NamedDataSlot.Allocate (name); + return _localDataStoreMgr.AllocateNamedDataSlot (name); } public static void FreeNamedDataSlot (string name) { - NamedDataSlot.Free (name); + _localDataStoreMgr.FreeNamedDataSlot (name); } public static LocalDataStoreSlot GetNamedDataSlot (string name) { - return NamedDataSlot.Get (name); + return _localDataStoreMgr.GetNamedDataSlot (name); } public static object GetData (LocalDataStoreSlot slot) { - object[] slots = local_slots; - if (slot == null) - throw new ArgumentNullException ("slot"); - if (slots != null && slot.slot < slots.Length) - return slots [slot.slot]; - return null; + return Thread.CurrentContext.MyLocalStore.GetData (slot); } public static void SetData (LocalDataStoreSlot slot, object data) { - object[] slots = local_slots; - if (slot == null) - throw new ArgumentNullException ("slot"); - if (slots == null) { - slots = new object [slot.slot + 2]; - local_slots = slots; - } else if (slot.slot >= slots.Length) { - object[] nslots = new object [slot.slot + 2]; - slots.CopyTo (nslots, 0); - slots = nslots; - local_slots = slots; - } - slots [slot.slot] = data; + Thread.CurrentContext.MyLocalStore.SetData (slot, data); } } diff --git a/mcs/class/corlib/System.Threading/NamedDataSlot.cs b/mcs/class/corlib/System.Threading/NamedDataSlot.cs deleted file mode 100644 index 0931fb8b930..00000000000 --- a/mcs/class/corlib/System.Threading/NamedDataSlot.cs +++ /dev/null @@ -1,92 +0,0 @@ -// -// NamedDataSlot.cs: -// -// Authors: -// Dick Porter (dick@ximian.com) -// Marek Safar (marek.safar@gmail.com) -// -// (C) Ximian, Inc. http://www.ximian.com -// Copyright (C) 2004-2006 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Collections.Generic; - -namespace System.Threading -{ - sealed class NamedDataSlot - { - bool thread_local; - // Stores a hash keyed by strings of LocalDataStoreSlot objects - Dictionary datastorehash; - - public NamedDataSlot (bool thread_local) - { - this.thread_local = thread_local; - } - - public LocalDataStoreSlot Allocate (string name) - { - lock (this) { - if (datastorehash == null) - datastorehash = new Dictionary (); - - if (datastorehash.ContainsKey (name)) { - // This exception isnt documented (of - // course) but .net throws it - throw new ArgumentException ("Named data slot already added"); - } - - var slot = new LocalDataStoreSlot (thread_local); - datastorehash.Add (name, slot); - return slot; - } - } - - public LocalDataStoreSlot Get (string name) - { - lock (this) { - if (datastorehash == null) - datastorehash = new Dictionary (); - - LocalDataStoreSlot slot; - if (!datastorehash.TryGetValue (name, out slot)) { - slot = new LocalDataStoreSlot (thread_local); - datastorehash.Add (name, slot); - } - - return slot; - } - } - - public void Free (string name) - { - lock (this) { - if (datastorehash == null) - datastorehash = new Dictionary (); - - if (datastorehash.ContainsKey (name)) { - datastorehash.Remove (name); - } - } - } - } -} diff --git a/mcs/class/corlib/System.Threading/Thread.cs b/mcs/class/corlib/System.Threading/Thread.cs index 6bcb53a6058..ce0ba639bed 100644 --- a/mcs/class/corlib/System.Threading/Thread.cs +++ b/mcs/class/corlib/System.Threading/Thread.cs @@ -141,8 +141,6 @@ namespace System.Threading { [ThreadStatic] static ExecutionContext _ec; - static NamedDataSlot namedDataSlot; - static internal CultureInfo default_culture; static internal CultureInfo default_ui_culture; @@ -317,64 +315,7 @@ namespace System.Threading { return (int)(CurrentThread.internal_thread.thread_id); } } - - static NamedDataSlot NamedDataSlot { - get { - if (namedDataSlot == null) - Interlocked.CompareExchange (ref namedDataSlot, new NamedDataSlot (true), null); - - return namedDataSlot; - } - } - - public static LocalDataStoreSlot AllocateNamedDataSlot (string name) - { - return NamedDataSlot.Allocate (name); - } - - public static void FreeNamedDataSlot (string name) - { - NamedDataSlot.Free (name); - } - - public static LocalDataStoreSlot AllocateDataSlot () - { - return new LocalDataStoreSlot (true); - } - - public static object GetData (LocalDataStoreSlot slot) { - object[] slots = local_slots; - if (slot == null) - throw new ArgumentNullException ("slot"); - if (slots != null && slot.slot < slots.Length) - return slots [slot.slot]; - return null; - } - - public static void SetData (LocalDataStoreSlot slot, object data) { - object[] slots = local_slots; - if (slot == null) - throw new ArgumentNullException ("slot"); - if (slots == null) { - slots = new object [slot.slot + 2]; - local_slots = slots; - } else if (slot.slot >= slots.Length) { - object[] nslots = new object [slot.slot + 2]; - slots.CopyTo (nslots, 0); - slots = nslots; - local_slots = slots; - } - slots [slot.slot] = data; - } - [MethodImplAttribute (MethodImplOptions.InternalCall)] - internal extern static void FreeLocalSlotValues (int slot, bool thread_local); - - public static LocalDataStoreSlot GetNamedDataSlot(string name) - { - return NamedDataSlot.Get (name); - } - public static AppDomain GetDomain() { return AppDomain.CurrentDomain; } @@ -936,29 +877,6 @@ namespace System.Threading { Start (); } -#if !MOBILE - void _Thread.GetIDsOfNames ([In] ref Guid riid, IntPtr rgszNames, uint cNames, uint lcid, IntPtr rgDispId) - { - throw new NotImplementedException (); - } - - void _Thread.GetTypeInfo (uint iTInfo, uint lcid, IntPtr ppTInfo) - { - throw new NotImplementedException (); - } - - void _Thread.GetTypeInfoCount (out uint pcTInfo) - { - throw new NotImplementedException (); - } - - void _Thread.Invoke (uint dispIdMember, [In] ref Guid riid, uint lcid, short wFlags, IntPtr pDispParams, - IntPtr pVarResult, IntPtr pExcepInfo, IntPtr puArgErr) - { - throw new NotImplementedException (); - } -#endif - internal CultureInfo GetCurrentUICultureNoAppX () { return CultureInfo.CurrentUICulture; diff --git a/mcs/class/corlib/System/LocalDataStoreSlot.cs b/mcs/class/corlib/System/LocalDataStoreSlot.cs deleted file mode 100644 index 232c7ede523..00000000000 --- a/mcs/class/corlib/System/LocalDataStoreSlot.cs +++ /dev/null @@ -1,97 +0,0 @@ -// -// System.LocalDataStoreSlot.cs -// -// Author: -// Dick Porter (dick@ximian.com) -// -// (C) Ximian, Inc. http://www.ximian.com -// - -// -// Copyright (C) 2004 Novell, Inc (http://www.novell.com) -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// - -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -namespace System -{ - [ComVisible (true)] - public sealed class LocalDataStoreSlot - { - internal int slot; - internal bool thread_local; // false for context-local - - static object lock_obj = new object (); - static bool[] slot_bitmap_thread; - static bool[] slot_bitmap_context; - - internal LocalDataStoreSlot (bool in_thread) - { - thread_local = in_thread; - lock (lock_obj) { - int i; - bool[] slot_bitmap; - if (in_thread) - slot_bitmap = slot_bitmap_thread; - else - slot_bitmap = slot_bitmap_context; - if (slot_bitmap != null) { - for (i = 0; i < slot_bitmap.Length; ++i) { - if (!slot_bitmap [i]) { - slot = i; - slot_bitmap [i] = true; - return; - } - } - bool[] new_bitmap = new bool [i + 2]; - slot_bitmap.CopyTo (new_bitmap, 0); - slot_bitmap = new_bitmap; - } else { - slot_bitmap = new bool [2]; - i = 0; - } - slot_bitmap [i] = true; - slot = i; - if (in_thread) - slot_bitmap_thread = slot_bitmap; - else - slot_bitmap_context = slot_bitmap; - } - } - - ~LocalDataStoreSlot () - { - /* first remove all the values from the slots and - * then free the slot itself for reuse. - */ - System.Threading.Thread.FreeLocalSlotValues (slot, thread_local); - lock (lock_obj) { - if (thread_local) - slot_bitmap_thread [slot] = false; - else - slot_bitmap_context [slot] = false; - } - } - } -} diff --git a/mcs/class/corlib/corlib.dll.sources b/mcs/class/corlib/corlib.dll.sources index 2a03392d713..5c70282854b 100644 --- a/mcs/class/corlib/corlib.dll.sources +++ b/mcs/class/corlib/corlib.dll.sources @@ -108,7 +108,6 @@ System/Guid.MonoTouch.cs System/IConsoleDriver.cs System/IntPtr.cs System/KnownTerminals.cs -System/LocalDataStoreSlot.cs System/MarshalByRefObject.cs System/Math.cs System/MonoAsyncCall.cs @@ -877,7 +876,6 @@ System.Threading/LockCookie.cs System.Threading/LockQueue.cs System.Threading/Monitor.cs System.Threading/Mutex.cs -System.Threading/NamedDataSlot.cs System.Threading/NativeEventCalls.cs System.Threading/NativeOverlapped.cs System.Threading/Overlapped.cs @@ -925,6 +923,8 @@ ReferenceSources/SharedStatics.cs ../../../external/referencesource/mscorlib/system/__filters.cs ../../../external/referencesource/mscorlib/system/__hresults.cs +../../../external/referencesource/mscorlib/system/_localdatastore.cs +../../../external/referencesource/mscorlib/system/_localdatastoremgr.cs ../../../external/referencesource/mscorlib/system/accessviolationexception.cs ../../../external/referencesource/mscorlib/system/action.cs ../../../external/referencesource/mscorlib/system/activator.cs diff --git a/mono/metadata/icall-def.h b/mono/metadata/icall-def.h index 14e349bf068..93c3bb54dbd 100644 --- a/mono/metadata/icall-def.h +++ b/mono/metadata/icall-def.h @@ -917,7 +917,6 @@ ICALL(THREAD_2, "ClrState(System.Threading.InternalThread,System.Threading.Threa ICALL(THREAD_2a, "ConstructInternalThread", ves_icall_System_Threading_Thread_ConstructInternalThread) ICALL(THREAD_3, "CurrentInternalThread_internal", mono_thread_internal_current) ICALL(THREAD_3a, "DestroyTlsData", mono_thread_destroy_tls) -ICALL(THREAD_4, "FreeLocalSlotValues", mono_thread_free_local_slot_values) ICALL(THREAD_55, "GetAbortExceptionState", ves_icall_System_Threading_Thread_GetAbortExceptionState) ICALL(THREAD_7, "GetDomainID", ves_icall_System_Threading_Thread_GetDomainID) ICALL(THREAD_8, "GetName_internal(System.Threading.InternalThread)", ves_icall_System_Threading_Thread_GetName_internal) diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index ae7b1588561..a901e2b41bb 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -198,7 +198,6 @@ void mono_alloc_special_static_data_free (GHashTable *special_static_fields); uint32_t mono_thread_alloc_tls (MonoReflectionType *type); void mono_thread_destroy_tls (uint32_t tls_offset); void mono_thread_destroy_domain_tls (MonoDomain *domain); -void mono_thread_free_local_slot_values (int slot, MonoBoolean is_thread_local); void mono_thread_current_check_pending_interrupt (void); void mono_thread_set_state (MonoInternalThread *thread, MonoThreadState state); diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index e1755a1dce6..2c272ce15ac 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -4064,9 +4064,6 @@ mono_thread_destroy_domain_tls (MonoDomain *domain) destroy_tls (domain, domain->tlsrec_list->tls_offset); } -static MonoClassField *thread_local_slots = NULL; -static MonoClassField *context_local_slots = NULL; - typedef struct { /* local tls data to get locals_slot from a thread */ guint32 offset; @@ -4128,52 +4125,6 @@ clear_context_local_slot (gpointer key, gpointer value, gpointer user_data) mono_array_set (slots_array, MonoObject *, sid->slot, NULL); } -void -mono_thread_free_local_slot_values (int slot, MonoBoolean thread_local) -{ - if (!thread_local_slots) { - thread_local_slots = mono_class_get_field_from_name (mono_defaults.thread_class, "local_slots"); - if (!thread_local_slots) { - g_warning ("local_slots field not found in Thread class"); - return; - } - } - - if (!context_local_slots) { - MonoClass *ctx_class = mono_class_from_name (mono_defaults.corlib, "System.Runtime.Remoting.Contexts", "Context"); - context_local_slots = mono_class_get_field_from_name (ctx_class, "local_slots"); - if (!context_local_slots) { - g_warning ("local_slots field not found in Context class"); - return; - } - } - - void *addr = NULL; - MonoDomain *domain = mono_domain_get (); - - mono_domain_lock (domain); - - if (domain->special_static_fields) - addr = g_hash_table_lookup (domain->special_static_fields, thread_local ? thread_local_slots : context_local_slots); - - mono_domain_unlock (domain); - - if (!addr) - return; - - LocalSlotID sid = { .slot = slot, .offset = GPOINTER_TO_UINT (addr) }; - - mono_threads_lock (); - - if (thread_local) { - mono_g_hash_table_foreach (threads, clear_thread_local_slot, &sid); - } else { - g_hash_table_foreach (contexts, clear_context_local_slot, &sid); - } - - mono_threads_unlock (); -} - #ifdef HOST_WIN32 static void CALLBACK dummy_apc (ULONG_PTR param) {