Added support for the TLS expansion slots, adding an extra 1024
entries.
This commit is contained in:
parent
2b3aa7c5be
commit
f1020bc6e0
|
@ -2192,11 +2192,32 @@ UINT WINAPI SetErrorMode( UINT mode )
|
|||
DWORD WINAPI TlsAlloc( void )
|
||||
{
|
||||
DWORD index;
|
||||
PEB * const peb = NtCurrentTeb()->Peb;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
index = RtlFindClearBitsAndSet( NtCurrentTeb()->Peb->TlsBitmap, 1, 0 );
|
||||
index = RtlFindClearBitsAndSet( peb->TlsBitmap, 1, 0 );
|
||||
if (index != ~0UL) NtCurrentTeb()->TlsSlots[index] = 0; /* clear the value */
|
||||
else SetLastError( ERROR_NO_MORE_ITEMS );
|
||||
else
|
||||
{
|
||||
index = RtlFindClearBitsAndSet( peb->TlsExpansionBitmap, 1, 0 );
|
||||
if (index != ~0UL)
|
||||
{
|
||||
if (!NtCurrentTeb()->TlsExpansionSlots &&
|
||||
!(NtCurrentTeb()->TlsExpansionSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
8 * sizeof(peb->TlsExpansionBitmapBits) * sizeof(void*) )))
|
||||
{
|
||||
RtlClearBits( peb->TlsExpansionBitmap, index, 1 );
|
||||
index = ~0UL;
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
}
|
||||
else
|
||||
{
|
||||
NtCurrentTeb()->TlsExpansionSlots[index] = 0; /* clear the value */
|
||||
index += TLS_MINIMUM_AVAILABLE;
|
||||
}
|
||||
}
|
||||
else SetLastError( ERROR_NO_MORE_ITEMS );
|
||||
}
|
||||
RtlReleasePebLock();
|
||||
return index;
|
||||
}
|
||||
|
@ -2217,12 +2238,17 @@ BOOL WINAPI TlsFree(
|
|||
BOOL ret;
|
||||
|
||||
RtlAcquirePebLock();
|
||||
ret = RtlAreBitsSet( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
|
||||
if (ret)
|
||||
if (index >= TLS_MINIMUM_AVAILABLE)
|
||||
{
|
||||
RtlClearBits( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
|
||||
NtSetInformationThread( GetCurrentThread(), ThreadZeroTlsCell, &index, sizeof(index) );
|
||||
ret = RtlAreBitsSet( NtCurrentTeb()->Peb->TlsExpansionBitmap, index - TLS_MINIMUM_AVAILABLE, 1 );
|
||||
if (ret) RtlClearBits( NtCurrentTeb()->Peb->TlsExpansionBitmap, index - TLS_MINIMUM_AVAILABLE, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = RtlAreBitsSet( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
|
||||
if (ret) RtlClearBits( NtCurrentTeb()->Peb->TlsBitmap, index, 1 );
|
||||
}
|
||||
if (ret) NtSetInformationThread( GetCurrentThread(), ThreadZeroTlsCell, &index, sizeof(index) );
|
||||
else SetLastError( ERROR_INVALID_PARAMETER );
|
||||
RtlReleasePebLock();
|
||||
return TRUE;
|
||||
|
@ -2239,13 +2265,25 @@ BOOL WINAPI TlsFree(
|
|||
LPVOID WINAPI TlsGetValue(
|
||||
DWORD index) /* [in] TLS index to retrieve value for */
|
||||
{
|
||||
if (index >= NtCurrentTeb()->Peb->TlsBitmap->SizeOfBitMap)
|
||||
LPVOID ret;
|
||||
|
||||
if (index < TLS_MINIMUM_AVAILABLE)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
ret = NtCurrentTeb()->TlsSlots[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
index -= TLS_MINIMUM_AVAILABLE;
|
||||
if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return NULL;
|
||||
}
|
||||
if (!NtCurrentTeb()->TlsExpansionSlots) ret = NULL;
|
||||
else ret = NtCurrentTeb()->TlsExpansionSlots[index];
|
||||
}
|
||||
SetLastError( ERROR_SUCCESS );
|
||||
return NtCurrentTeb()->TlsSlots[index];
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2260,12 +2298,27 @@ BOOL WINAPI TlsSetValue(
|
|||
DWORD index, /* [in] TLS index to set value for */
|
||||
LPVOID value) /* [in] Value to be stored */
|
||||
{
|
||||
if (index >= NtCurrentTeb()->Peb->TlsBitmap->SizeOfBitMap)
|
||||
if (index < TLS_MINIMUM_AVAILABLE)
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
NtCurrentTeb()->TlsSlots[index] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
index -= TLS_MINIMUM_AVAILABLE;
|
||||
if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return FALSE;
|
||||
}
|
||||
if (!NtCurrentTeb()->TlsExpansionSlots &&
|
||||
!(NtCurrentTeb()->TlsExpansionSlots = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits) * sizeof(void*) )))
|
||||
{
|
||||
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
|
||||
return FALSE;
|
||||
}
|
||||
NtCurrentTeb()->TlsExpansionSlots[index] = value;
|
||||
}
|
||||
NtCurrentTeb()->TlsSlots[index] = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ static PEB peb;
|
|||
static PEB_LDR_DATA ldr;
|
||||
static RTL_USER_PROCESS_PARAMETERS params; /* default parameters if no parent */
|
||||
static RTL_BITMAP tls_bitmap;
|
||||
static RTL_BITMAP tls_expansion_bitmap;
|
||||
static LIST_ENTRY tls_links;
|
||||
|
||||
|
||||
|
@ -109,8 +110,11 @@ void thread_init(void)
|
|||
peb.NumberOfProcessors = 1;
|
||||
peb.ProcessParameters = ¶ms;
|
||||
peb.TlsBitmap = &tls_bitmap;
|
||||
peb.TlsExpansionBitmap = &tls_expansion_bitmap;
|
||||
peb.LdrData = &ldr;
|
||||
RtlInitializeBitMap( &tls_bitmap, peb.TlsBitmapBits, sizeof(peb.TlsBitmapBits) * 8 );
|
||||
RtlInitializeBitMap( &tls_expansion_bitmap, peb.TlsExpansionBitmapBits,
|
||||
sizeof(peb.TlsExpansionBitmapBits) * 8 );
|
||||
InitializeListHead( &ldr.InLoadOrderModuleList );
|
||||
InitializeListHead( &ldr.InMemoryOrderModuleList );
|
||||
InitializeListHead( &ldr.InInitializationOrderModuleList );
|
||||
|
@ -535,14 +539,29 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
|
||||
if (length != sizeof(DWORD)) return STATUS_INVALID_PARAMETER;
|
||||
index = *(const DWORD *)data;
|
||||
if (index >= 64) return STATUS_INVALID_PARAMETER;
|
||||
RtlAcquirePebLock();
|
||||
for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink)
|
||||
if (index < TLS_MINIMUM_AVAILABLE)
|
||||
{
|
||||
TEB *teb = CONTAINING_RECORD(entry, TEB, TlsLinks);
|
||||
teb->TlsSlots[index] = 0;
|
||||
RtlAcquirePebLock();
|
||||
for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink)
|
||||
{
|
||||
TEB *teb = CONTAINING_RECORD(entry, TEB, TlsLinks);
|
||||
teb->TlsSlots[index] = 0;
|
||||
}
|
||||
RtlReleasePebLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
index -= TLS_MINIMUM_AVAILABLE;
|
||||
if (index >= 8 * sizeof(NtCurrentTeb()->Peb->TlsExpansionBitmapBits))
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
RtlAcquirePebLock();
|
||||
for (entry = tls_links.Flink; entry != &tls_links; entry = entry->Flink)
|
||||
{
|
||||
TEB *teb = CONTAINING_RECORD(entry, TEB, TlsLinks);
|
||||
if (teb->TlsExpansionSlots) teb->TlsExpansionSlots[index] = 0;
|
||||
}
|
||||
RtlReleasePebLock();
|
||||
}
|
||||
RtlReleasePebLock();
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
FIXME( "ZeroTlsCell not supported on other threads\n" );
|
||||
|
|
|
@ -132,7 +132,7 @@ typedef struct _TEB
|
|||
DWORD pad9[24]; /* --n f20 */
|
||||
PVOID ReservedForOle; /* -2- f80 used by ole32 (IErrorInfo*) */
|
||||
PVOID pad10[4]; /* --n f84 */
|
||||
PVOID TlsExpansionSlots; /* -2- f94 */
|
||||
PVOID *TlsExpansionSlots; /* -2- f94 */
|
||||
} TEB;
|
||||
#endif /* WINE_TEB_DEFINED */
|
||||
|
||||
|
|
|
@ -1589,6 +1589,8 @@ extern struct _TEB * WINAPI NtCurrentTeb(void);
|
|||
#endif
|
||||
#define GetFiberData() (*(void **)GetCurrentFiber())
|
||||
|
||||
#define TLS_MINIMUM_AVAILABLE 64
|
||||
|
||||
/*
|
||||
* File formats definitions
|
||||
*/
|
||||
|
|
|
@ -197,7 +197,7 @@ typedef struct _PEB
|
|||
ULONG ImageProcessAffinityMask; /* c0 */
|
||||
ULONG GdiHandleBuffer[34]; /* c4 */
|
||||
ULONG PostProcessInitRoutine; /* 14c */
|
||||
ULONG TlsExpansionBitmap; /* 150 */
|
||||
PRTL_BITMAP TlsExpansionBitmap; /* 150 */
|
||||
ULONG TlsExpansionBitmapBits[32]; /* 154 */
|
||||
ULONG SessionId; /* 1d4 */
|
||||
} PEB, *PPEB;
|
||||
|
@ -235,7 +235,7 @@ typedef struct _TEB
|
|||
PVOID Reserved4[26]; /* f18 */
|
||||
PVOID ReservedForOle; /* f80 Windows 2000 only */
|
||||
PVOID Reserved5[4]; /* f84 */
|
||||
PVOID TlsExpansionSlots; /* f94 */
|
||||
PVOID *TlsExpansionSlots; /* f94 */
|
||||
} TEB, *PTEB;
|
||||
# endif /* WINE_TEB_DEFINED */
|
||||
#endif /* WINE_NO_TEB */
|
||||
|
|
Loading…
Reference in New Issue