From 54a39e253c1833bb49201bf2648029e940e9a6df Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Sat, 29 May 1999 14:27:26 +0000 Subject: [PATCH] Got rid of THREAD_InitDone. Made THREAD_Current() inline. Moved server tid into TEB. --- include/thread.h | 34 ++++++++++++++++++++++------------ loader/task.c | 8 +++----- scheduler/client.c | 24 ++++++++++++++---------- scheduler/process.c | 2 +- scheduler/sysdeps.c | 48 ++++++++++++++++++++++++++++++++++-------------- scheduler/syslevel.c | 8 ++++---- scheduler/thread.c | 38 ++++++-------------------------------- windows/queue.c | 2 +- windows/winproc.c | 2 +- 9 files changed, 86 insertions(+), 80 deletions(-) diff --git a/include/thread.h b/include/thread.h index 4426e022184..9dd985ee1dd 100644 --- a/include/thread.h +++ b/include/thread.h @@ -29,11 +29,11 @@ typedef struct _TEB WORD flags; /* 1c Flags */ WORD mutex_count; /* 1e Win16 mutex count */ DWORD debug_context; /* 20 Debug context */ - DWORD *ppriority; /* 24 Pointer to current priority */ + void *tid; /* 24 Thread id */ HQUEUE16 queue; /* 28 Message queue */ WORD pad1; /* 2a */ LPVOID *tls_ptr; /* 2c Pointer to TLS array */ - struct _PDB *process; /* 30 owning process (used by NT3.51 applets)*/ + struct _PDB *process; /* 30 owning process (used by NT3.51 applets)*/ } TEB; /* Thread exception flags */ @@ -84,7 +84,6 @@ typedef struct _THDB /* The following are Wine-specific fields */ int socket; /* Socket for server communication */ unsigned int seq; /* Server sequence number */ - void *server_tid; /* Server id for this thread */ void (*startup)(void); /* Thread startup routine */ struct _THDB *next; /* Global thread list */ DWORD cleanup; /* Cleanup service handle */ @@ -96,27 +95,38 @@ typedef struct _THDB /* The per-thread signal stack size */ #define SIGNAL_STACK_SIZE 16384 -#ifdef __i386__ -/* On the i386, the current thread is in the %fs register */ -# define SET_CUR_THREAD(thdb) SET_FS((thdb)->teb_sel) -#else -extern THDB *pCurrentThread; -# define SET_CUR_THREAD(thdb) (pCurrentThread = (thdb)) -#endif /* __i386__ */ - /* scheduler/thread.c */ extern THDB *THREAD_CreateInitialThread( struct _PDB *pdb, int server_fd ); extern THDB *THREAD_Create( struct _PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16, LPSECURITY_ATTRIBUTES sa, int *server_handle ); -extern THDB *THREAD_Current(void); extern BOOL THREAD_IsWin16( THDB *thdb ); extern THDB *THREAD_IdToTHDB( DWORD id ); /* scheduler/sysdeps.c */ extern int SYSDEPS_SpawnThread( THDB *thread ); +extern void SYSDEPS_SetCurThread( THDB *thread ); extern void SYSDEPS_ExitThread(void); extern TEB * WINAPI NtCurrentTeb(void); +/* return the current thread TEB pointer */ +static inline TEB *CURRENT(void) +{ +#ifdef __i386__ + TEB *teb; + __asm__( ".byte 0x64\n\tmovl (0x18),%0" : "=r" (teb) ); + return teb; +#else + return NtCurrentTeb(); +#endif +} + +/* return the current thread THDB pointer */ +static inline THDB *THREAD_Current(void) +{ + TEB *teb = CURRENT(); + return (THDB *)((char *)teb - (int)&((THDB *)0)->teb); +} + #endif /* __WINE_THREAD_H */ diff --git a/loader/task.c b/loader/task.c index 61cb6df8ad5..8dca248c649 100644 --- a/loader/task.c +++ b/loader/task.c @@ -66,8 +66,6 @@ static HANDLE TASK_ScheduleEvent = INVALID_HANDLE_VALUE; static void TASK_YieldToSystem( void ); -extern BOOL THREAD_InitDone; - /*********************************************************************** * TASK_InstallTHHook @@ -239,7 +237,7 @@ static void TASK_CallToStart(void) NE_MODULE *pModule = NE_GetPtr( pTask->hModule ); SEGTABLEENTRY *pSegTable = NE_SEG_TABLE( pModule ); - SET_CUR_THREAD( pTask->thdb ); + SYSDEPS_SetCurThread( pTask->thdb ); CLIENT_InitThread(); /* Terminate the stack frame chain */ @@ -825,7 +823,7 @@ BOOL TASK_Reschedule(void) SYSLEVEL_ReleaseWin16Lock(); hCurrentTask = hTask; - SET_CUR_THREAD( pNewTask->thdb ); + SYSDEPS_SetCurThread( pNewTask->thdb ); pNewTask->ss_sp = pNewTask->thdb->cur_stack; SYSLEVEL_RestoreWin16Lock(); @@ -1415,7 +1413,7 @@ void WINAPI GetTaskQueueES16( CONTEXT *context ) */ HTASK16 WINAPI GetCurrentTask(void) { - return THREAD_InitDone? PROCESS_Current()->task : 0; + return PROCESS_Current()->task; } DWORD WINAPI WIN16_GetCurrentTask(void) diff --git a/scheduler/client.c b/scheduler/client.c index 411427f5354..1ca19d22852 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -32,9 +32,9 @@ * * Die on protocol errors or socket close */ -static void CLIENT_Die( THDB *thdb ) +static void CLIENT_Die(void) { - close( thdb->socket ); + close( THREAD_Current()->socket ); SYSDEPS_ExitThread(); } @@ -43,14 +43,13 @@ static void CLIENT_Die( THDB *thdb ) */ void CLIENT_ProtocolError( const char *err, ... ) { - THDB *thdb = THREAD_Current(); va_list args; va_start( args, err ); - fprintf( stderr, "Client protocol error:%p: ", thdb->server_tid ); + fprintf( stderr, "Client protocol error:%p: ", CURRENT()->tid ); vfprintf( stderr, err, args ); va_end( args ); - CLIENT_Die( thdb ); + CLIENT_Die(); } @@ -116,7 +115,11 @@ static void CLIENT_SendRequest_v( enum request req, int pass_fd, if ((ret = sendmsg( thdb->socket, &msghdr, 0 )) < len) { - if (ret == -1) perror( "sendmsg" ); + if (ret == -1) + { + if (errno == EPIPE) CLIENT_Die(); + perror( "sendmsg" ); + } CLIENT_ProtocolError( "partial msg sent %d/%d\n", ret, len ); } /* we passed the fd now we can close it */ @@ -193,10 +196,11 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, while ((ret = recvmsg( thdb->socket, &msghdr, 0 )) == -1) { if (errno == EINTR) continue; + if (errno == EPIPE) CLIENT_Die(); perror("recvmsg"); CLIENT_ProtocolError( "recvmsg\n" ); } - if (!ret) CLIENT_Die( thdb ); /* the server closed the connection; time to die... */ + if (!ret) CLIENT_Die(); /* the server closed the connection; time to die... */ /* sanity checks */ @@ -240,7 +244,7 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, perror( "recv" ); CLIENT_ProtocolError( "recv\n" ); } - if (!addlen) CLIENT_Die( thdb ); /* the server closed the connection; time to die... */ + if (!addlen) CLIENT_Die(); /* the server closed the connection; time to die... */ if (len) *len += addlen; remaining -= addlen; } @@ -257,7 +261,7 @@ static unsigned int CLIENT_WaitReply_v( int *len, int *passed_fd, perror( "recv" ); CLIENT_ProtocolError( "recv\n" ); } - if (!addlen) CLIENT_Die( thdb ); /* the server closed the connection; time to die... */ + if (!addlen) CLIENT_Die(); /* the server closed the connection; time to die... */ remaining -= addlen; } @@ -367,7 +371,7 @@ int CLIENT_InitThread(void) CLIENT_SendRequest( REQ_INIT_THREAD, -1, 1, &req, sizeof(req) ); if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) return -1; thdb->process->server_pid = reply.pid; - thdb->server_tid = reply.tid; + thdb->teb.tid = reply.tid; return 0; } diff --git a/scheduler/process.c b/scheduler/process.c index 72a22315130..eca3e0d34f6 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -606,7 +606,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env, if (!(thdb = THREAD_Create( pdb, 0L, size, hInstance == 0, tsa, &server_thandle ))) goto error; info->hThread = server_thandle; - info->dwThreadId = (DWORD)thdb->server_tid; + info->dwThreadId = (DWORD)thdb->teb.tid; thdb->startup = PROCESS_Start; if (pModule->module32) diff --git a/scheduler/sysdeps.c b/scheduler/sysdeps.c index 4a0b21d3934..27d4734119e 100644 --- a/scheduler/sysdeps.c +++ b/scheduler/sysdeps.c @@ -54,6 +54,12 @@ extern int clone( int (*fn)(void *arg), void *stack, int flags, void *arg ); # endif /* CLONE_VM */ #endif /* HAVE_CLONE_SYSCALL */ +static int init_done; + +#ifndef __i386__ +static THDB *pCurrentThread; +#endif + #ifndef NO_REENTRANT_LIBC @@ -72,11 +78,12 @@ int *__error() int *___errno() #endif { - THDB *thdb = THREAD_Current(); - if (!thdb) return perrno; + THDB *thdb; + if (!init_done) return perrno; + thdb = THREAD_Current(); #ifdef NO_REENTRANT_X11 /* Use static libc errno while running in Xlib. */ - if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->server_tid) + if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->teb.tid) return perrno; #endif return &thdb->thread_errno; @@ -89,11 +96,12 @@ int *___errno() */ int *__h_errno_location() { - THDB *thdb = THREAD_Current(); - if (!thdb) return ph_errno; + THDB *thdb; + if (!init_done) return ph_errno; + thdb = THREAD_Current(); #ifdef NO_REENTRANT_X11 /* Use static libc h_errno while running in Xlib. */ - if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->server_tid) + if (X11DRV_CritSection.OwningThread == (HANDLE)thdb->teb.tid) return ph_errno; #endif return &thdb->thread_h_errno; @@ -102,16 +110,33 @@ int *__h_errno_location() #endif /* NO_REENTRANT_LIBC */ /*********************************************************************** + * SYSDEPS_SetCurThread + * + * Make 'thread' the current thread. + */ +void SYSDEPS_SetCurThread( THDB *thread ) +{ +#ifdef __i386__ + /* On the i386, the current thread is in the %fs register */ + SET_FS( thread->teb_sel ); +#else + /* FIXME: only works if there is no preemptive task-switching going on... */ + pCurrentThread = thread; +#endif /* __i386__ */ + init_done = 1; /* now we can use threading routines */ +} + +/*********************************************************************** * SYSDEPS_StartThread * * Startup routine for a new thread. */ static void SYSDEPS_StartThread( THDB *thdb ) { - SET_CUR_THREAD( thdb ); + SYSDEPS_SetCurThread( thdb ); CLIENT_InitThread(); thdb->startup(); - _exit(0); /* should never get here */ + SYSDEPS_ExitThread(); /* should never get here */ } @@ -197,12 +222,7 @@ void SYSDEPS_ExitThread(void) TEB * WINAPI NtCurrentTeb(void) { #ifdef __i386__ - TEB *teb; - - /* Get the TEB self-pointer */ - __asm__( ".byte 0x64\n\tmovl (%1),%0" - : "=r" (teb) : "r" (&((TEB *)0)->self) ); - return teb; + return CURRENT(); #else return &pCurrentThread->teb; #endif /* __i386__ */ diff --git a/scheduler/syslevel.c b/scheduler/syslevel.c index 95c6eec117f..da715fe32bd 100644 --- a/scheduler/syslevel.c +++ b/scheduler/syslevel.c @@ -75,7 +75,7 @@ VOID WINAPI _EnterSysLevel(SYSLEVEL *lock) int i; TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n", - lock, lock->level, thdb->server_tid, thdb->teb_sel, getpid(), + lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(), thdb->sys_count[lock->level] ); for ( i = 3; i > lock->level; i-- ) @@ -91,7 +91,7 @@ VOID WINAPI _EnterSysLevel(SYSLEVEL *lock) thdb->sys_mutex[lock->level] = lock; TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n", - lock, lock->level, thdb->server_tid, thdb->teb_sel, getpid(), + lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(), thdb->sys_count[lock->level] ); if (lock == &Win16Mutex) @@ -106,7 +106,7 @@ VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock) THDB *thdb = THREAD_Current(); TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count before %ld\n", - lock, lock->level, thdb->server_tid, thdb->teb_sel, getpid(), + lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(), thdb->sys_count[lock->level] ); if ( thdb->sys_count[lock->level] <= 0 || thdb->sys_mutex[lock->level] != lock ) @@ -124,7 +124,7 @@ VOID WINAPI _LeaveSysLevel(SYSLEVEL *lock) LeaveCriticalSection( &lock->crst ); TRACE("(%p, level %d): thread %p (fs %04x, pid %d) count after %ld\n", - lock, lock->level, thdb->server_tid, thdb->teb_sel, getpid(), + lock, lock->level, thdb->teb.tid, thdb->teb_sel, getpid(), thdb->sys_count[lock->level] ); } diff --git a/scheduler/thread.c b/scheduler/thread.c index ee8bf3720a2..6c184b14ae9 100644 --- a/scheduler/thread.c +++ b/scheduler/thread.c @@ -28,13 +28,6 @@ DEFAULT_DEBUG_CHANNEL(thread) -#ifndef __i386__ -THDB *pCurrentThread; -#endif - -/* Is threading code initialized? */ -BOOL THREAD_InitDone = FALSE; - /* THDB of the initial thread */ static THDB initial_thdb; @@ -42,17 +35,6 @@ static THDB initial_thdb; THDB *THREAD_First = &initial_thdb; /*********************************************************************** - * THREAD_Current - * - * Return the current thread THDB pointer. - */ -THDB *THREAD_Current(void) -{ - if (!THREAD_InitDone) return NULL; - return (THDB *)((char *)NtCurrentTeb() - (int)&((THDB *)0)->teb); -} - -/*********************************************************************** * THREAD_IsWin16 */ BOOL THREAD_IsWin16( THDB *thdb ) @@ -72,7 +54,7 @@ THDB *THREAD_IdToTHDB( DWORD id ) if (!id) return THREAD_Current(); while (thdb) { - if ((DWORD)thdb->server_tid == id) return thdb; + if ((DWORD)thdb->teb.tid == id) return thdb; thdb = thdb->next; } /* Allow task handles to be used; convert to main thread */ @@ -202,8 +184,7 @@ THDB *THREAD_CreateInitialThread( PDB *pdb, int server_fd ) MESSAGE("Could not allocate fs register for initial thread\n" ); return NULL; } - SET_CUR_THREAD( &initial_thdb ); - THREAD_InitDone = TRUE; + SYSDEPS_SetCurThread( &initial_thdb ); /* Now proceed with normal initialization */ @@ -259,7 +240,7 @@ THDB *THREAD_Create( PDB *pdb, DWORD flags, DWORD stack_size, BOOL alloc_stack16 request.inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle); CLIENT_SendRequest( REQ_NEW_THREAD, fd[1], 1, &request, sizeof(request) ); if (CLIENT_WaitSimpleReply( &reply, sizeof(reply), NULL )) goto error; - thdb->server_tid = reply.tid; + thdb->teb.tid = reply.tid; *server_handle = reply.handle; /* Do the rest of the initialization */ @@ -321,7 +302,7 @@ HANDLE WINAPI CreateThread( SECURITY_ATTRIBUTES *sa, DWORD stack, CloseHandle( handle ); return INVALID_HANDLE_VALUE; } - if (id) *id = (DWORD)thread->server_tid; + if (id) *id = (DWORD)thread->teb.tid; return handle; } @@ -359,10 +340,7 @@ HANDLE WINAPI GetCurrentThread(void) */ DWORD WINAPI GetCurrentThreadId(void) { - THDB *thdb = THREAD_Current(); - assert( thdb ); - assert( thdb->server_tid ); - return (DWORD)thdb->server_tid; + return (DWORD)CURRENT()->tid; } @@ -391,12 +369,8 @@ void WINAPI SetLastError( DWORD error) /* [in] Per-thread error code */ { THDB *thread = THREAD_Current(); - /* This one must work before we have a thread (FIXME) */ - TRACE("%p error=0x%lx\n",thread,error); - - if (thread) - thread->last_error = error; + thread->last_error = error; } diff --git a/windows/queue.c b/windows/queue.c index d27ec951163..f4ae0d7d4f4 100644 --- a/windows/queue.c +++ b/windows/queue.c @@ -1370,7 +1370,7 @@ DWORD WINAPI GetWindowThreadProcessId( HWND hwnd, LPDWORD process ) if (!queue) return 0; if ( process ) *process = (DWORD)queue->thdb->process->server_pid; - retvalue = (DWORD)queue->thdb->server_tid; + retvalue = (DWORD)queue->thdb->teb.tid; QUEUE_Unlock( queue ); return retvalue; diff --git a/windows/winproc.c b/windows/winproc.c index 4e4c351c346..1f0b4b1b7e4 100644 --- a/windows/winproc.c +++ b/windows/winproc.c @@ -1114,7 +1114,7 @@ INT WINPROC_MapMsg16To32A( UINT16 msg16, WPARAM16 wParam16, UINT *pmsg32, message queues. */ HTASK16 htask = (HTASK16) *plparam; - DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->thdb->server_tid; + DWORD idThread = (DWORD)((TDB*)GlobalLock16(htask))->thdb->teb.tid; *plparam = (LPARAM) idThread; } return 1; -- 2.11.4.GIT