ROOT
Version v6.32
master
v6.34
v6.32
v6.30
v6.28
v6.26
v6.24
v6.22
v6.20
v6.18
v6.16
v6.14
v6.12
v6.10
v6.08
v6.06
v6.04
Reference Guide
▼
ROOT
ROOT Reference Documentation
Tutorials
►
Functional Parts
►
Namespaces
►
All Classes
▼
Files
▼
File List
►
bindings
▼
core
►
base
►
clingutils
►
cont
►
dictgen
▼
foundation
▼
inc
►
ROOT
►
DllImport.h
►
ESTLType.h
RStringView.h
Rstrstream.h
►
RtypesCore.h
►
RVersion.h
►
TClassEdit.h
►
TError.h
ThreadLocalStorage.h
►
res
►
src
►
v7
►
gui
►
imt
►
macosx
►
meta
►
metacling
►
multiproc
►
rint
►
testsupport
►
thread
►
unix
►
winnt
►
zip
►
documentation
►
geom
►
graf2d
►
graf3d
►
gui
►
hist
►
html
►
io
►
main
►
math
►
montecarlo
►
net
►
proof
►
roofit
►
sql
►
tmva
►
tree
►
tutorials
►
v6-32-00-patches
►
File Members
Release Notes
•
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Properties
Friends
Macros
Modules
Pages
Loading...
Searching...
No Matches
ThreadLocalStorage.h
Go to the documentation of this file.
1
// @(#)root/thread:$Id$
2
/*
3
* Copyright (c) 2006-2011 High Performance Computing Center Stuttgart,
4
* University of Stuttgart. All rights reserved.
5
* Author: Rainer Keller, HLRS
6
* Modified: Fons Rademakers, CERN
7
* Modified: Philippe Canal, FNAL
8
*
9
* Thread-local storage (TLS) is not supported on all environments.
10
* This header file and test-program shows how to abstract away, using either
11
* __thread,
12
* __declspec(thread),
13
* thread_local or
14
* Pthread-Keys
15
* depending on the (configure-set) CPP-variables R__HAS___THREAD,
16
* R__HAS_DECLSPEC_THREAD or R__HAS_PTHREAD.
17
*
18
* Use the macros TTHREAD_TLS_DECLARE, TTHREAD_TLS_INIT, and the
19
* getters and setters TTHREAD_TLS_GET and TTHREAD_TLS_GET
20
* to work on the declared variables.
21
*
22
* In case of PThread keys, we need to resolve to using keys!
23
* In order to do so, we need to declare and access
24
* TLS variables through three macros:
25
* - TTHREAD_TLS_DECLARE
26
* - TTHREAD_TLS_INIT
27
* - TTHREAD_TLS_SET and
28
* - TTHREAD_TLS_GET
29
* We do depend on the following (GCC-)extension:
30
* - In case of function-local static functions,
31
* we declare a sub-function to create a specific key.
32
* Unfortunately, we do NOT use the following extensions:
33
* - Using typeof, we could get rid of the type-declaration
34
* which is used for casting, however typeof is not ANSI C.
35
* - We do NOT allow something like
36
* func (a, TTHREAD_TLS_SET(int, my_var, 5));
37
* as we do not use the gcc-extension of returning macro-values.
38
*
39
* C++11 requires the implementation of the thread_local storage.
40
*
41
* For simple type use:
42
* TTHREAD_TLS(int) varname;
43
*
44
* For array of simple type use:
45
* TTHREAD_TLS_ARRAY(int, arraysize, varname);
46
*
47
* For object use:
48
* TTHREAD_TLS_DECL(classname, varname);
49
* TTHREAD_TLS_DECL_ARG(classname, varname, arg);
50
* TTHREAD_TLS_DECL_ARG2(classname, varname, arg1, arg2);
51
*
52
*/
53
54
#ifndef ROOT_ThreadLocalStorage
55
#define ROOT_ThreadLocalStorage
56
57
#include <stddef.h>
58
59
#ifdef __cplusplus
60
#include "
RtypesCore.h
"
61
#endif
62
63
#include <
ROOT/RConfig.hxx
>
64
65
#include "RConfigure.h"
66
67
#if defined(R__MACOSX)
68
# if defined(__clang__) && defined(MAC_OS_X_VERSION_10_7) && (defined(__x86_64__) || defined(__i386__))
69
# define R__HAS___THREAD
70
# elif !defined(R__HAS_PTHREAD)
71
# define R__HAS_PTHREAD
72
# endif
73
#endif
74
#if defined(R__LINUX) || defined(R__AIX)
75
# define R__HAS___THREAD
76
#endif
77
#if defined(R__SOLARIS) && !defined(R__HAS_PTHREAD)
78
# define R__HAS_PTHREAD
79
#endif
80
#if defined(R__WIN32)
81
# define R__HAS_DECLSPEC_THREAD
82
#endif
83
#if defined(R__FBSD)
84
# define R__HAS_PTHREAD
85
#endif
86
87
#ifdef __cplusplus
88
89
// Note that the order is relevant, more than one of the flag might be
90
// on at the same time and we want to use 'best' option available.
91
92
# define TTHREAD_TLS(type) thread_local type
93
# define TTHREAD_TLS_ARRAY(type,size,name) thread_local type name[size]
94
# define TTHREAD_TLS_PTR(name) &name
95
96
# define TTHREAD_TLS_DECL(type, name) thread_local type name
97
# define TTHREAD_TLS_DECL_ARG(type, name, arg) thread_local type name(arg)
98
# define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) thread_local type name(arg1,arg2)
99
100
// Available on all platforms
101
102
103
// Neither TTHREAD_TLS_DECL_IMPL and TTHREAD_TLS_INIT
104
// do not delete the object at the end of the process.
105
106
#define TTHREAD_TLS_DECL_IMPL(type, name, ptr, arg) \
107
TTHREAD_TLS(type *) ptr = 0; \
108
if (!ptr) ptr = new type(arg); \
109
type &name = *ptr;
110
111
#define TTHREAD_TLS_DECL_IMPL2(type, name, ptr, arg1, arg2) \
112
TTHREAD_TLS(type *) ptr = 0; \
113
if (!ptr) ptr = new type(arg1,arg2); \
114
type &name = *ptr;
115
116
#ifndef TTHREAD_TLS_DECL
117
118
#define TTHREAD_TLS_DECL(type, name) \
119
TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),)
120
121
#define TTHREAD_TLS_DECL_ARG(type, name, arg) \
122
TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),arg)
123
124
#define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) \
125
TTHREAD_TLS_DECL_IMPL2(type,name,_R__JOIN_(ptr,__LINE__),arg1,arg2)
126
127
#endif
128
129
template
<
int
marker,
typename
T>
130
T &
TTHREAD_TLS_INIT
() {
131
TTHREAD_TLS
(T*) ptr =
NULL
;
132
TTHREAD_TLS
(
Bool_t
)
isInit
(
kFALSE
);
133
if
(!
isInit
) {
134
ptr =
new
T;
135
isInit
=
kTRUE
;
136
}
137
return
*ptr;
138
}
139
140
template
<
int
marker,
typename
Array,
typename
T>
141
Array
&
TTHREAD_TLS_INIT_ARRAY
() {
142
TTHREAD_TLS
(Array*) ptr =
NULL
;
143
TTHREAD_TLS
(
Bool_t
)
isInit
(
kFALSE
);
144
if
(!
isInit
) {
145
ptr =
new
Array
[
sizeof
(
Array
)/
sizeof
(T)];
146
isInit
=
kTRUE
;
147
}
148
return
*ptr;
149
}
150
151
template
<
int
marker,
typename
T,
typename
ArgType>
152
T &
TTHREAD_TLS_INIT
(
ArgType
arg) {
153
TTHREAD_TLS
(T*) ptr =
NULL
;
154
TTHREAD_TLS
(
Bool_t
)
isInit
(
kFALSE
);
155
if
(!
isInit
) {
156
ptr =
new
T(arg);
157
isInit
=
kTRUE
;
158
}
159
return
*ptr;
160
}
161
162
#else
// __cplusplus
163
164
// TODO: Evaluate using thread_local / _Thread_local from C11 instead of
165
// platform-specific solutions such as __thread, __declspec(thread) or the
166
// pthreads API functions.
167
168
#if defined(R__HAS___THREAD)
169
170
# define TTHREAD_TLS_DECLARE(type,name)
171
# define TTHREAD_TLS_INIT(type,name,value) static __thread type name = (value)
172
# define TTHREAD_TLS_SET(type,name,value) name = (value)
173
# define TTHREAD_TLS_GET(type,name) (name)
174
# define TTHREAD_TLS_FREE(name)
175
176
#elif defined(R__HAS_DECLSPEC_THREAD)
177
178
# define TTHREAD_TLS_DECLARE(type,name)
179
# define TTHREAD_TLS_INIT(type,name,value) static __declspec(thread) type name = (value)
180
# define TTHREAD_TLS_SET(type,name,value) name = (value)
181
# define TTHREAD_TLS_GET(type,name) (name)
182
# define TTHREAD_TLS_FREE(name)
183
184
#elif defined(R__HAS_PTHREAD)
185
186
#include <assert.h>
187
#include <pthread.h>
188
189
# define TTHREAD_TLS_DECLARE(type,name) \
190
static pthread_key_t _##name##_key; \
191
static void _##name##_key_delete(void * arg) \
192
{ \
193
assert (NULL != arg); \
194
free(arg); \
195
} \
196
static void _##name##_key_create(void) \
197
{ \
198
int _ret; \
199
_ret = pthread_key_create(&(_##name##_key), _##name##_key_delete); \
200
_ret = _ret;
/* To get rid of warnings in case of NDEBUG */
\
201
assert (0 == _ret); \
202
} \
203
static pthread_once_t _##name##_once = PTHREAD_ONCE_INIT;
204
205
# define TTHREAD_TLS_INIT(type,name,value) \
206
do { \
207
void *_ptr; \
208
(void) pthread_once(&(_##name##_once), _##name##_key_create); \
209
if ((_ptr = pthread_getspecific(_##name##_key)) == NULL) { \
210
_ptr = malloc(sizeof(type)); \
211
assert (NULL != _ptr); \
212
(void) pthread_setspecific(_##name##_key, _ptr); \
213
*((type*)_ptr) = (value); \
214
} \
215
} while (0)
216
217
# define TTHREAD_TLS_SET(type,name,value) \
218
do { \
219
void *_ptr = pthread_getspecific(_##name##_key); \
220
assert (NULL != _ptr); \
221
*((type*)_ptr) = (value); \
222
} while (0)
223
224
# define TTHREAD_TLS_GET(type,name) \
225
*((type*)pthread_getspecific(_##name##_key))
226
227
# define TTHREAD_TLS_FREE(name) \
228
pthread_key_delete(_##name##_key);
229
230
#else
231
232
#error "No Thread Local Storage (TLS) technology for this platform specified."
233
234
#endif
235
236
#endif
// __cplusplus
237
238
#endif
239
RConfig.hxx
RtypesCore.h
Bool_t
bool Bool_t
Definition
RtypesCore.h:63
kFALSE
constexpr Bool_t kFALSE
Definition
RtypesCore.h:101
kTRUE
constexpr Bool_t kTRUE
Definition
RtypesCore.h:100
TRangeDynCast
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Definition
TCollection.h:358
ROOT::Detail::TRangeCast
Definition
TCollection.h:311
sqlio::Array
const char * Array
Definition
TSQLStructure.cxx:68
core
foundation
inc
ThreadLocalStorage.h
ROOT v6-32 - Reference Guide Generated on Thu Mar 6 2025 14:28:25 (GVA Time) using Doxygen 1.10.0