From ef36ea764e445c2c0665784749d1fd48ecd657c8 Mon Sep 17 00:00:00 2001 From: Jan Kotas Date: Wed, 1 Feb 2017 23:29:54 -0800 Subject: Delete LocalDataStore (#9266) This lives in CoreFX now --- src/mscorlib/model.xml | 3 - src/mscorlib/mscorlib.shared.sources.props | 2 - src/mscorlib/ref/mscorlib.cs | 6 - src/mscorlib/src/System/Threading/Thread.cs | 97 -------- src/mscorlib/src/System/_LocalDataStore.cs | 244 ------------------- src/mscorlib/src/System/_LocalDataStoreMgr.cs | 332 -------------------------- 6 files changed, 684 deletions(-) delete mode 100644 src/mscorlib/src/System/_LocalDataStore.cs delete mode 100644 src/mscorlib/src/System/_LocalDataStoreMgr.cs diff --git a/src/mscorlib/model.xml b/src/mscorlib/model.xml index 3c12877d13..95ddaf0715 100644 --- a/src/mscorlib/model.xml +++ b/src/mscorlib/model.xml @@ -3505,9 +3505,6 @@ - - - diff --git a/src/mscorlib/mscorlib.shared.sources.props b/src/mscorlib/mscorlib.shared.sources.props index 32156e3d37..d2b3cafda9 100644 --- a/src/mscorlib/mscorlib.shared.sources.props +++ b/src/mscorlib/mscorlib.shared.sources.props @@ -338,8 +338,6 @@ - - diff --git a/src/mscorlib/ref/mscorlib.cs b/src/mscorlib/ref/mscorlib.cs index 3a8ca2dc65..2ef242a1c9 100644 --- a/src/mscorlib/ref/mscorlib.cs +++ b/src/mscorlib/ref/mscorlib.cs @@ -2414,12 +2414,6 @@ namespace System public override string ToString() { throw null; } } [System.Runtime.InteropServices.ComVisibleAttribute(true)] - public sealed partial class LocalDataStoreSlot - { - internal LocalDataStoreSlot() { } - ~LocalDataStoreSlot() { } - } - [System.Runtime.InteropServices.ComVisibleAttribute(true)] public abstract partial class MarshalByRefObject { protected MarshalByRefObject() { } diff --git a/src/mscorlib/src/System/Threading/Thread.cs b/src/mscorlib/src/System/Threading/Thread.cs index ead7a5e4c9..8370b74d24 100644 --- a/src/mscorlib/src/System/Threading/Thread.cs +++ b/src/mscorlib/src/System/Threading/Thread.cs @@ -145,18 +145,6 @@ namespace System.Threading { private bool m_ForbidExecutionContextMutation; #endif - /*========================================================================= - ** This manager is responsible for storing the global data that is - ** shared amongst all the thread local stores. - =========================================================================*/ - static private LocalDataStoreMgr s_LocalDataStoreMgr; - - /*========================================================================= - ** Thread-local data store - =========================================================================*/ - [ThreadStatic] - static private LocalDataStoreHolder s_LocalDataStore; - // Do not move! Order of above fields needs to be preserved for alignment // with native code // See code:#threadCultureInfo @@ -498,78 +486,6 @@ namespace System.Threading { private extern void StartupSetApartmentStateInternal(); #endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT - /*========================================================================= - ** Allocates an un-named data slot. The slot is allocated on ALL the - ** threads. - =========================================================================*/ - public static LocalDataStoreSlot AllocateDataSlot() - { - return LocalDataStoreManager.AllocateDataSlot(); - } - - /*========================================================================= - ** Allocates a named data slot. The slot is allocated on ALL the - ** threads. Named data slots are "public" and can be manipulated by - ** anyone. - =========================================================================*/ - public static LocalDataStoreSlot AllocateNamedDataSlot(String name) - { - return LocalDataStoreManager.AllocateNamedDataSlot(name); - } - - /*========================================================================= - ** Looks up a named data slot. If the name has not been used, a new slot is - ** allocated. Named data slots are "public" and can be manipulated by - ** anyone. - =========================================================================*/ - public static LocalDataStoreSlot GetNamedDataSlot(String name) - { - return LocalDataStoreManager.GetNamedDataSlot(name); - } - - /*========================================================================= - ** Frees a named data slot. The slot is allocated on ALL the - ** threads. Named data slots are "public" and can be manipulated by - ** anyone. - =========================================================================*/ - public static void FreeNamedDataSlot(String name) - { - LocalDataStoreManager.FreeNamedDataSlot(name); - } - - /*========================================================================= - ** Retrieves the value from the specified slot on the current thread, for that thread's current domain. - =========================================================================*/ - public static Object GetData(LocalDataStoreSlot slot) - { - LocalDataStoreHolder dls = s_LocalDataStore; - if (dls == null) - { - // Make sure to validate the slot even if we take the quick path - LocalDataStoreManager.ValidateSlot(slot); - return null; - } - - return dls.Store.GetData(slot); - } - - /*========================================================================= - ** Sets the data in the specified slot on the currently running thread, for that thread's current domain. - =========================================================================*/ - public static void SetData(LocalDataStoreSlot slot, Object data) - { - LocalDataStoreHolder dls = s_LocalDataStore; - - // Create new DLS if one hasn't been created for this domain for this thread - if (dls == null) { - dls = LocalDataStoreManager.CreateLocalDataStore(); - s_LocalDataStore = dls; - } - - dls.Store.SetData(slot, data); - } - - // #threadCultureInfo // // Background: @@ -821,19 +737,6 @@ namespace System.Threading { [MethodImplAttribute(MethodImplOptions.InternalCall)] public static extern void MemoryBarrier(); - private static LocalDataStoreMgr LocalDataStoreManager - { - get - { - if (s_LocalDataStoreMgr == null) - { - Interlocked.CompareExchange(ref s_LocalDataStoreMgr, new LocalDataStoreMgr(), null); - } - - return s_LocalDataStoreMgr; - } - } - // Helper function to set the AbortReason for a thread abort. // Checks that they're not alredy set, and then atomically updates // the reason info (object + ADID). diff --git a/src/mscorlib/src/System/_LocalDataStore.cs b/src/mscorlib/src/System/_LocalDataStore.cs deleted file mode 100644 index a1fa488076..0000000000 --- a/src/mscorlib/src/System/_LocalDataStore.cs +++ /dev/null @@ -1,244 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================================= -** -** -** -** Purpose: Class that stores local data. This class is used in cooperation -** with the _LocalDataStoreMgr class. -** -** -=============================================================================*/ - -namespace System { - - using System; - using System.Threading; - using System.Runtime.CompilerServices; - using System.Diagnostics; - using System.Diagnostics.Contracts; - - // Helper class to aid removal of LocalDataStore from the LocalDataStoreMgr - // LocalDataStoreMgr does not holds references to LocalDataStoreHolder. It holds - // references to LocalDataStore only. LocalDataStoreHolder finalizer will run once - // the only outstanding reference to the store is in LocalDataStoreMgr. - sealed internal class LocalDataStoreHolder - { - private LocalDataStore m_Store; - - public LocalDataStoreHolder(LocalDataStore store) - { - m_Store = store; - } - - ~LocalDataStoreHolder() - { - LocalDataStore store = m_Store; - if (store == null) - return; - - store.Dispose(); - } - - public LocalDataStore Store - { - get - { - return m_Store; - } - } - } - - sealed internal class LocalDataStoreElement - { - private Object m_value; - private long m_cookie; // This is immutable cookie of the slot used to verify that - // the value is indeed indeed owned by the slot. Necessary - // to avoid resurection holes. - - public LocalDataStoreElement(long cookie) - { - m_cookie = cookie; - } - - public Object Value - { - get - { - return m_value; - } - set - { - m_value = value; - } - } - - public long Cookie - { - get - { - return m_cookie; - } - } - } - - // This class will not be marked serializable - sealed internal class LocalDataStore - { - private LocalDataStoreElement[] m_DataTable; - private LocalDataStoreMgr m_Manager; - - /*========================================================================= - ** Initialize the data store. - =========================================================================*/ - public LocalDataStore(LocalDataStoreMgr mgr, int InitialCapacity) - { - // Store the manager of the local data store. - m_Manager = mgr; - - // Allocate the array that will contain the data. - m_DataTable = new LocalDataStoreElement[InitialCapacity]; - } - - /*========================================================================= - ** Delete this store from its manager - =========================================================================*/ - internal void Dispose() - { - m_Manager.DeleteLocalDataStore(this); - } - - /*========================================================================= - ** Retrieves the value from the specified slot. - =========================================================================*/ - public Object GetData(LocalDataStoreSlot slot) - { - // Validate the slot. - m_Manager.ValidateSlot(slot); - - // Cache the slot index to avoid synchronization issues. - int slotIdx = slot.Slot; - - if (slotIdx >= 0) - { - // Delay expansion of m_DataTable if we can - if (slotIdx >= m_DataTable.Length) - return null; - - // Retrieve the data from the given slot. - LocalDataStoreElement element = m_DataTable[slotIdx]; - - //Initially we prepopulate the elements to be null. - if (element == null) - return null; - - // Check that the element is owned by this slot by comparing cookies. - // This is necesary to avoid resurection race conditions. - if (element.Cookie == slot.Cookie) - return element.Value; - - // Fall thru and throw exception - } - - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); - } - - /*========================================================================= - ** Sets the data in the specified slot. - =========================================================================*/ - public void SetData(LocalDataStoreSlot slot, Object data) - { - // Validate the slot. - m_Manager.ValidateSlot(slot); - - // Cache the slot index to avoid synchronization issues. - int slotIdx = slot.Slot; - - if (slotIdx >= 0) - { - LocalDataStoreElement element = (slotIdx < m_DataTable.Length) ? m_DataTable[slotIdx] : null; - if (element == null) - { - element = PopulateElement(slot); - } - - // Check that the element is owned by this slot by comparing cookies. - // This is necesary to avoid resurection race conditions. - if (element.Cookie == slot.Cookie) - { - // Set the data on the given slot. - element.Value = data; - return; - } - - // Fall thru and throw exception - } - - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); - } - - /*========================================================================= - ** This method does clears the unused slot. - * Assumes lock on m_Manager is taken - =========================================================================*/ - internal void FreeData(int slot, long cookie) - { - // We try to delay allocate the dataTable (in cases like the manager clearing a - // just-freed slot in all stores - if (slot >= m_DataTable.Length) - return; - - LocalDataStoreElement element = m_DataTable[slot]; - if (element != null && element.Cookie == cookie) - m_DataTable[slot] = null; - } - - /*========================================================================= - ** Method used to expand the capacity of the local data store. - =========================================================================*/ - private LocalDataStoreElement PopulateElement(LocalDataStoreSlot slot) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try { - Monitor.Enter(m_Manager, ref tookLock); - - // Make sure that the slot was not freed in the meantime - int slotIdx = slot.Slot; - if (slotIdx < 0) - throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_SlotHasBeenFreed")); - - if (slotIdx >= m_DataTable.Length) - { - int capacity = m_Manager.GetSlotTableLength(); - - // Validate that the specified capacity is larger than the current one. - Debug.Assert(capacity >= m_DataTable.Length, "LocalDataStore corrupted: capacity >= m_DataTable.Length"); - - // Allocate the new data table. - LocalDataStoreElement[] NewDataTable = new LocalDataStoreElement[capacity]; - - // Copy all the objects into the new table. - Array.Copy(m_DataTable, NewDataTable, m_DataTable.Length); - - // Save the new table. - m_DataTable = NewDataTable; - } - - // Validate that there is enough space in the local data store now - Debug.Assert(slotIdx < m_DataTable.Length, "LocalDataStore corrupted: slotIdx < m_DataTable.Length"); - - if (m_DataTable[slotIdx] == null) - m_DataTable[slotIdx] = new LocalDataStoreElement(slot.Cookie); - - return m_DataTable[slotIdx]; - } - finally { - if (tookLock) - Monitor.Exit(m_Manager); - } - } - } -} diff --git a/src/mscorlib/src/System/_LocalDataStoreMgr.cs b/src/mscorlib/src/System/_LocalDataStoreMgr.cs deleted file mode 100644 index 8f60d6f754..0000000000 --- a/src/mscorlib/src/System/_LocalDataStoreMgr.cs +++ /dev/null @@ -1,332 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -/*============================================================================= -** -** -** -** Purpose: Class that manages stores of local data. This class is used in -** cooperation with the LocalDataStore class. -** -** -=============================================================================*/ -namespace System { - - using System; - using System.Collections.Generic; - using System.Threading; - using System.Runtime.CompilerServices; - using System.Diagnostics.Contracts; - - // This class is an encapsulation of a slot so that it is managed in a secure fashion. - // It is constructed by the LocalDataStoreManager, holds the slot and the manager - // and cleans up when it is finalized. - // This class will not be marked serializable -[System.Runtime.InteropServices.ComVisible(true)] - public sealed class LocalDataStoreSlot - { - private LocalDataStoreMgr m_mgr; - private int m_slot; - private long m_cookie; - - // Construct the object to encapsulate the slot. - internal LocalDataStoreSlot(LocalDataStoreMgr mgr, int slot, long cookie) - { - m_mgr = mgr; - m_slot = slot; - m_cookie = cookie; - } - - // Accessors for the two fields of this class. - internal LocalDataStoreMgr Manager - { - get - { - return m_mgr; - } - } - internal int Slot - { - get - { - return m_slot; - } - } - internal long Cookie - { - get - { - return m_cookie; - } - } - - // Release the slot reserved by this object when this object goes away. - ~LocalDataStoreSlot() - { - LocalDataStoreMgr mgr = m_mgr; - if (mgr == null) - return; - - int slot = m_slot; - - // Mark the slot as free. - m_slot = -1; - - mgr.FreeDataSlot(slot, m_cookie); - } - } - - // This class will not be marked serializable - sealed internal class LocalDataStoreMgr - { - private const int InitialSlotTableSize = 64; - private const int SlotTableDoubleThreshold = 512; - private const int LargeSlotTableSizeIncrease = 128; - - /*========================================================================= - ** Create a data store to be managed by this manager and add it to the - ** list. The initial size of the new store matches the number of slots - ** allocated in this manager. - =========================================================================*/ - public LocalDataStoreHolder CreateLocalDataStore() - { - // Create a new local data store. - LocalDataStore store = new LocalDataStore(this, m_SlotInfoTable.Length); - LocalDataStoreHolder holder = new LocalDataStoreHolder(store); - - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Add the store to the array list and return it. - m_ManagedLocalDataStores.Add(store); - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - return holder; - } - - /*========================================================================= - * Remove the specified store from the list of managed stores.. - =========================================================================*/ - public void DeleteLocalDataStore(LocalDataStore store) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Remove the store to the array list and return it. - m_ManagedLocalDataStores.Remove(store); - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Allocates a data slot by finding an available index and wrapping it - ** an object to prevent clients from manipulating it directly, allowing us - ** to make assumptions its integrity. - =========================================================================*/ - public LocalDataStoreSlot AllocateDataSlot() - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - LocalDataStoreSlot slot; - - int slotTableSize = m_SlotInfoTable.Length; - - // In case FreeDataSlot has moved the pointer back, the next slot may not be available. - // Find the first actually available slot. - int availableSlot = m_FirstAvailableSlot; - while (availableSlot < slotTableSize) - { - if (!m_SlotInfoTable[availableSlot]) - break; - availableSlot++; - } - - // Check if there are any slots left. - if (availableSlot >= slotTableSize) - { - // The table is full so we need to increase its size. - int newSlotTableSize; - if (slotTableSize < SlotTableDoubleThreshold) - { - // The table is still relatively small so double it. - newSlotTableSize = slotTableSize * 2; - } - else - { - // The table is relatively large so simply increase its size by a given amount. - newSlotTableSize = slotTableSize + LargeSlotTableSizeIncrease; - } - - // Allocate the new slot info table. - bool[] newSlotInfoTable = new bool[newSlotTableSize]; - - // Copy the old array into the new one. - Array.Copy(m_SlotInfoTable, newSlotInfoTable, slotTableSize); - m_SlotInfoTable = newSlotInfoTable; - } - - // availableSlot is the index of the empty slot. - m_SlotInfoTable[availableSlot] = true; - - // We do not need to worry about overflowing m_CookieGenerator. It would take centuries - // of intensive slot allocations on current machines to get the 2^64 counter to overflow. - // We will perform the increment with overflow check just to play it on the safe side. - slot = new LocalDataStoreSlot(this, availableSlot, checked(m_CookieGenerator++)); - - // Save the new "first available slot".hint - m_FirstAvailableSlot = availableSlot + 1; - - // Return the selected slot - return slot; - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Allocate a slot and associate a name with it. - =========================================================================*/ - public LocalDataStoreSlot AllocateNamedDataSlot(String name) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Allocate a normal data slot. - LocalDataStoreSlot slot = AllocateDataSlot(); - - // Insert the association between the name and the data slot number - // in the hash table. - m_KeyToSlotMap.Add(name, slot); - return slot; - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Retrieve the slot associated with a name, allocating it if no such - ** association has been defined. - =========================================================================*/ - public LocalDataStoreSlot GetNamedDataSlot(String name) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Lookup in the hashtable to try find a slot for the name. - LocalDataStoreSlot slot = m_KeyToSlotMap.GetValueOrDefault(name); - - // If the name is not yet in the hashtable then add it. - if (null == slot) - return AllocateNamedDataSlot(name); - - // The name was in the hashtable so return the associated slot. - return slot; - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Eliminate the association of a name with a slot. The actual slot will - ** be reclaimed when the finalizer for the slot object runs. - =========================================================================*/ - public void FreeNamedDataSlot(String name) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Remove the name slot association from the hashtable. - m_KeyToSlotMap.Remove(name); - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Free's a previously allocated data slot on ALL the managed data stores. - =========================================================================*/ - internal void FreeDataSlot(int slot, long cookie) - { - bool tookLock = false; - RuntimeHelpers.PrepareConstrainedRegions(); - try - { - Monitor.Enter(this, ref tookLock); - // Go thru all the managed stores and set the data on the specified slot to 0. - for (int i = 0; i < m_ManagedLocalDataStores.Count; i++) - { - ((LocalDataStore)m_ManagedLocalDataStores[i]).FreeData(slot, cookie); - } - - // Mark the slot as being no longer occupied. - m_SlotInfoTable[slot] = false; - if (slot < m_FirstAvailableSlot) - m_FirstAvailableSlot = slot; - } - finally - { - if (tookLock) - Monitor.Exit(this); - } - } - - /*========================================================================= - ** Check that this is a valid slot for this store - =========================================================================*/ - public void ValidateSlot(LocalDataStoreSlot slot) - { - // Make sure the slot was allocated for this store. - if (slot == null || slot.Manager != this) - throw new ArgumentException(Environment.GetResourceString("Argument_ALSInvalidSlot")); - Contract.EndContractBlock(); - } - - /*========================================================================= - ** Return the number of allocated slots in this manager. - =========================================================================*/ - internal int GetSlotTableLength() - { - return m_SlotInfoTable.Length; - } - - private bool[] m_SlotInfoTable = new bool[InitialSlotTableSize]; - private int m_FirstAvailableSlot; - private List m_ManagedLocalDataStores = new List(); - private Dictionary m_KeyToSlotMap = new Dictionary(); - private long m_CookieGenerator; - } -} -- cgit v1.2.3