source: trunk/src/kernel32/wintls.cpp@ 4285

Last change on this file since 4285 was 4285, checked in by hugh, 25 years ago

Implemented Serial APIs

File size: 7.4 KB
Line 
1/* $Id: wintls.cpp,v 1.12 2000-09-20 21:32:54 hugh Exp $ */
2/*
3 * Win32 TLS API functions
4 *
5 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 * TODO: correct errors set for Tls* apis? (verify in NT)
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <string.h>
14#include <winimagebase.h>
15#include <thread.h>
16#include <wprocess.h>
17#include "exceptutil.h"
18
19#define DBG_LOCALLOG DBG_wintls
20#include "dbglocal.h"
21
22//******************************************************************************
23//******************************************************************************
24void Win32ImageBase::tlsAlloc() //Allocate TLS index for this module
25{
26 if(!tlsAddress)
27 return;
28
29 tlsIndex = TlsAlloc();
30 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
31 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
32 DebugInt3();
33 return;
34 }
35 dprintf(("Win32ImageBase::tlsAlloc (%d) for module %x", tlsIndex, hinstance));
36}
37//******************************************************************************
38//******************************************************************************
39void Win32ImageBase::tlsDelete() //Free TLS index for this module
40{
41 if(!tlsAddress)
42 return;
43
44 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
45 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
46 DebugInt3();
47 return;
48 }
49 dprintf(("Win32ImageBase::tlsDestroy (%d) for module %x", tlsIndex, hinstance));
50 TlsFree(tlsIndex);
51 tlsIndex = -1;
52}
53//******************************************************************************
54//******************************************************************************
55void Win32ImageBase::tlsAttachThread() //setup TLS structures for new thread
56{
57 EXCEPTION_FRAME exceptFrame;
58 PIMAGE_TLS_CALLBACK *pCallback;
59 LPVOID tibmem;
60
61 if(!tlsAddress)
62 return;
63
64 if(tlsIndex >= TLS_MINIMUM_AVAILABLE) {
65 dprintf(("tlsAttachThread: invalid tlsIndex %x!!!!", tlsIndex));
66 DebugInt3();
67 return;
68 }
69
70 dprintf(("Win32ImageBase::tlsAttachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
71 dprintf(("tlsAddress: %x", tlsAddress));
72 dprintf(("tlsInitSize: %x", tlsInitSize));
73 dprintf(("tlsTotalSize %x", tlsTotalSize));
74 dprintf(("tlsIndexAddr %x", tlsIndexAddr));
75 dprintf(("tlsCallbackAddr %x", tlsCallBackAddr));
76 dprintf(("*tlsCallbackAddr %x", (tlsCallBackAddr) ? *tlsCallBackAddr : 0));
77 tibmem = VirtualAlloc(0, tlsTotalSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
78 if(tibmem == NULL) {
79 dprintf(("tlsAttachThread: tibmem == NULL!!!!"));
80 DebugInt3();
81 return;
82 }
83 memset(tibmem, 0, tlsTotalSize);
84 memcpy(tibmem, tlsAddress, tlsInitSize);
85
86 TlsSetValue(tlsIndex, tibmem);
87 *tlsIndexAddr = tlsIndex;
88
89 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0) {
90 pCallback = tlsCallBackAddr;
91 while(*pCallback) {
92 dprintf(("tlsAttachThread: calling TLS Callback %x", *pCallback));
93
94 (*pCallback)((LPVOID)hinstance, DLL_THREAD_ATTACH, 0);
95
96 dprintf(("tlsAttachThread: finished calling TLS Callback %x", *pCallback));
97 *pCallback++;
98 }
99 }
100 return;
101}
102//******************************************************************************
103//******************************************************************************
104void Win32ImageBase::tlsDetachThread() //destroy TLS structures
105{
106 EXCEPTION_FRAME exceptFrame;
107 PIMAGE_TLS_CALLBACK *pCallback;
108 LPVOID tlsmem;
109
110 if(!tlsAddress)
111 return;
112
113 dprintf(("Win32ImageBase::tlsDetachThread for module %x, thread id %x", hinstance, GetCurrentThreadId()));
114
115 if(tlsCallBackAddr && (ULONG)*tlsCallBackAddr != 0) {
116 pCallback = tlsCallBackAddr;
117 while(*pCallback) {
118 dprintf(("tlsDetachThread: calling TLS Callback %x", *pCallback));
119
120 (*pCallback)((LPVOID)hinstance, DLL_THREAD_DETACH, 0);
121
122 dprintf(("tlsDetachThread: finished calling TLS Callback %x", *pCallback));
123 *pCallback++;
124 }
125 }
126 tlsmem = TlsGetValue(tlsIndex);
127 if(tlsmem) {
128 VirtualFree(tlsmem, tlsTotalSize, MEM_RELEASE);
129 }
130 else {
131 dprintf(("ERROR: tlsDetachThread: tlsmem == NULL!!!"));
132 }
133 TlsFree(tlsIndex);
134}
135//******************************************************************************
136//******************************************************************************
137
138//******************************************************************************
139//******************************************************************************
140DWORD WIN32API TlsAlloc()
141{
142 DWORD index = -1;
143
144#if 1
145 THDB *thdb;
146 PDB *pdb;
147 DWORD mask, tibidx;
148 int i;
149
150 thdb = GetThreadTHDB();
151 pdb = PROCESS_Current();
152
153 EnterCriticalSection(&pdb->crit_section);
154 tibidx = 0;
155 if(pdb->tls_bits[0] == 0xFFFFFFFF) {
156 if(pdb->tls_bits[1] == 0xFFFFFFFF) {
157 LeaveCriticalSection(&pdb->crit_section);
158 SetLastError(ERROR_NO_MORE_ITEMS); //TODO: correct error?
159 return -1;
160 }
161 tibidx = 1;
162 }
163 for(i=0;i<32;i++) {
164 mask = (1 << i);
165 if((pdb->tls_bits[tibidx] & mask) == 0) {
166 pdb->tls_bits[tibidx] |= mask;
167 index = (tibidx*32) + i;
168 break;
169 }
170 }
171 LeaveCriticalSection(&pdb->crit_section);
172 thdb->tls_array[index] = 0;
173#else
174 index = O32_TlsAlloc();
175#endif
176 dprintf(("KERNEL32: TlsAlloc returned %d", index));
177 return index;
178}
179//******************************************************************************
180//******************************************************************************
181BOOL WIN32API TlsFree(DWORD index)
182{
183 dprintf(("KERNEL32: TlsFree %d", index));
184#if 1
185 THDB *thdb;
186 PDB *pdb;
187 int tlsidx;
188 DWORD mask;
189
190 if(index >= TLS_MINIMUM_AVAILABLE)
191 {
192 SetLastError(ERROR_INVALID_PARAMETER);
193 return NULL;
194 }
195
196 thdb = GetThreadTHDB();
197 pdb = PROCESS_Current();
198
199 EnterCriticalSection(&pdb->crit_section);
200 tlsidx = 0;
201 if(index > 32) {
202 tlsidx++;
203 }
204 mask = (1 << index);
205 if(pdb->tls_bits[tlsidx] & mask) {
206 LeaveCriticalSection(&pdb->crit_section);
207 pdb->tls_bits[tlsidx] &= ~mask;
208 thdb->tls_array[index] = 0;
209 SetLastError(ERROR_SUCCESS);
210 return TRUE;
211 }
212 LeaveCriticalSection(&pdb->crit_section);
213 SetLastError(ERROR_INVALID_PARAMETER); //TODO: correct error? (does NT even change the last error?)
214 return FALSE;
215#else
216 return(O32_TlsFree(index));
217#endif
218}
219//******************************************************************************
220//******************************************************************************
221LPVOID WIN32API TlsGetValue(DWORD index)
222{
223 LPVOID rc;
224
225 if(index >= TLS_MINIMUM_AVAILABLE)
226 {
227 SetLastError(ERROR_INVALID_PARAMETER);
228 return NULL;
229 }
230 SetLastError(ERROR_SUCCESS);
231
232#if 1
233 THDB *thdb;
234
235 thdb = GetThreadTHDB();
236 rc = thdb->tls_array[index];
237#else
238 rc = O32_TlsGetValue(index);
239#endif
240 dprintf2(("KERNEL32: TlsGetValue %d returned %X\n", index, rc));
241 return(rc);
242}
243//******************************************************************************
244//******************************************************************************
245BOOL WIN32API TlsSetValue(DWORD index, LPVOID val)
246{
247 dprintf2(("KERNEL32: TlsSetValue %d %x", index, val));
248 if(index >= TLS_MINIMUM_AVAILABLE)
249 {
250 SetLastError(ERROR_INVALID_PARAMETER);
251 return FALSE;
252 }
253 SetLastError(ERROR_SUCCESS);
254#if 1
255 THDB *thdb;
256
257 thdb = GetThreadTHDB();
258 thdb->tls_array[index] = val;
259 return TRUE;
260#else
261 return(O32_TlsSetValue(index, val));
262#endif
263}
264//******************************************************************************
265//******************************************************************************
Note: See TracBrowser for help on using the repository browser.