ntdll: Allocate TEBs out of a larger memory block.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
5dcb9ddff7
commit
dee934c0ff
|
@ -93,7 +93,6 @@ extern void debug_init(void) DECLSPEC_HIDDEN;
|
||||||
extern TEB *thread_init(void) DECLSPEC_HIDDEN;
|
extern TEB *thread_init(void) DECLSPEC_HIDDEN;
|
||||||
extern void actctx_init(void) DECLSPEC_HIDDEN;
|
extern void actctx_init(void) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
extern void virtual_init(void) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_init_threading(void) DECLSPEC_HIDDEN;
|
|
||||||
extern void fill_cpu_info(void) DECLSPEC_HIDDEN;
|
extern void fill_cpu_info(void) DECLSPEC_HIDDEN;
|
||||||
extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
|
extern void heap_set_debug_flags( HANDLE handle ) DECLSPEC_HIDDEN;
|
||||||
extern void init_unix_codepage(void) DECLSPEC_HIDDEN;
|
extern void init_unix_codepage(void) DECLSPEC_HIDDEN;
|
||||||
|
@ -200,6 +199,7 @@ extern NTSTATUS virtual_map_section( HANDLE handle, PVOID *addr_ptr, unsigned sh
|
||||||
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
ULONG protect, pe_image_info_t *image_info ) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
extern void virtual_get_system_info( SYSTEM_BASIC_INFORMATION *info ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
|
extern NTSTATUS virtual_create_builtin_view( void *base ) DECLSPEC_HIDDEN;
|
||||||
|
extern TEB * virtual_alloc_first_teb(void) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS virtual_alloc_teb( TEB **teb ) DECLSPEC_HIDDEN;
|
extern NTSTATUS virtual_alloc_teb( TEB **teb ) DECLSPEC_HIDDEN;
|
||||||
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
|
extern void virtual_free_teb( TEB *teb ) DECLSPEC_HIDDEN;
|
||||||
extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size,
|
extern NTSTATUS virtual_alloc_thread_stack( INITIAL_TEB *stack, SIZE_T reserve_size,
|
||||||
|
|
|
@ -246,13 +246,10 @@ TEB *thread_init(void)
|
||||||
user_shared_data = addr;
|
user_shared_data = addr;
|
||||||
memcpy( user_shared_data->NtSystemRoot, default_windirW, sizeof(default_windirW) );
|
memcpy( user_shared_data->NtSystemRoot, default_windirW, sizeof(default_windirW) );
|
||||||
|
|
||||||
/* allocate and initialize the PEB */
|
/* allocate and initialize the PEB and initial TEB */
|
||||||
|
|
||||||
addr = NULL;
|
|
||||||
size = sizeof(*peb);
|
|
||||||
virtual_alloc_aligned( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN, PAGE_READWRITE, 1 );
|
|
||||||
peb = addr;
|
|
||||||
|
|
||||||
|
teb = virtual_alloc_first_teb();
|
||||||
|
peb = teb->Peb;
|
||||||
peb->FastPebLock = &peb_lock;
|
peb->FastPebLock = &peb_lock;
|
||||||
peb->TlsBitmap = &tls_bitmap;
|
peb->TlsBitmap = &tls_bitmap;
|
||||||
peb->TlsExpansionBitmap = &tls_expansion_bitmap;
|
peb->TlsExpansionBitmap = &tls_expansion_bitmap;
|
||||||
|
@ -282,21 +279,12 @@ TEB *thread_init(void)
|
||||||
*/
|
*/
|
||||||
peb->SessionId = 1;
|
peb->SessionId = 1;
|
||||||
|
|
||||||
/* allocate and initialize the initial TEB */
|
|
||||||
|
|
||||||
signal_init_threading();
|
|
||||||
virtual_alloc_teb( &teb );
|
|
||||||
teb->Peb = peb;
|
|
||||||
teb->Tib.StackBase = (void *)~0UL;
|
|
||||||
|
|
||||||
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
thread_data->request_fd = -1;
|
thread_data->request_fd = -1;
|
||||||
thread_data->reply_fd = -1;
|
thread_data->reply_fd = -1;
|
||||||
thread_data->wait_fd[0] = -1;
|
thread_data->wait_fd[0] = -1;
|
||||||
thread_data->wait_fd[1] = -1;
|
thread_data->wait_fd[1] = -1;
|
||||||
|
|
||||||
signal_init_thread( teb );
|
|
||||||
virtual_init_threading();
|
|
||||||
debug_init();
|
debug_init();
|
||||||
init_paths();
|
init_paths();
|
||||||
set_process_name( __wine_main_argc, __wine_main_argv );
|
set_process_name( __wine_main_argc, __wine_main_argv );
|
||||||
|
@ -517,7 +505,6 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
||||||
|
|
||||||
if ((status = virtual_alloc_teb( &teb ))) goto error;
|
if ((status = virtual_alloc_teb( &teb ))) goto error;
|
||||||
|
|
||||||
teb->Peb = NtCurrentTeb()->Peb;
|
|
||||||
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
teb->ClientId.UniqueProcess = ULongToHandle(GetCurrentProcessId());
|
||||||
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
teb->ClientId.UniqueThread = ULongToHandle(tid);
|
||||||
|
|
||||||
|
|
|
@ -164,6 +164,11 @@ SIZE_T signal_stack_size = 0;
|
||||||
SIZE_T signal_stack_mask = 0;
|
SIZE_T signal_stack_mask = 0;
|
||||||
static SIZE_T signal_stack_align;
|
static SIZE_T signal_stack_align;
|
||||||
|
|
||||||
|
/* TEB allocation blocks */
|
||||||
|
static TEB *teb_block;
|
||||||
|
static TEB *next_free_teb;
|
||||||
|
static int teb_block_pos;
|
||||||
|
|
||||||
#define ROUND_ADDR(addr,mask) \
|
#define ROUND_ADDR(addr,mask) \
|
||||||
((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
((void *)((UINT_PTR)(addr) & ~(UINT_PTR)(mask)))
|
||||||
|
|
||||||
|
@ -2011,15 +2016,6 @@ void virtual_init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* virtual_init_threading
|
|
||||||
*/
|
|
||||||
void virtual_init_threading(void)
|
|
||||||
{
|
|
||||||
use_locks = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* virtual_get_system_info
|
* virtual_get_system_info
|
||||||
*/
|
*/
|
||||||
|
@ -2093,29 +2089,90 @@ NTSTATUS virtual_create_builtin_view( void *module )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* virtual_alloc_first_teb
|
||||||
|
*/
|
||||||
|
TEB *virtual_alloc_first_teb(void)
|
||||||
|
{
|
||||||
|
TEB *teb;
|
||||||
|
PEB *peb;
|
||||||
|
SIZE_T peb_size = page_size;
|
||||||
|
SIZE_T teb_size = signal_stack_mask + 1;
|
||||||
|
SIZE_T total = 32 * teb_size;
|
||||||
|
|
||||||
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb_block, 0, &total,
|
||||||
|
MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE );
|
||||||
|
teb_block_pos = 30;
|
||||||
|
teb = (TEB *)((char *)teb_block + 30 * teb_size);
|
||||||
|
peb = (PEB *)((char *)teb_block + 32 * teb_size - peb_size);
|
||||||
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb, 0, &teb_size, MEM_COMMIT, PAGE_READWRITE );
|
||||||
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&peb, 0, &peb_size, MEM_COMMIT, PAGE_READWRITE );
|
||||||
|
|
||||||
|
teb->Peb = peb;
|
||||||
|
teb->Tib.Self = &teb->Tib;
|
||||||
|
teb->Tib.ExceptionList = (void *)~0ul;
|
||||||
|
teb->Tib.StackBase = (void *)~0ul;
|
||||||
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
|
signal_init_threading();
|
||||||
|
signal_alloc_thread( teb );
|
||||||
|
signal_init_thread( teb );
|
||||||
|
use_locks = TRUE;
|
||||||
|
return teb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* virtual_alloc_teb
|
* virtual_alloc_teb
|
||||||
*/
|
*/
|
||||||
NTSTATUS virtual_alloc_teb( TEB **ret_teb )
|
NTSTATUS virtual_alloc_teb( TEB **ret_teb )
|
||||||
{
|
{
|
||||||
SIZE_T size = signal_stack_mask + 1;
|
sigset_t sigset;
|
||||||
void *addr = NULL;
|
TEB *teb = NULL;
|
||||||
TEB *teb;
|
NTSTATUS status = STATUS_SUCCESS;
|
||||||
NTSTATUS status;
|
SIZE_T teb_size = signal_stack_mask + 1;
|
||||||
|
|
||||||
if ((status = virtual_alloc_aligned( &addr, 0, &size, MEM_COMMIT | MEM_TOP_DOWN,
|
server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||||
PAGE_READWRITE, signal_stack_align )))
|
if (next_free_teb)
|
||||||
return status;
|
{
|
||||||
|
teb = next_free_teb;
|
||||||
|
next_free_teb = *(TEB **)teb;
|
||||||
|
memset( teb, 0, sizeof(*teb) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!teb_block_pos)
|
||||||
|
{
|
||||||
|
void *addr = NULL;
|
||||||
|
SIZE_T total = 32 * teb_size;
|
||||||
|
|
||||||
*ret_teb = teb = addr;
|
if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), &addr, 0, &total,
|
||||||
|
MEM_RESERVE, PAGE_READWRITE )))
|
||||||
|
{
|
||||||
|
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
teb_block = addr;
|
||||||
|
teb_block_pos = 32;
|
||||||
|
}
|
||||||
|
teb = (TEB *)((char *)teb_block + --teb_block_pos * teb_size);
|
||||||
|
NtAllocateVirtualMemory( NtCurrentProcess(), (void **)&teb, 0, &teb_size,
|
||||||
|
MEM_COMMIT, PAGE_READWRITE );
|
||||||
|
}
|
||||||
|
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||||
|
|
||||||
|
*ret_teb = teb;
|
||||||
|
teb->Peb = NtCurrentTeb()->Peb;
|
||||||
teb->Tib.Self = &teb->Tib;
|
teb->Tib.Self = &teb->Tib;
|
||||||
teb->Tib.ExceptionList = (void *)~0UL;
|
teb->Tib.ExceptionList = (void *)~0UL;
|
||||||
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
teb->StaticUnicodeString.Buffer = teb->StaticUnicodeBuffer;
|
||||||
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
teb->StaticUnicodeString.MaximumLength = sizeof(teb->StaticUnicodeBuffer);
|
||||||
if ((status = signal_alloc_thread( teb )))
|
if ((status = signal_alloc_thread( teb )))
|
||||||
{
|
{
|
||||||
size = 0;
|
server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
|
*(TEB **)teb = next_free_teb;
|
||||||
|
next_free_teb = teb;
|
||||||
|
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
@ -2128,6 +2185,7 @@ void virtual_free_teb( TEB *teb )
|
||||||
{
|
{
|
||||||
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
struct ntdll_thread_data *thread_data = (struct ntdll_thread_data *)&teb->GdiTebBatch;
|
||||||
SIZE_T size;
|
SIZE_T size;
|
||||||
|
sigset_t sigset;
|
||||||
|
|
||||||
signal_free_thread( teb );
|
signal_free_thread( teb );
|
||||||
if (teb->DeallocationStack)
|
if (teb->DeallocationStack)
|
||||||
|
@ -2140,8 +2198,11 @@ void virtual_free_teb( TEB *teb )
|
||||||
size = 0;
|
size = 0;
|
||||||
NtFreeVirtualMemory( GetCurrentProcess(), &thread_data->start_stack, &size, MEM_RELEASE );
|
NtFreeVirtualMemory( GetCurrentProcess(), &thread_data->start_stack, &size, MEM_RELEASE );
|
||||||
}
|
}
|
||||||
size = 0;
|
|
||||||
NtFreeVirtualMemory( NtCurrentProcess(), (void **)&teb, &size, MEM_RELEASE );
|
server_enter_uninterrupted_section( &csVirtual, &sigset );
|
||||||
|
*(TEB **)teb = next_free_teb;
|
||||||
|
next_free_teb = teb;
|
||||||
|
server_leave_uninterrupted_section( &csVirtual, &sigset );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue