From aee989a7ed5f935f61502e5d0c9fb87205987e0e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 21 Aug 2003 21:34:33 +0000 Subject: [PATCH] Store the debug info structure on the thread stack. Moved thread initialization code from sysdeps.c to thread.c to avoid an indirection. --- dlls/ntdll/debugtools.c | 20 +------------------- dlls/ntdll/sysdeps.c | 25 +++++-------------------- include/thread.h | 14 +++++++++++--- scheduler/thread.c | 27 +++++++++++++++++++-------- 4 files changed, 36 insertions(+), 50 deletions(-) diff --git a/dlls/ntdll/debugtools.c b/dlls/ntdll/debugtools.c index 8b0665d18b9..69ced57028d 100644 --- a/dlls/ntdll/debugtools.c +++ b/dlls/ntdll/debugtools.c @@ -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 */ diff --git a/dlls/ntdll/sysdeps.c b/dlls/ntdll/sysdeps.c index 14dd2b913da..b0dc4ea0359 100644 --- a/dlls/ntdll/sysdeps.c +++ b/dlls/ntdll/sysdeps.c @@ -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; diff --git a/include/thread.h b/include/thread.h index eb85f7fd820..79665cb3af6 100644 --- a/include/thread.h +++ b/include/thread.h @@ -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 ); diff --git a/scheduler/thread.c b/scheduler/thread.c index 700006a0d6c..414a52daa01 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -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] );