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:
Alexandre Julliard 2003-08-21 21:34:33 +00:00
parent 6677ac4bc0
commit aee989a7ed
4 changed files with 36 additions and 50 deletions

View File

@ -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 */

View File

@ -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;

View File

@ -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 );

View File

@ -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 *)&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(); }
* *
* 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] );