source: trunk/src/kernel32/hmthread.cpp@ 8877

Last change on this file since 8877 was 8877, checked in by sandervl, 23 years ago

Rewrote algorithm for 64kb alignment in VirtualAlloc'ed memory; allocation changes for heap (in 64kb chunks) & PE image (align at 64kb)

File size: 9.9 KB
Line 
1/* $Id: hmthread.cpp,v 1.14 2002-07-15 14:28:51 sandervl Exp $ */
2
3/*
4 * Project Odin Software License can be found in LICENSE.TXT
5 *
6 * Win32 thread handle class
7 *
8 *
9 * TODO: Handle is not destroyed when thread terminates (or else GetExitCodeThread won't work)
10 * Create thread token during thread creation??
11 * Fix for WaitForSingleObject when thread is already terminated, but
12 * WaitForMultipleObjects can still fail!
13 * WaitForSingle/MultipleObjects needs to be rewritten! (not using
14 * Open32)
15 *
16 ************************************************************************************
17 * NOTE: If we ever decide to allocate our own stack, then we MUST use VirtualAlloc!!!!
18 * (alignment reasons)
19 ************************************************************************************
20 *
21 * Copyright 2000 Sander van Leeuwen (sandervl@xs4all.nl)
22 *
23 */
24#include <os2win.h>
25#include <stdlib.h>
26#include <string.h>
27#include <misc.h>
28#include <wprocess.h>
29
30#include <HandleManager.H>
31#include "HMThread.h"
32#include "oslibdos.h"
33
34#include <win\thread.h>
35#include "thread.h"
36#include "asmutil.h"
37
38#define DBG_LOCALLOG DBG_hmthread
39#include "dbglocal.h"
40
41
42//******************************************************************************
43//******************************************************************************
44HANDLE HMDeviceThreadClass::CreateThread(PHMHANDLEDATA pHMHandleData,
45 LPSECURITY_ATTRIBUTES lpsa,
46 DWORD cbStack,
47 LPTHREAD_START_ROUTINE lpStartAddr,
48 LPVOID lpvThreadParm,
49 DWORD fdwCreate,
50 LPDWORD lpIDThread,
51 BOOL fFirstThread)
52{
53 Win32Thread *winthread;
54 DWORD threadid;
55 HANDLE hThread = pHMHandleData->hHMHandle;
56
57 if(lpIDThread == NULL) {
58 lpIDThread = &threadid;
59 }
60 pHMHandleData->dwInternalType = HMTYPE_THREAD;
61 pHMHandleData->dwUserData = THREAD_ALIVE;
62
63 //SvL: This doesn't really create a thread, but only sets up the
64 // handle of thread 0
65 if(fFirstThread) {
66 pHMHandleData->hHMHandle = O32_GetCurrentThread(); //return Open32 handle of thread
67 return pHMHandleData->hHMHandle;
68 }
69 winthread = new Win32Thread(lpStartAddr, lpvThreadParm, fdwCreate, hThread);
70
71 if(winthread == 0) {
72 DebugInt3();
73 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
74 return(0);
75 }
76 // @@@PH Note: with debug code enabled, ODIN might request more stack space!
77 //SvL: Also need more stack in release build (RealPlayer 7 sometimes runs
78 // out of stack
79 if (cbStack > 0)
80 cbStack <<= 1; // double stack
81 else
82 cbStack = 1048576; // per default 1MB stack per thread
83
84 //************************************************************************************
85 //NOTE: If we ever decide to allocate our own stack, then we MUST use VirtualAlloc!!!!
86 // (alignment reasons)
87 //************************************************************************************
88 pHMHandleData->hHMHandle = O32_CreateThread(lpsa, cbStack, winthread->GetOS2Callback(),
89 (LPVOID)winthread, fdwCreate, lpIDThread);
90
91 *lpIDThread = MAKE_THREADID(O32_GetCurrentProcessId(), *lpIDThread);
92
93 TEB *teb = GetTEBFromThreadHandle(hThread);
94 if(teb) {
95 //store thread id in TEB
96 teb->o.odin.threadId = *lpIDThread;
97 }
98 dprintf(("CreateThread created %08x, id %x", pHMHandleData->hHMHandle, *lpIDThread));
99
100 return pHMHandleData->hHMHandle;
101}
102//******************************************************************************
103//******************************************************************************
104DWORD HMDeviceThreadClass::SuspendThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
105{
106 dprintf(("SuspendThread %08xh)\n", pHMHandleData->hHMHandle));
107
108 return O32_SuspendThread(pHMHandleData->hHMHandle);
109}
110//******************************************************************************
111//******************************************************************************
112INT HMDeviceThreadClass::GetThreadPriority(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
113{
114 TEB *teb;
115
116 dprintf(("GetThreadPriority(%08xh)\n", pHMHandleData->hHMHandle));
117
118 teb = GetTEBFromThreadHandle(hThread);
119 if(teb == NULL) {
120 dprintf(("!WARNING!: TEB not found!!"));
121 SetLastError(ERROR_INVALID_HANDLE);
122 return THREAD_PRIORITY_ERROR_RETURN;
123 }
124 return teb->delta_priority;
125}
126//******************************************************************************
127//******************************************************************************
128BOOL HMDeviceThreadClass::SetThreadPriority(HANDLE hThread, PHMHANDLEDATA pHMHandleData, int priority)
129{
130 TEB *teb;
131
132 dprintf(("SetThreadPriority (%08xh,%08xh)", pHMHandleData->hHMHandle, priority));
133
134 teb = GetTEBFromThreadHandle(hThread);
135 if(teb == NULL) {
136 dprintf(("!WARNING!: TEB not found!!"));
137 SetLastError(ERROR_INVALID_HANDLE);
138 return THREAD_PRIORITY_ERROR_RETURN;
139 }
140 DWORD ret = OSLibDosSetPriority(ODIN_TO_OS2_THREADID(teb->o.odin.threadId), priority);
141 if(ret == ERROR_SUCCESS) {
142 teb->delta_priority = priority;
143 return TRUE;
144 }
145 else {
146 dprintf(("DosSetPriority failed with rc %d", ret));
147 return FALSE;
148 }
149}
150//******************************************************************************
151//TODO: Implement this??
152//******************************************************************************
153BOOL HMDeviceThreadClass::GetThreadContext(HANDLE hThread, PHMHANDLEDATA pHMHandleData, PCONTEXT lpContext)
154{
155 dprintf(("GetThreadContext NOT IMPLEMENTED!! (TRUE)\n"));
156 memset(lpContext, 0, sizeof(CONTEXT));
157
158 /* make up some plausible values for segment registers */
159 lpContext->SegCs = getCS();
160 lpContext->SegDs = getDS();
161 lpContext->SegSs = getSS();
162 lpContext->SegEs = getES();
163 lpContext->SegGs = getGS();
164 lpContext->SegFs = GetFS();
165
166 return TRUE;
167}
168//******************************************************************************
169//TODO: Implement this??
170//******************************************************************************
171BOOL HMDeviceThreadClass::SetThreadContext(HANDLE hThread, PHMHANDLEDATA pHMHandleData, const CONTEXT *lpContext)
172{
173 dprintf(("SetThreadContext NOT IMPLEMENTED!!\n"));
174
175 return FALSE;
176}
177//******************************************************************************
178//******************************************************************************
179BOOL HMDeviceThreadClass::TerminateThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData, DWORD exitcode)
180{
181 dprintf(("TerminateThread (%08xh,%08xh)\n",
182 pHMHandleData->hHMHandle,
183 exitcode));
184
185 pHMHandleData->dwUserData = THREAD_TERMINATED;
186 return O32_TerminateThread(pHMHandleData->hHMHandle, exitcode);
187}
188//******************************************************************************
189//******************************************************************************
190BOOL HMDeviceThreadClass::SetThreadTerminated(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
191{
192 pHMHandleData->dwUserData = THREAD_TERMINATED;
193 return TRUE;
194}
195//******************************************************************************
196//******************************************************************************
197DWORD HMDeviceThreadClass::ResumeThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData)
198{
199 dprintf(("ResumeThread (%08xh)\n",
200 pHMHandleData->hHMHandle));
201
202 return O32_ResumeThread(pHMHandleData->hHMHandle);
203}
204//******************************************************************************
205//******************************************************************************
206BOOL HMDeviceThreadClass::GetExitCodeThread(HANDLE hThread, PHMHANDLEDATA pHMHandleData, LPDWORD lpExitCode)
207{
208 dprintf(("GetExitCodeThread (%08xh,%08xh)\n",
209 pHMHandleData->hHMHandle,
210 lpExitCode));
211
212#if 0
213 if(pHMHandleData->dwUserData == THREAD_ALIVE) {
214 lpExitCode == STILL_ALIVE;
215 return TRUE;
216 }
217#endif
218 return O32_GetExitCodeThread(pHMHandleData->hHMHandle, lpExitCode);
219}
220//******************************************************************************
221//******************************************************************************
222BOOL HMDeviceThreadClass::CloseHandle(PHMHANDLEDATA pHMHandleData)
223{
224 return TRUE;
225}
226//******************************************************************************
227//******************************************************************************
228DWORD HMDeviceThreadClass::WaitForSingleObject(PHMHANDLEDATA pHMHandleData,
229 DWORD dwTimeout)
230{
231 dprintf(("HMThread::WaitForSingleObject (%08xh,%08xh)\n",
232 pHMHandleData->hHMHandle,
233 dwTimeout));
234
235 //This doesn't work very well in Open32 (object's state never signaled)
236 if(pHMHandleData->dwUserData == THREAD_TERMINATED) {
237 return WAIT_OBJECT_0;
238 }
239 return HMDeviceOpen32Class::WaitForSingleObject(pHMHandleData, dwTimeout);
240}
241//******************************************************************************
242//******************************************************************************
243DWORD HMDeviceThreadClass::WaitForSingleObjectEx(PHMHANDLEDATA pHMHandleData,
244 DWORD dwTimeout,
245 BOOL fAlertable)
246{
247 if(pHMHandleData->dwUserData == THREAD_TERMINATED) {
248 return WAIT_OBJECT_0;
249 }
250 return HMDeviceOpen32Class::WaitForSingleObjectEx(pHMHandleData, dwTimeout, fAlertable);
251}
252//******************************************************************************
253//******************************************************************************
Note: See TracBrowser for help on using the repository browser.