55 #ifndef ROOT_ThreadLocalStorage 56 #define ROOT_ThreadLocalStorage 68 #ifndef ROOT_RConfigure 69 #include "RConfigure.h" 72 #if defined(R__MACOSX) 73 # if defined(__clang__) && defined(MAC_OS_X_VERSION_10_7) && (defined(__x86_64__) || defined(__i386__)) 74 # define R__HAS___THREAD 75 # elif !defined(R__HAS_PTHREAD) 76 # define R__HAS_PTHREAD 79 #if defined(R__LINUX) || defined(R__AIX) 80 # define R__HAS___THREAD 82 #if defined(R__SOLARIS) && !defined(R__HAS_PTHREAD) 83 # define R__HAS_PTHREAD 86 # define R__HAS_DECLSPEC_THREAD 89 #if __cplusplus >= 201103L 92 # if defined(__clang__) 94 # if __has_feature(cxx_thread_local) 99 # define R__HAS_THREAD_LOCAL 101 # define R__HAS___THREAD 104 # elif defined(__INTEL_COMPILER) 105 # define R__HAS__THREAD 107 # elif defined(__GNUG__) && (__GNUC__ <= 4 && __GNUC_MINOR__ < 8) 109 # define R__HAS___THREAD 111 # define R__HAS_THREAD_LOCAL 124 # define TTHREAD_TLS(type) static type 125 # define TTHREAD_TLS_ARRAY(type,size,name) static type name[size] 126 # define TTHREAD_TLS_PTR(name) &name 128 #elif defined(R__HAS_THREAD_LOCAL) 130 # define TTHREAD_TLS(type) thread_local type 131 # define TTHREAD_TLS_ARRAY(type,size,name) thread_local type name[size] 132 # define TTHREAD_TLS_PTR(name) &name 134 # define TTHREAD_TLS_DECL(type, name) thread_local type name 135 # define TTHREAD_TLS_DECL_ARG(type, name, arg) thread_local type name(arg) 136 # define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) thread_local type name(arg1,arg2) 138 #elif defined(R__HAS___THREAD) 140 # define TTHREAD_TLS(type) static __thread type 141 # define TTHREAD_TLS_ARRAY(type,size,name) static __thread type name[size] 142 # define TTHREAD_TLS_PTR(name) &name 144 #elif defined(R__HAS_DECLSPEC_THREAD) 146 # define TTHREAD_TLS(type) static __declspec(thread) type 147 # define TTHREAD_TLS_ARRAY(type,size,name) static __declspec(thread) type name[size] 148 # define TTHREAD_TLS_PTR(name) &name 150 #elif defined(R__HAS_PTHREAD) 155 template <
typename type>
class TThreadTLSWrapper
161 static void key_delete(
void *arg) {
162 assert (
NULL != arg);
168 TThreadTLSWrapper() : fInitValue() {
170 pthread_key_create(&(fKey), key_delete);
173 TThreadTLSWrapper(
const type &value) : fInitValue(value) {
175 pthread_key_create(&(fKey), key_delete);
178 ~TThreadTLSWrapper() {
179 pthread_key_delete(fKey);
183 void *ptr = pthread_getspecific(fKey);
185 ptr =
new type(fInitValue);
186 assert (
NULL != ptr);
187 (
void) pthread_setspecific(fKey, ptr);
204 template <
typename type,
int size>
class TThreadTLSArrayWrapper
209 static void key_delete(
void *arg) {
210 assert (
NULL != arg);
211 delete [] (
type*)(arg);
216 TThreadTLSArrayWrapper() {
218 pthread_key_create(&(fKey), key_delete);
221 ~TThreadTLSArrayWrapper() {
222 pthread_key_delete(fKey);
226 void *ptr = pthread_getspecific(fKey);
228 ptr =
new type[size];
229 assert (
NULL != ptr);
230 (
void) pthread_setspecific(fKey, ptr);
247 # define TTHREAD_TLS(type) static TThreadTLSWrapper<type> 248 # define TTHREAD_TLS_ARRAY(type,size,name) static TThreadTLSArrayWrapper<type,size> name; 249 # define TTHREAD_TLS_PTR(name) &(name.get()) 250 # define TTHREAD_TLS_OBJ(index,type,name) type &name( TTHREAD_TLS_INIT<index,type>() ) 254 #error "No Thread Local Storage (TLS) technology for this platform specified." 264 #define TTHREAD_TLS_DECL_IMPL(type, name, ptr, arg) \ 265 TTHREAD_TLS(type *) ptr = 0; \ 266 if (!ptr) ptr = new type(arg); \ 269 #define TTHREAD_TLS_DECL_IMPL2(type, name, ptr, arg1, arg2) \ 270 TTHREAD_TLS(type *) ptr = 0; \ 271 if (!ptr) ptr = new type(arg1,arg2); \ 274 #ifndef TTHREAD_TLS_DECL 276 #define TTHREAD_TLS_DECL(type, name) \ 277 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),) 279 #define TTHREAD_TLS_DECL_ARG(type, name, arg) \ 280 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),arg) 282 #define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) \ 283 TTHREAD_TLS_DECL_IMPL2(type,name,_R__JOIN_(ptr,__LINE__),arg1,arg2) 287 template <
int marker,
typename T>
288 T &TTHREAD_TLS_INIT() {
289 TTHREAD_TLS(
T*) ptr =
NULL;
298 template <
int marker,
typename Array,
typename T>
299 Array &TTHREAD_TLS_INIT_ARRAY() {
309 template <
int marker,
typename T,
typename ArgType>
310 T &TTHREAD_TLS_INIT(ArgType arg) {
311 TTHREAD_TLS(
T*) ptr =
NULL;
322 #if defined(R__HAS_THREAD_LOCAL) 324 # define TTHREAD_TLS_DECLARE(type,name) 325 # define TTHREAD_TLS_INIT(type,name,value) thread_local type name = (value) 326 # define TTHREAD_TLS_SET(type,name,value) name = (value) 327 # define TTHREAD_TLS_GET(type,name) (name) 328 # define TTHREAD_TLS_FREE(name) 330 #elif defined(R__HAS___THREAD) 332 # define TTHREAD_TLS_DECLARE(type,name) 333 # define TTHREAD_TLS_INIT(type,name,value) static __thread type name = (value) 334 # define TTHREAD_TLS_SET(type,name,value) name = (value) 335 # define TTHREAD_TLS_GET(type,name) (name) 336 # define TTHREAD_TLS_FREE(name) 338 #elif defined(R__HAS_DECLSPEC_THREAD) 340 # define TTHREAD_TLS_DECLARE(type,name) 341 # define TTHREAD_TLS_INIT(type,name,value) static __declspec(thread) type name = (value) 342 # define TTHREAD_TLS_SET(type,name,value) name = (value) 343 # define TTHREAD_TLS_GET(type,name) (name) 344 # define TTHREAD_TLS_FREE(name) 346 #elif defined(R__HAS_PTHREAD) 351 # define TTHREAD_TLS_DECLARE(type,name) \ 352 static pthread_key_t _##name##_key; \ 353 static void _##name##_key_delete(void * arg) \ 355 assert (NULL != arg); \ 358 static void _##name##_key_create(void) \ 361 _ret = pthread_key_create(&(_##name##_key), _##name##_key_delete); \ 363 assert (0 == _ret); \ 365 static pthread_once_t _##name##_once = PTHREAD_ONCE_INIT; 367 # define TTHREAD_TLS_INIT(type,name,value) \ 370 (void) pthread_once(&(_##name##_once), _##name##_key_create); \ 371 if ((_ptr = pthread_getspecific(_##name##_key)) == NULL) { \ 372 _ptr = malloc(sizeof(type)); \ 373 assert (NULL != _ptr); \ 374 (void) pthread_setspecific(_##name##_key, _ptr); \ 375 *((type*)_ptr) = (value); \ 379 # define TTHREAD_TLS_SET(type,name,value) \ 381 void *_ptr = pthread_getspecific(_##name##_key); \ 382 assert (NULL != _ptr); \ 383 *((type*)_ptr) = (value); \ 386 # define TTHREAD_TLS_GET(type,name) \ 387 *((type*)pthread_getspecific(_##name##_key)) 389 # define TTHREAD_TLS_FREE(name) \ 390 pthread_key_delete(_##name##_key); 394 #error "No Thread Local Storage (TLS) technology for this platform specified." 398 #endif // __cplusplus
typedef void((*Func_t)())