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
13 /* INCLUDES ******************************************************************/
18 #include "../include/debug.h"
20 #define TLS_EXPANSION_SLOTS (8 * sizeof(((PPEB)NULL)->TlsExpansionBitmapBits))
22 /* FUNCTIONS *****************************************************************/
34 /* Try to get regular TEB slot. */
35 Index
= RtlFindClearBitsAndSet(NtCurrentPeb()->TlsBitmap
, 1, 0);
38 /* If it fails, try to find expansion TEB slot. */
39 Index
= RtlFindClearBitsAndSet(NtCurrentPeb()->TlsExpansionBitmap
, 1, 0);
42 if (NtCurrentTeb()->TlsExpansionSlots
== NULL
)
44 NtCurrentTeb()->TlsExpansionSlots
= HeapAlloc(
45 GetProcessHeap(), HEAP_ZERO_MEMORY
,
46 TLS_EXPANSION_SLOTS
* sizeof(PVOID
));
49 if (NtCurrentTeb()->TlsExpansionSlots
== NULL
)
51 RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap
, Index
, 1);
53 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
57 /* Clear the value. */
58 NtCurrentTeb()->TlsExpansionSlots
[Index
] = 0;
59 Index
+= TLS_MINIMUM_AVAILABLE
;
64 SetLastError(ERROR_NO_MORE_ITEMS
);
69 /* Clear the value. */
70 NtCurrentTeb()->TlsSlots
[Index
] = 0;
87 if (Index
>= TLS_EXPANSION_SLOTS
+ TLS_MINIMUM_AVAILABLE
)
89 SetLastErrorByStatus(STATUS_INVALID_PARAMETER
);
95 if (Index
>= TLS_MINIMUM_AVAILABLE
)
97 BitSet
= RtlAreBitsSet(NtCurrentPeb()->TlsExpansionBitmap
,
98 Index
- TLS_MINIMUM_AVAILABLE
, 1);
100 RtlClearBits(NtCurrentPeb()->TlsExpansionBitmap
,
101 Index
- TLS_MINIMUM_AVAILABLE
, 1);
105 BitSet
= RtlAreBitsSet(NtCurrentPeb()->TlsBitmap
, Index
, 1);
107 RtlClearBits(NtCurrentPeb()->TlsBitmap
, Index
, 1);
112 /* Clear the TLS cells (slots) in all threads of the current process. */
113 NtSetInformationThread(NtCurrentThread(), ThreadZeroTlsCell
,
114 &Index
, sizeof(DWORD
));
118 SetLastError(ERROR_INVALID_PARAMETER
);
131 TlsGetValue(DWORD Index
)
133 if (Index
>= TLS_EXPANSION_SLOTS
+ TLS_MINIMUM_AVAILABLE
)
135 SetLastErrorByStatus(STATUS_INVALID_PARAMETER
);
139 SetLastError(NO_ERROR
);
141 if (Index
>= TLS_MINIMUM_AVAILABLE
)
143 /* The expansion slots are allocated on demand, so check for it. */
144 if (NtCurrentTeb()->TlsExpansionSlots
== NULL
)
146 return NtCurrentTeb()->TlsExpansionSlots
[Index
- TLS_MINIMUM_AVAILABLE
];
150 return NtCurrentTeb()->TlsSlots
[Index
];
159 TlsSetValue(DWORD Index
, LPVOID Value
)
161 if (Index
>= TLS_EXPANSION_SLOTS
+ TLS_MINIMUM_AVAILABLE
)
163 SetLastErrorByStatus(STATUS_INVALID_PARAMETER
);
167 if (Index
>= TLS_MINIMUM_AVAILABLE
)
169 if (NtCurrentTeb()->TlsExpansionSlots
== NULL
)
171 NtCurrentTeb()->TlsExpansionSlots
= HeapAlloc(
172 GetProcessHeap(), HEAP_ZERO_MEMORY
,
173 TLS_EXPANSION_SLOTS
* sizeof(PVOID
));
175 if (NtCurrentTeb()->TlsExpansionSlots
== NULL
)
177 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
182 NtCurrentTeb()->TlsExpansionSlots
[Index
- TLS_MINIMUM_AVAILABLE
] = Value
;
186 NtCurrentTeb()->TlsSlots
[Index
] = Value
;