Commit aee989a7 authored by Alexandre Julliard's avatar Alexandre Julliard

Store the debug info structure on the thread stack.

Moved thread initialization code from sysdeps.c to thread.c to avoid an indirection.
parent 6677ac4b
...@@ -47,16 +47,6 @@ WINE_DECLARE_DEBUG_CHANNEL(tid); ...@@ -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) ...@@ -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 */
......
...@@ -138,27 +138,12 @@ static void cleanup_thread( void *ptr ) ...@@ -138,27 +138,12 @@ 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 ) ...@@ -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 ) ...@@ -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 ) ...@@ -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; ...@@ -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 ...@@ -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 ...@@ -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 ); ...@@ -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 ) ...@@ -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 ) ...@@ -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 *)&current_process; /* FIXME */ initial_teb.Peb = (PEB *)&current_process; /* FIXME */
SYSDEPS_SetCurThread( &initial_teb ); SYSDEPS_SetCurThread( &initial_teb );
} }
...@@ -224,9 +227,18 @@ DECL_GLOBAL_CONSTRUCTOR(thread_init) { THREAD_Init(); } ...@@ -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, ...@@ -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] );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment