update for HEAD-2003091401
[reactos.git] / lib / kernel32 / thread / tls.c
1 /* $Id$
2  *
3  * COPYRIGHT:       See COPYING in the top level directory
4  * PROJECT:         ReactOS system libraries
5  * FILE:            lib/kernel32/thread/tls.c
6  * PURPOSE:         Thread functions
7  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
8  *                  Tls functions are modified from WINE
9  * UPDATE HISTORY:
10  *                  Created 01/11/98
11  */
12
13 /* INCLUDES ******************************************************************/
14
15 #include <k32.h>
16
17 #define NDEBUG
18 #include <kernel32/kernel32.h>
19
20
21 /* FUNCTIONS *****************************************************************/
22
23 /*
24  * @implemented
25  */
26 DWORD STDCALL 
27 TlsAlloc(VOID)
28 {
29    ULONG Index;
30
31    RtlAcquirePebLock();
32    Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap, 1, 0);
33    if (Index == (ULONG)-1)
34      {
35        SetLastErrorByStatus(STATUS_NO_MEMORY);
36      }
37    else
38      {
39        NtCurrentTeb()->TlsSlots[Index] = 0;
40      }
41    RtlReleasePebLock();
42    
43    return(Index);
44 }
45
46
47 /*
48  * @implemented
49  */
50 WINBOOL STDCALL 
51 TlsFree(DWORD dwTlsIndex)
52 {
53    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
54      {
55         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
56         return(FALSE);
57      }
58
59    RtlAcquirePebLock();
60    if (RtlAreBitsSet(NtCurrentPeb()->TlsBitmap, dwTlsIndex, 1))
61      {
62         /*
63          * clear the tls cells (slots) in all threads
64          * of the current process
65          */
66         NtSetInformationThread(NtCurrentThread(),
67                                ThreadZeroTlsCell,
68                                &dwTlsIndex,
69                                sizeof(DWORD));
70         RtlClearBits(NtCurrentPeb()->TlsBitmap,
71                      dwTlsIndex,
72                      1);
73      }
74    RtlReleasePebLock();
75
76    return(TRUE);
77 }
78
79
80 /*
81  * @implemented
82  */
83 LPVOID STDCALL 
84 TlsGetValue(DWORD dwTlsIndex)
85 {
86    LPVOID Value;
87
88    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
89      {
90         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
91         return(NULL);
92      }
93
94    Value = NtCurrentTeb()->TlsSlots[dwTlsIndex];
95    if (Value == 0)
96    {
97       SetLastError(NO_ERROR);
98    }
99    return Value;
100 }
101
102
103 /*
104  * @implemented
105  */
106 WINBOOL STDCALL 
107 TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
108 {
109    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
110      {
111         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
112         return(FALSE);
113      }
114    NtCurrentTeb()->TlsSlots[dwTlsIndex] = lpTlsValue;
115    return(TRUE);
116 }
117
118 /* EOF */