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

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

View file

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

View file

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