:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[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 <ddk/ntddk.h>
16 #include <ntdll/rtl.h>
17 #include <windows.h>
18 #include <kernel32/thread.h>
19 #include <kernel32/error.h>
20
21 #define NDEBUG
22 #include <kernel32/kernel32.h>
23
24
25 /* FUNCTIONS *****************************************************************/
26
27 DWORD STDCALL 
28 TlsAlloc(VOID)
29 {
30    ULONG Index;
31
32    RtlAcquirePebLock();
33    Index = RtlFindClearBitsAndSet (NtCurrentPeb()->TlsBitmap, 1, 0);
34    if (Index == (ULONG)-1)
35      {
36        SetLastErrorByStatus(STATUS_NO_MEMORY);
37      }
38    else
39      {
40        NtCurrentTeb()->TlsSlots[Index] = 0;
41      }
42    RtlReleasePebLock();
43    
44    return(Index);
45 }
46
47 WINBOOL STDCALL 
48 TlsFree(DWORD dwTlsIndex)
49 {
50    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
51      {
52         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
53         return(FALSE);
54      }
55
56    RtlAcquirePebLock();
57    if (RtlAreBitsSet(NtCurrentPeb()->TlsBitmap, dwTlsIndex, 1))
58      {
59         /*
60          * clear the tls cells (slots) in all threads
61          * of the current process
62          */
63         NtSetInformationThread(NtCurrentThread(),
64                                ThreadZeroTlsCell,
65                                &dwTlsIndex,
66                                sizeof(DWORD));
67         RtlClearBits(NtCurrentPeb()->TlsBitmap,
68                      dwTlsIndex,
69                      1);
70      }
71    RtlReleasePebLock();
72
73    return(TRUE);
74 }
75
76 LPVOID STDCALL 
77 TlsGetValue(DWORD dwTlsIndex)
78 {
79    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
80      {
81         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
82         return(NULL);
83      }
84    return(NtCurrentTeb()->TlsSlots[dwTlsIndex]);
85 }
86
87 WINBOOL STDCALL 
88 TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue)
89 {
90    if (dwTlsIndex >= TLS_MINIMUM_AVAILABLE)
91      {
92         SetLastErrorByStatus(STATUS_INVALID_PARAMETER);
93         return(FALSE);
94      }
95    NtCurrentTeb()->TlsSlots[dwTlsIndex] = lpTlsValue;
96    return(TRUE);
97 }
98
99 /* EOF */