public LocalDataStoreSlot AllocateDataSlot()
{
bool tookLock = false;
RuntimeHelpers.PrepareConstrainedRegions();
try {
Monitor.ReliableEnter(this, ref tookLock);
int i;
LocalDataStoreSlot slot;
// Retrieve the current size of the table.
int SlotTableSize = m_SlotInfoTable.Length;
// Check if there are any slots left.
if (m_FirstAvailableSlot < SlotTableSize)
{
// Save the first available slot.
slot = new LocalDataStoreSlot(this, m_FirstAvailableSlot);
m_SlotInfoTable[m_FirstAvailableSlot] = DataSlotOccupied;
// Find the next available slot.
for (i=m_FirstAvailableSlot+1; i < SlotTableSize; ++i)
if (0 == (m_SlotInfoTable[i] & DataSlotOccupied))
break;
// Save the new "first available slot".
m_FirstAvailableSlot = i;
// Return the slot index.
return slot;
}
// 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.
byte[] NewSlotInfoTable = new byte[NewSlotTableSize];
// Copy the old array into the new one.
Array.Copy(m_SlotInfoTable, NewSlotInfoTable, SlotTableSize);
m_SlotInfoTable = NewSlotInfoTable;
// SlotTableSize is the index of the first empty slot in the expanded table.
slot = new LocalDataStoreSlot(this, SlotTableSize);
m_SlotInfoTable[SlotTableSize] = DataSlotOccupied;
m_FirstAvailableSlot = SlotTableSize + 1;
// Return the selected slot
return slot;
}
finally {
if (tookLock)
Monitor.Exit(this);
}
}