[corlib] LocalDataStoreSlot from reference sources
authorMarek Safar <marek.safar@gmail.com>
Tue, 19 May 2015 20:06:27 +0000 (22:06 +0200)
committerMarek Safar <marek.safar@gmail.com>
Tue, 19 May 2015 20:06:58 +0000 (22:06 +0200)
external/referencesource
mcs/class/corlib/System.Runtime.Remoting.Contexts/Context.cs
mcs/class/corlib/System.Threading/NamedDataSlot.cs [deleted file]
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/LocalDataStoreSlot.cs [deleted file]
mcs/class/corlib/corlib.dll.sources
mono/metadata/icall-def.h
mono/metadata/threads-types.h
mono/metadata/threads.c

index b8813958c3630d1b06d2a34d8d3b74bf3db79a38..ce1b13e7cdfd610d243207faab3e7a1237d36132 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b8813958c3630d1b06d2a34d8d3b74bf3db79a38
+Subproject commit ce1b13e7cdfd610d243207faab3e7a1237d36132
index e184e3b9762a4f55d1fa653337c76b89dea528cb..35dd8f5858afce346da2aeeb03671031b0252509 100644 (file)
@@ -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 (file)
index 0931fb8..0000000
+++ /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<string, LocalDataStoreSlot> datastorehash;
-
-               public NamedDataSlot (bool thread_local)
-               {
-                       this.thread_local = thread_local;
-               }
-
-               public LocalDataStoreSlot Allocate (string name)
-               {               
-                       lock (this) {
-                               if (datastorehash == null)
-                                       datastorehash = new Dictionary<string, LocalDataStoreSlot> ();
-
-                               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<string, LocalDataStoreSlot> ();
-
-                               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<string, LocalDataStoreSlot> ();
-
-                               if (datastorehash.ContainsKey (name)) {
-                                       datastorehash.Remove (name);
-                               }
-                       }
-               }
-       }
-}
index 6bcb53a60581a649587a9e6e0b91dc59c0fe136f..ce0ba639bed32190560034bac6d79b15e9c14255 100644 (file)
@@ -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 (file)
index 232c7ed..0000000
+++ /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;
-                       }
-               }
-       }
-}
index 2a03392d713edf670855fb1897c140f946d90010..5c70282854bef6cfccca5dd868a442536f15cdd2 100644 (file)
@@ -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
index 14e349bf0681ad68f1cbaf1ebf2f8bfc0543b68e..93c3bb54dbd6b7d9470de5f4c0ffce4bda608dbf 100644 (file)
@@ -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)
index ae7b15885611e205e9d83f8c66353afb24b38557..a901e2b41bbf89749c54d9e91b411e152c6b4a69 100644 (file)
@@ -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);
index e1755a1dce66ffe962c0f12b82dd68a0fc05bd02..2c272ce15acd1109837732cab9f7b7de07eb2ae3 100644 (file)
@@ -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)
 {