source: trunk/src/kernel32/thread.cpp@ 6829

Last change on this file since 6829 was 6829, checked in by phaller, 24 years ago

added calldepth tracing

File size: 5.5 KB
Line 
1/* $Id: thread.cpp,v 1.32 2001-09-26 15:29:39 phaller Exp $ */
2
3/*
4 * Win32 Thread API functions
5 *
6 * TODO: Initialize threadInfo structure during thread creation
7 *
8 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
9 *
10 * Project Odin Software License can be found in LICENSE.TXT
11 *
12 */
13
14/*****************************************************************************
15 * Includes *
16 *****************************************************************************/
17
18#include <odin.h>
19#include <odinwrap.h>
20#include <os2sel.h>
21
22#include <os2win.h>
23#include <stdarg.h>
24#include <string.h>
25#include "thread.h"
26#include <misc.h>
27#include <cpuhlp.h>
28#include <wprocess.h>
29#include <windllbase.h>
30#include <winexebase.h>
31#include "exceptutil.h"
32#include "oslibmisc.h"
33#include <handlemanager.h>
34
35#define DBG_LOCALLOG DBG_thread
36#include "dbglocal.h"
37
38ODINDEBUGCHANNEL(KERNEL32-THREAD)
39
40//******************************************************************************
41//******************************************************************************
42DWORD WIN32API GetCurrentThreadId()
43{
44//// dprintf(("GetCurrentThreadId\n"));
45 return(O32_GetCurrentThreadId());
46}
47//******************************************************************************
48//******************************************************************************
49HANDLE WIN32API GetCurrentThread()
50{
51 TEB *teb;
52
53 teb = GetThreadTEB();
54 if(teb == 0) {
55 SetLastError(ERROR_INVALID_HANDLE); //todo
56 return 0;
57 }
58 return teb->o.odin.hThread;
59}
60
61// these two debugging functions allow access to a
62// calldepth counter inside the TEB block of each thread
63ULONG WIN32API dbg_GetThreadCallDepth()
64{
65#ifdef DEBUG
66 TEB *teb;
67
68 teb = GetThreadTEB();
69 if(teb == NULL)
70 return 0;
71 else
72 return teb->o.odin.dbgCallDepth;
73#else
74 return 0;
75#endif
76}
77
78
79void WIN32API dbg_IncThreadCallDepth()
80{
81#ifdef DEBUG
82 TEB *teb;
83
84 teb = GetThreadTEB();
85 if(teb != NULL)
86 teb->o.odin.dbgCallDepth++;
87#endif
88}
89
90
91void WIN32API dbg_DecThreadCallDepth()
92{
93#ifdef DEBUG
94 TEB *teb;
95
96 teb = GetThreadTEB();
97 if(teb != NULL)
98 --(teb->o.odin.dbgCallDepth);
99#endif
100}
101
102
103//******************************************************************************
104//******************************************************************************
105VOID WIN32API ExitThread(DWORD exitcode)
106{
107 EXCEPTION_FRAME *exceptFrame;
108 TEB *teb;
109
110 dprintf(("ExitThread %x (%x)", GetCurrentThread(), exitcode));
111
112 teb = GetThreadTEB();
113 if(teb != 0) {
114 exceptFrame = (EXCEPTION_FRAME *)teb->o.odin.exceptFrame;
115 }
116 else DebugInt3();
117
118 HMSetThreadTerminated(GetCurrentThread());
119 Win32DllBase::detachThreadFromAllDlls(); //send DLL_THREAD_DETACH message to all dlls
120 Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
121 WinExe->tlsDetachThread(); //destroy TLS structure of main exe
122 DestroyTIB();
123
124 if(exceptFrame) OS2UnsetExceptionHandler((void *)exceptFrame);
125
126 O32_ExitThread(exitcode);
127}
128//******************************************************************************
129//******************************************************************************
130Win32Thread::Win32Thread(LPTHREAD_START_ROUTINE pUserCallback, LPVOID lpData, DWORD dwFlags, HANDLE hThread)
131{
132 lpUserData = lpData;
133 pCallback = pUserCallback;
134 this->dwFlags = dwFlags;
135 this->hThread = hThread;
136}
137//******************************************************************************
138//******************************************************************************
139DWORD OPEN32API Win32ThreadProc(LPVOID lpData)
140{
141 EXCEPTION_FRAME exceptFrame;
142 Win32Thread *me = (Win32Thread *)lpData;
143 ULONG winthread = (ULONG)me->pCallback;
144 LPVOID userdata = me->lpUserData;
145 HANDLE hThread = me->hThread;
146 DWORD rc;
147
148 delete(me); //only called once
149 dprintf(("Win32ThreadProc %d\n", GetCurrentThreadId()));
150
151 TEB *winteb = (TEB *)InitializeTIB();
152 if(winteb == NULL) {
153 dprintf(("Win32ThreadProc: InitializeTIB failed!!"));
154 DebugInt3();
155 return 0;
156 }
157 winteb->flags = me->dwFlags;
158
159 winteb->entry_point = (void *)winthread;
160 winteb->entry_arg = (void *)userdata;
161 winteb->o.odin.hThread = hThread;
162
163 winteb->o.odin.hab = OSLibWinInitialize();
164 winteb->o.odin.hmq = OSLibWinQueryMsgQueue(winteb->o.odin.hab);
165 dprintf(("Win32ThreadProc: hab %x hmq %x", winteb->o.odin.hab, winteb->o.odin.hmq));
166
167 //Note: The Win32 exception structure referenced by FS:[0] is the same
168 // in OS/2
169 OS2SetExceptionHandler((void *)&exceptFrame);
170 winteb->o.odin.exceptFrame = (ULONG)&exceptFrame;
171
172 SetWin32TIB();
173 WinExe->tlsAttachThread(); //setup TLS structure of main exe
174 Win32DllBase::tlsAttachThreadToAllDlls(); //setup TLS structures of all dlls
175 Win32DllBase::attachThreadToAllDlls(); //send DLL_THREAD_ATTACH message to all dlls
176
177 //Set FPU control word to 0x27F (same as in NT)
178 CONTROL87(0x27F, 0xFFF);
179 rc = AsmCallThreadHandler(winthread, userdata);
180
181 HMSetThreadTerminated(GetCurrentThread());
182 winteb->o.odin.exceptFrame = 0;
183 Win32DllBase::detachThreadFromAllDlls(); //send DLL_THREAD_DETACH message to all dlls
184 Win32DllBase::tlsDetachThreadFromAllDlls(); //destroy TLS structures of all dlls
185 WinExe->tlsDetachThread(); //destroy TLS structure of main exe
186 DestroyTIB();
187 OS2UnsetExceptionHandler((void *)&exceptFrame);
188
189 return rc;
190}
191//******************************************************************************
192//******************************************************************************
Note: See TracBrowser for help on using the repository browser.