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 */
|
/* filter for page-fault exceptions */
|
||||||
static WINE_EXCEPTION_FILTER(page_fault)
|
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 */
|
/* get the debug info pointer for the current thread */
|
||||||
static inline struct debug_info *get_info(void)
|
static inline struct debug_info *get_info(void)
|
||||||
{
|
{
|
||||||
struct debug_info *info = NtCurrentTeb()->debug_info;
|
return 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* allocate some tmp space for a string */
|
/* 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
|
* SYSDEPS_SpawnThread
|
||||||
*
|
*
|
||||||
* Start running a new thread.
|
* Start running a new thread.
|
||||||
* Return -1 on error, 0 if OK.
|
* Return -1 on error, 0 if OK.
|
||||||
*/
|
*/
|
||||||
int SYSDEPS_SpawnThread( TEB *teb )
|
int SYSDEPS_SpawnThread( void (*func)(TEB *), TEB *teb )
|
||||||
{
|
{
|
||||||
#ifdef HAVE_NPTL
|
#ifdef HAVE_NPTL
|
||||||
pthread_t id;
|
pthread_t id;
|
||||||
|
@ -166,10 +151,10 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
||||||
|
|
||||||
pthread_attr_init( &attr );
|
pthread_attr_init( &attr );
|
||||||
pthread_attr_setstack( &attr, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
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;
|
return 0;
|
||||||
#elif defined(HAVE_CLONE)
|
#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)
|
CLONE_VM | CLONE_FS | CLONE_FILES | SIGCHLD, teb ) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -177,7 +162,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
||||||
void **sp = (void **)teb->stack_top;
|
void **sp = (void **)teb->stack_top;
|
||||||
*--sp = teb;
|
*--sp = teb;
|
||||||
*--sp = 0;
|
*--sp = 0;
|
||||||
*--sp = SYSDEPS_StartThread;
|
*--sp = func;
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
"pushl %2;\n\t" /* flags */
|
"pushl %2;\n\t" /* flags */
|
||||||
"pushl $0;\n\t" /* 0 ? */
|
"pushl $0;\n\t" /* 0 ? */
|
||||||
|
@ -194,7 +179,7 @@ int SYSDEPS_SpawnThread( TEB *teb )
|
||||||
return 0;
|
return 0;
|
||||||
#elif defined(HAVE__LWP_CREATE)
|
#elif defined(HAVE__LWP_CREATE)
|
||||||
ucontext_t context;
|
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 );
|
NULL, teb->stack_base, (char *)teb->stack_top - (char *)teb->stack_base );
|
||||||
if ( _lwp_create( &context, 0, NULL ) )
|
if ( _lwp_create( &context, 0, NULL ) )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -30,6 +30,14 @@ struct tagSYSLEVEL;
|
||||||
struct server_buffer_info;
|
struct server_buffer_info;
|
||||||
struct fiber_data;
|
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
|
/* Thread exception block
|
||||||
|
|
||||||
flags in the comment:
|
flags in the comment:
|
||||||
|
@ -70,7 +78,7 @@ typedef struct _TEB
|
||||||
WORD emu_sel; /* 1-n 3e 80387 emulator selector */
|
WORD emu_sel; /* 1-n 3e 80387 emulator selector */
|
||||||
DWORD unknown1; /* --n 40 */
|
DWORD unknown1; /* --n 40 */
|
||||||
DWORD unknown2; /* --n 44 */
|
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_errno; /* --3 4c Per-thread errno (was: ring0_thread) */
|
||||||
int thread_h_errno; /* --3 50 Per-thread h_errno (was: ptr to tdbx structure) */
|
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) */
|
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 request_fd; /* --3 20c fd for sending server requests */
|
||||||
int reply_fd; /* --3 210 fd for receiving server replies */
|
int reply_fd; /* --3 210 fd for receiving server replies */
|
||||||
int wait_fd[2]; /* --3 214 fd for sleeping server requests */
|
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 */
|
void *pthread_data; /* --3 220 Data for pthread emulation */
|
||||||
struct async_private *pending_list; /* --3 224 list of pending async operations */
|
struct async_private *pending_list; /* --3 224 list of pending async operations */
|
||||||
void *driver_data; /* --3 228 Graphics driver private data */
|
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 );
|
extern TEB *THREAD_IdToTEB( DWORD id );
|
||||||
|
|
||||||
/* scheduler/sysdeps.c */
|
/* 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 void SYSDEPS_SetCurThread( TEB *teb );
|
||||||
extern int SYSDEPS_GetUnixTid(void);
|
extern int SYSDEPS_GetUnixTid(void);
|
||||||
extern void DECLSPEC_NORETURN SYSDEPS_ExitThread( int status );
|
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
|
* 1 page PAGE_GUARD guard page
|
||||||
* stack_size normal stack
|
* stack_size normal stack
|
||||||
* 1 page TEB (except for initial thread)
|
* 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);
|
stack_size = (stack_size + (page_size - 1)) & ~(page_size - 1);
|
||||||
total_size = stack_size + SIGNAL_STACK_SIZE + 3 * page_size;
|
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 )))
|
if (!(base = VirtualAlloc( NULL, total_size, MEM_COMMIT, PAGE_EXECUTE_READWRITE )))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (!teb)
|
if (!teb)
|
||||||
{
|
{
|
||||||
teb = (TEB *)((char *)base + total_size - 2 * page_size);
|
teb = (TEB *)((char *)base + total_size - page_size);
|
||||||
if (!THREAD_InitTEB( teb ))
|
if (!THREAD_InitTEB( teb ))
|
||||||
{
|
{
|
||||||
VirtualFree( base, 0, MEM_RELEASE );
|
VirtualFree( base, 0, MEM_RELEASE );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
teb->debug_info = (char *)teb + page_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
teb->stack_low = base;
|
teb->stack_low = base;
|
||||||
|
@ -207,10 +205,15 @@ TEB *THREAD_InitStack( TEB *teb, DWORD stack_size )
|
||||||
*/
|
*/
|
||||||
void THREAD_Init(void)
|
void THREAD_Init(void)
|
||||||
{
|
{
|
||||||
|
static struct debug_info info; /* debug info for initial thread */
|
||||||
|
|
||||||
if (!initial_teb.self) /* do it only once */
|
if (!initial_teb.self) /* do it only once */
|
||||||
{
|
{
|
||||||
THREAD_InitTEB( &initial_teb );
|
THREAD_InitTEB( &initial_teb );
|
||||||
assert( initial_teb.teb_sel );
|
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 */
|
initial_teb.Peb = (PEB *)¤t_process; /* FIXME */
|
||||||
SYSDEPS_SetCurThread( &initial_teb );
|
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.
|
* 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))
|
if (TRACE_ON(relay))
|
||||||
DPRINTF("%04lx:Starting thread (entryproc=%p)\n", GetCurrentThreadId(), func );
|
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->request_fd = request_pipe[1];
|
||||||
teb->entry_point = start;
|
teb->entry_point = start;
|
||||||
teb->entry_arg = param;
|
teb->entry_arg = param;
|
||||||
teb->startup = THREAD_Start;
|
|
||||||
teb->htask16 = GetCurrentTask();
|
teb->htask16 = GetCurrentTask();
|
||||||
|
|
||||||
if (id) *id = tid;
|
if (id) *id = tid;
|
||||||
if (SYSDEPS_SpawnThread( teb ) == -1)
|
if (SYSDEPS_SpawnThread( THREAD_Start, teb ) == -1)
|
||||||
{
|
{
|
||||||
CloseHandle( handle );
|
CloseHandle( handle );
|
||||||
close( request_pipe[1] );
|
close( request_pipe[1] );
|
||||||
|
|
Loading…
Reference in New Issue