ReactOS  0.4.14-dev-831-gef8c9239
threadSafeInit.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS CRT library
3  * LICENSE: CC0-1.0 (https://spdx.org/licenses/CC0-1.0)
4  * PURPOSE: Thread safe initialization support routines for MSVC and Clang-CL
5  * COPYRIGHT: Copyright 2019 Timo Kreuzer (timo.kreuzer@reactos.org)
6  */
7 
8 #include <intrin.h>
9 
10 int _stdcall SwitchToThread(void);
11 
12 unsigned int _tls_array;
13 unsigned int _tls_index;
16 
17 /*
18  This function tries to acquire a lock on the initialization for the static
19  variable by changing the value saved in *ptss to -1. If *ptss is 0, the
20  variable was not initialized yet and the function tries to set it to -1.
21  If that succeeds, the function will return. If the value is already -1,
22  another thread is in the process of doing the initialization and we
23  wait for it. If it is any other value the initialization is complete.
24  After returning the compiler generated code will check the value:
25  if it is -1 it will continue with the initialization, otherwise the
26  initialization must be complete and will be skipped.
27 */
28 void
29 _Init_thread_header(volatile int* ptss)
30 {
31  while (1)
32  {
33  /* Try to acquire the first initialization lock */
34  int oldTss = _InterlockedCompareExchange((long*)ptss, -1, 0);
35  if (oldTss == -1)
36  {
37  /* Busy, wait for the other thread to do the initialization */
39  continue;
40  }
41 
42  /* Either we acquired the lock and the caller will do the initializaion
43  or the initialization is complete and the caller will skip it */
44  break;
45  }
46 }
47 
48 void
49 _Init_thread_footer(volatile int* ptss)
50 {
51  /* Initialization is complete */
53 }
54 
55 void
56 _Init_thread_abort(volatile int* ptss)
57 {
58  /* Abort the initialization */
59  _InterlockedAnd((volatile long*)ptss, 0);
60 }
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
void _Init_thread_footer(volatile int *ptss)
unsigned int _tls_index
int _stdcall SwitchToThread(void)
Definition: thread.c:447
unsigned int _tls_array
long __cdecl _InterlockedIncrement(_Interlocked_operand_ long volatile *_Addend)
volatile char *const const char modify _InterlockedAnd
Definition: intrin_ppc.h:267
long _Init_thread_epoch
long _Init_global_epoch
void _Init_thread_abort(volatile int *ptss)
void _Init_thread_header(volatile int *ptss)