Store the debug info structure on the thread stack.
Moved thread initialization code from sysdeps.c to thread.c to avoid an indirection.
This commit is contained in:
parent
6677ac4bc0
commit
aee989a7ed
|
@ -47,16 +47,6 @@ WINE_DECLARE_DEBUG_CHANNEL(tid);
|
|||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
|
||||
struct debug_info
|
||||
{
|
||||
char *str_pos; /* current position in strings buffer */
|
||||
char *out_pos; /* current position in output buffer */
|
||||
char strings[1024]; /* buffer for temporary strings */
|
||||
char output[1024]; /* current output line */
|
||||
};
|
||||
|
||||
static struct debug_info initial_thread_info; /* debug info for initial thread */
|
||||
|
||||
/* filter for page-fault exceptions */
|
||||
static WINE_EXCEPTION_FILTER(page_fault)
|
||||
{
|
||||
|
@ -68,15 +58,7 @@ static WINE_EXCEPTION_FILTER(page_fault)
|
|||
/* get the debug info pointer for the current thread */
|
||||
static inline struct debug_info *get_info(void)
|
||||
{
|
||||
struct debug_info *info = NtCurrentTeb()->debug_info;
|
||||
|
||||
if (!info) NtCurrentTeb()->debug_info = info = &initial_thread_info;
|
||||
if (!info->str_pos)
|
||||
{
|
||||
info->str_pos = info->strings;
|
||||
info->out_pos = info->output;
|
||||
}
|
||||
return info;
|
||||
return NtCurrentTeb()->debug_info;
|
||||
}
|
||||
|
||||
/* allocate some tmp space for a string */
|
||||
|
|
|
@ -137,28 +137,13 @@ static void cleanup_thread( void *ptr )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SYSDEPS_StartThread
|
||||
*
|
||||
* Startup routine for a new thread.
|
||||
*/
|
||||
static void SYSDEPS_StartThread( TEB *teb )
|
||||
{
|
||||
SYSDEPS_SetCurThread( teb );
|
||||
SIGNAL_Init();
|
||||
CLIENT_InitThread();
|
||||
teb->startup();
|
||||
SYSDEPS_ExitThread(0); /* should never get here */
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SYSDEPS_SpawnThread
|
||||
*
|
||||
* Start running a new thread.
|
||||
* Return -1 on error, 0 if OK.
|
||||
*/
|
||||
int SYSDEPS_SpawnThread( TEB *teb )
|
||||
int SYSDEPS_SpawnThread( void (*func)(TEB *), TEB *teb )
|
||||
{
|
||||
#ifdef HAVE_NPTL
|
||||
pthread_t id;
|
||||
|
@ -166,10 +151,10 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
|||
|
||||
pthread_attr_init( &attr );
|
||||
pthread_attr_setstack( &attr, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
||||
if (pthread_create( &id, &attr, (void * (*)(void *))SYSDEPS_StartThread, teb )) return -1;
|
||||
if (pthread_create( &id, &attr, (void * (*)(void *))func, teb )) return -1;
|
||||
return 0;
|
||||
#elif defined(HAVE_CLONE)
|
||||
if (clone( (int (*)(void *))SYSDEPS_StartThread, teb->stack_top,
|
||||
if (clone( (int (*)(void *))func, teb->stack_top,
|
||||
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, teb ) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
|
@ -177,7 +162,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
|||
void **sp = (void **)teb->stack_top;
|
||||
*--sp = teb;
|
||||
*--sp = 0;
|
||||
*--sp = SYSDEPS_StartThread;
|
||||
*--sp = func;
|
||||
__asm__ __volatile__(
|
||||
"pushl %2;\n\t" /* flags */
|
||||
"pushl $0;\n\t" /* 0 ? */
|
||||
|
@ -194,7 +179,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
|||
return 0;
|
||||
#elif defined(HAVE__LWP_CREATE)
|
||||
ucontext_t context;
|
||||
_lwp_makecontext( &context, (void(*)(void *))SYSDEPS_StartThread, teb,
|
||||
_lwp_makecontext( &context, (void(*)(void *))func, teb,
|
||||
NULL, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
||||
if ( _lwp_create( &context, 0, NULL ) )
|
||||
return -1;
|
||||
|
|
|
@ -30,6 +30,14 @@ struct tagSYSLEVEL;
|
|||
struct server_buffer_info;
|
||||
struct fiber_data;
|
||||
|
||||
struct debug_info
|
||||
{
|
||||
char *str_pos; /* current position in strings buffer */
|
||||
char *out_pos; /* current position in output buffer */
|
||||
char strings[1024]; /* buffer for temporary strings */
|
||||
char output[1024]; /* current output line */
|
||||
};
|
||||
|
||||
/* Thread exception block
|
||||
|
||||
flags in the comment:
|
||||
|
@ -70,7 +78,7 @@ typedef struct _TEB
|
|||
WORD emu_sel; /* 1-n 3e 80387 emulator selector */
|
||||
DWORD unknown1; /* --n 40 */
|
||||
DWORD unknown2; /* --n 44 */
|
||||
void (*startup)(void); /* --3 48 Thread startup routine */
|
||||
DWORD unknown3; /* --n 48 */
|
||||
int thread_errno; /* --3 4c Per-thread errno (was: ring0_thread) */
|
||||
int thread_h_errno; /* --3 50 Per-thread h_errno (was: ptr to tdbx structure) */
|
||||
void *signal_stack; /* --3 54 Signal stack (was: stack_base) */
|
||||
|
@ -109,7 +117,7 @@ typedef struct _TEB
|
|||
int request_fd; /* --3 20c fd for sending server requests */
|
||||
int reply_fd; /* --3 210 fd for receiving server replies */
|
||||
int wait_fd[2]; /* --3 214 fd for sleeping server requests */
|
||||
void *debug_info; /* --3 21c Info for debugstr functions */
|
||||
struct debug_info *debug_info; /* --3 21c Info for debugstr functions */
|
||||
void *pthread_data; /* --3 220 Data for pthread emulation */
|
||||
struct async_private *pending_list; /* --3 224 list of pending async operations */
|
||||
void *driver_data; /* --3 228 Graphics driver private data */
|
||||
|
@ -144,7 +152,7 @@ extern TEB *THREAD_InitStack( TEB *teb, DWORD stack_size );
|
|||
extern TEB *THREAD_IdToTEB( DWORD id );
|
||||
|
||||
/* scheduler/sysdeps.c */
|
||||
extern int SYSDEPS_SpawnThread( TEB *teb );
|
||||
extern int SYSDEPS_SpawnThread( void (*func)(TEB *), TEB *teb );
|
||||
extern void SYSDEPS_SetCurThread( TEB *teb );
|
||||
extern int SYSDEPS_GetUnixTid(void);
|
||||
extern void DECLSPEC_NORETURN SYSDEPS_ExitThread( int status );
|
||||
|
|
|
@ -162,25 +162,23 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
|
|||
* 1 page PAGE_GUARD guard page
|
||||
* stack_size normal stack
|
||||
* 1 page TEB (except for initial thread)
|
||||
* 1 page debug info (except for initial thread)
|
||||
*/
|
||||
|
||||
stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
|
||||
total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size;
|
||||
if (!teb) total_size += 2 * page_size;
|
||||
if (!teb) total_size += page_size;
|
||||
|
||||
if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
|
||||
return NULL;
|
||||
|
||||
if (!teb)
|
||||
{
|
||||
teb = (TEB *)((char *)base + total_size - 2 * page_size);
|
||||
teb = (TEB *)((char *)base + total_size - page_size);
|
||||
if (!THREAD_InitTEB( teb ))
|
||||
{
|
||||
VirtualFree( base, 0, MEM_RELEASE );
|
||||
return NULL;
|
||||
}
|
||||
teb->debug_info = (char *)teb + page_size;
|
||||
}
|
||||
|
||||
teb->stack_low = base;
|
||||
|
@ -207,10 +205,15 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
|
|||
*/
|
||||
void THREAD_Init(void)
|
||||
{
|
||||
static struct debug_info info; /* debug info for initial thread */
|
||||
|
||||
if (!initial_teb.self) /* do it only once */
|
||||
{
|
||||
THREAD_InitTEB( &initial_teb );
|
||||
assert( initial_teb.teb_sel );
|
||||
info.str_pos = info.strings;
|
||||
info.out_pos = info.output;
|
||||
initial_teb.debug_info = &info;
|
||||
initial_teb.Peb = (PEB *)¤t_process; /* FIXME */
|
||||
SYSDEPS_SetCurThread( &initial_teb );
|
||||
}
|
||||
|
@ -224,9 +227,18 @@ DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); }
|
|||
*
|
||||
* Start execution of a newly created thread. Does not return.
|
||||
*/
|
||||
static void THREAD_Start(void)
|
||||
static void THREAD_Start( TEB *teb )
|
||||
{
|
||||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)NtCurrentTeb()->entry_point;
|
||||
LPTHREAD_START_ROUTINE func = (LPTHREAD_START_ROUTINE)teb->entry_point;
|
||||
struct debug_info info;
|
||||
|
||||
info.str_pos = info.strings;
|
||||
info.out_pos = info.output;
|
||||
teb->debug_info = &info;
|
||||
|
||||
SYSDEPS_SetCurThread( teb );
|
||||
SIGNAL_Init();
|
||||
CLIENT_InitThread();
|
||||
|
||||
if (TRACE_ON(relay))
|
||||
DPRINTF("%04lx:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
|
||||
|
@ -289,11 +301,10 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, SIZE_T stack,
|
|||
teb->request_fd = request_pipe[1];
|
||||
teb->entry_point = start;
|
||||
teb->entry_arg = param;
|
||||
teb->startup = THREAD_Start;
|
||||
teb->htask16 = GetCurrentTask();
|
||||
|
||||
if (id) *id = tid;
|
||||
if (SYSDEPS_SpawnThread( teb ) == -1)
|
||||
if (SYSDEPS_SpawnThread( THREAD_Start, teb ) == -1)
|
||||
{
|
||||
CloseHandle( handle );
|
||||
close( request_pipe[1] );
|
||||
|
|
Loading…
Reference in New Issue