mirror of
https://github.com/reactos/reactos.git
synced 2025-06-30 20:11:22 +00:00
- Allow TLS usage for 1088 TLS slots, fixes part of Bug 191. Patch by Filip Navara (navaraf@reactos.com)
svn path=/trunk/; revision=19959
This commit is contained in:
parent
bc31c23df9
commit
ba70f8d6f5
1 changed files with 125 additions and 51 deletions
|
@ -17,6 +17,7 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "../include/debug.h"
|
#include "../include/debug.h"
|
||||||
|
|
||||||
|
#define TLS_EXPANSION_SLOTS (8 * sizeof(((PPEB)NULL)->TlsExpansionBitmapBits))
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
@ -29,18 +30,49 @@ TlsAlloc(VOID)
|
||||||
ULONG Index;
|
ULONG Index;
|
||||||
|
|
||||||
RtlAcquirePebLock();
|
RtlAcquirePebLock();
|
||||||
|
|
||||||
|
/* Try to get regular TEB slot. */
|
||||||
Index = RtlFindClearBitsAndSet(NtCurrentPeb()->TlsBitmap, 1, 0);
|
Index = RtlFindClearBitsAndSet(NtCurrentPeb()->TlsBitmap, 1, 0);
|
||||||
if (Index == (ULONG)-1)
|
if (Index == ~0)
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus(STATUS_NO_MEMORY);
|
/* If it fails, try to find expansion TEB slot. */
|
||||||
|
Index = RtlFindClearBitsAndSet(NtCurrentPeb()->TlsExpansionBitmap, 1, 0);
|
||||||
|
if (Index != ~0)
|
||||||
|
{
|
||||||
|
if (NtCurrentTeb()->TlsExpansionSlots == NULL)
|
||||||
|
{
|
||||||
|
NtCurrentTeb()->TlsExpansionSlots = HeapAlloc(
|
||||||
|
GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
TLS_EXPANSION_SLOTS * sizeof(PVOID));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NtCurrentTeb()->TlsExpansionSlots == NULL)
|
||||||
|
{
|
||||||
|
RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap, Index, 1);
|
||||||
|
Index = ~0;
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Clear the value. */
|
||||||
|
NtCurrentTeb()->TlsExpansionSlots[Index] = 0;
|
||||||
|
Index += TLS_MINIMUM_AVAILABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear the value. */
|
||||||
NtCurrentTeb()->TlsSlots[Index] = 0;
|
NtCurrentTeb()->TlsSlots[Index] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlReleasePebLock();
|
RtlReleasePebLock();
|
||||||
|
|
||||||
return(Index);
|
return Index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,32 +80,47 @@ TlsAlloc(VOID)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
TlsFree(DWORD dwTlsIndex)
|
TlsFree(DWORD Index)
|
||||||
{
|
{
|
||||||
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
|
BOOL BitSet;
|
||||||
|
|
||||||
|
if (Index >= TLS_EXPANSION_SLOTS + TLS_MINIMUM_AVAILABLE)
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlAcquirePebLock();
|
RtlAcquirePebLock();
|
||||||
if (RtlAreBitsSet(NtCurrentPeb()->TlsBitmap, dwTlsIndex, 1))
|
|
||||||
|
if (Index >= TLS_MINIMUM_AVAILABLE)
|
||||||
{
|
{
|
||||||
/*
|
BitSet = RtlAreBitsSet(NtCurrentPeb()->TlsExpansionBitmap,
|
||||||
* clear the tls cells (slots) in all threads
|
Index - TLS_MINIMUM_AVAILABLE, 1);
|
||||||
* of the current process
|
if (BitSet)
|
||||||
*/
|
RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap,
|
||||||
NtSetInformationThread(NtCurrentThread(),
|
Index - TLS_MINIMUM_AVAILABLE, 1);
|
||||||
ThreadZeroTlsCell,
|
|
||||||
&dwTlsIndex,
|
|
||||||
sizeof(DWORD));
|
|
||||||
RtlClearBits(NtCurrentPeb()->TlsBitmap,
|
|
||||||
dwTlsIndex,
|
|
||||||
1);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BitSet = RtlAreBitsSet(NtCurrentPeb()->TlsBitmap, Index, 1);
|
||||||
|
if (BitSet)
|
||||||
|
RtlClearBits(NtCurrentPeb()->TlsBitmap, Index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BitSet)
|
||||||
|
{
|
||||||
|
/* Clear the TLS cells (slots) in all threads of the current process. */
|
||||||
|
NtSetInformationThread(NtCurrentThread(), ThreadZeroTlsCell,
|
||||||
|
&Index, sizeof(DWORD));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
}
|
||||||
|
|
||||||
RtlReleasePebLock();
|
RtlReleasePebLock();
|
||||||
|
|
||||||
return(TRUE);
|
return BitSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -81,22 +128,27 @@ TlsFree(DWORD dwTlsIndex)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
LPVOID STDCALL
|
LPVOID STDCALL
|
||||||
TlsGetValue(DWORD dwTlsIndex)
|
TlsGetValue(DWORD Index)
|
||||||
{
|
{
|
||||||
LPVOID Value;
|
if (Index >= TLS_EXPANSION_SLOTS + TLS_MINIMUM_AVAILABLE)
|
||||||
|
|
||||||
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
|
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
||||||
return(NULL);
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value = NtCurrentTeb()->TlsSlots[dwTlsIndex];
|
|
||||||
if (Value == 0)
|
|
||||||
{
|
|
||||||
SetLastError(NO_ERROR);
|
SetLastError(NO_ERROR);
|
||||||
|
|
||||||
|
if (Index >= TLS_MINIMUM_AVAILABLE)
|
||||||
|
{
|
||||||
|
/* The expansion slots are allocated on demand, so check for it. */
|
||||||
|
if (NtCurrentTeb()->TlsExpansionSlots == NULL)
|
||||||
|
return NULL;
|
||||||
|
return NtCurrentTeb()->TlsExpansionSlots[Index - TLS_MINIMUM_AVAILABLE];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return NtCurrentTeb()->TlsSlots[Index];
|
||||||
}
|
}
|
||||||
return Value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -104,15 +156,37 @@ TlsGetValue(DWORD dwTlsIndex)
|
||||||
* @implemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
BOOL STDCALL
|
BOOL STDCALL
|
||||||
TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
TlsSetValue(DWORD Index, LPVOID Value)
|
||||||
{
|
{
|
||||||
if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
|
if (Index >= TLS_EXPANSION_SLOTS + TLS_MINIMUM_AVAILABLE)
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
|
||||||
return(FALSE);
|
return FALSE;
|
||||||
}
|
}
|
||||||
NtCurrentTeb()->TlsSlots[dwTlsIndex] = lpTlsValue;
|
|
||||||
return(TRUE);
|
if (Index >= TLS_MINIMUM_AVAILABLE)
|
||||||
|
{
|
||||||
|
if (NtCurrentTeb()->TlsExpansionSlots == NULL)
|
||||||
|
{
|
||||||
|
NtCurrentTeb()->TlsExpansionSlots = HeapAlloc(
|
||||||
|
GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||||
|
TLS_EXPANSION_SLOTS * sizeof(PVOID));
|
||||||
|
|
||||||
|
if (NtCurrentTeb()->TlsExpansionSlots == NULL)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NtCurrentTeb()->TlsExpansionSlots[Index - TLS_MINIMUM_AVAILABLE] = Value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NtCurrentTeb()->TlsSlots[Index] = Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue