55#ifndef ROOT_ThreadLocalStorage
56#define ROOT_ThreadLocalStorage
66#include "RConfigure.h"
69# if defined(__clang__) && defined(MAC_OS_X_VERSION_10_7) && (defined(__x86_64__) || defined(__i386__))
70# define R__HAS___THREAD
71# elif !defined(R__HAS_PTHREAD)
72# define R__HAS_PTHREAD
75#if defined(R__LINUX) || defined(R__AIX)
76# define R__HAS___THREAD
78#if defined(R__SOLARIS) && !defined(R__HAS_PTHREAD)
79# define R__HAS_PTHREAD
82# define R__HAS_DECLSPEC_THREAD
85#if __cplusplus >= 201103L
88# if defined(__clang__)
90# if __has_feature(cxx_thread_local)
95# define R__HAS_THREAD_LOCAL
97# define R__HAS___THREAD
100# elif defined(__INTEL_COMPILER)
101# define R__HAS__THREAD
103# elif defined(__GNUG__) && (__GNUC__ <= 4 && __GNUC_MINOR__ < 8)
105# define R__HAS___THREAD
107# define R__HAS_THREAD_LOCAL
120# define TTHREAD_TLS(type) static type
121# define TTHREAD_TLS_ARRAY(type,size,name) static type name[size]
122# define TTHREAD_TLS_PTR(name) &name
124#elif defined(R__HAS_THREAD_LOCAL)
126# define TTHREAD_TLS(type) thread_local type
127# define TTHREAD_TLS_ARRAY(type,size,name) thread_local type name[size]
128# define TTHREAD_TLS_PTR(name) &name
130# define TTHREAD_TLS_DECL(type, name) thread_local type name
131# define TTHREAD_TLS_DECL_ARG(type, name, arg) thread_local type name(arg)
132# define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) thread_local type name(arg1,arg2)
134#elif defined(R__HAS___THREAD)
136# define TTHREAD_TLS(type) static __thread type
137# define TTHREAD_TLS_ARRAY(type,size,name) static __thread type name[size]
138# define TTHREAD_TLS_PTR(name) &name
140#elif defined(R__HAS_DECLSPEC_THREAD)
142# define TTHREAD_TLS(type) static __declspec(thread) type
143# define TTHREAD_TLS_ARRAY(type,size,name) static __declspec(thread) type name[size]
144# define TTHREAD_TLS_PTR(name) &name
146#elif defined(R__HAS_PTHREAD)
151template <
typename type>
class TThreadTLSWrapper
157 static void key_delete(
void *arg) {
158 assert (NULL != arg);
164 TThreadTLSWrapper() : fInitValue() {
166 pthread_key_create(&(fKey), key_delete);
169 TThreadTLSWrapper(
const type &value) : fInitValue(value) {
171 pthread_key_create(&(fKey), key_delete);
174 ~TThreadTLSWrapper() {
175 pthread_key_delete(fKey);
179 void *ptr = pthread_getspecific(fKey);
181 ptr =
new type(fInitValue);
182 assert (NULL != ptr);
183 (
void) pthread_setspecific(fKey, ptr);
200template <
typename type,
int size>
class TThreadTLSArrayWrapper
205 static void key_delete(
void *arg) {
206 assert (NULL != arg);
207 delete [] (
type*)(arg);
212 TThreadTLSArrayWrapper() {
214 pthread_key_create(&(fKey), key_delete);
217 ~TThreadTLSArrayWrapper() {
218 pthread_key_delete(fKey);
222 void *ptr = pthread_getspecific(fKey);
224 ptr =
new type[size];
225 assert (NULL != ptr);
226 (
void) pthread_setspecific(fKey, ptr);
243# define TTHREAD_TLS(type) static TThreadTLSWrapper<type>
244# define TTHREAD_TLS_ARRAY(type,size,name) static TThreadTLSArrayWrapper<type,size> name;
245# define TTHREAD_TLS_PTR(name) &(name.get())
246# define TTHREAD_TLS_OBJ(index,type,name) type &name( TTHREAD_TLS_INIT<index,type>() )
250#error "No Thread Local Storage (TLS) technology for this platform specified."
260#define TTHREAD_TLS_DECL_IMPL(type, name, ptr, arg) \
261 TTHREAD_TLS(type *) ptr = 0; \
262 if (!ptr) ptr = new type(arg); \
265#define TTHREAD_TLS_DECL_IMPL2(type, name, ptr, arg1, arg2) \
266 TTHREAD_TLS(type *) ptr = 0; \
267 if (!ptr) ptr = new type(arg1,arg2); \
270#ifndef TTHREAD_TLS_DECL
272#define TTHREAD_TLS_DECL(type, name) \
273 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),)
275#define TTHREAD_TLS_DECL_ARG(type, name, arg) \
276 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),arg)
278#define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) \
279 TTHREAD_TLS_DECL_IMPL2(type,name,_R__JOIN_(ptr,__LINE__),arg1,arg2)
283template <
int marker,
typename T>
284T &TTHREAD_TLS_INIT() {
285 TTHREAD_TLS(
T*) ptr = NULL;
294template <
int marker,
typename Array,
typename T>
295Array &TTHREAD_TLS_INIT_ARRAY() {
296 TTHREAD_TLS(
Array*) ptr = NULL;
305template <
int marker,
typename T,
typename ArgType>
306T &TTHREAD_TLS_INIT(ArgType arg) {
307 TTHREAD_TLS(
T*) ptr = NULL;
318#if defined(R__HAS_THREAD_LOCAL)
320# define TTHREAD_TLS_DECLARE(type,name)
321# define TTHREAD_TLS_INIT(type,name,value) thread_local type name = (value)
322# define TTHREAD_TLS_SET(type,name,value) name = (value)
323# define TTHREAD_TLS_GET(type,name) (name)
324# define TTHREAD_TLS_FREE(name)
326#elif defined(R__HAS___THREAD)
328# define TTHREAD_TLS_DECLARE(type,name)
329# define TTHREAD_TLS_INIT(type,name,value) static __thread type name = (value)
330# define TTHREAD_TLS_SET(type,name,value) name = (value)
331# define TTHREAD_TLS_GET(type,name) (name)
332# define TTHREAD_TLS_FREE(name)
334#elif defined(R__HAS_DECLSPEC_THREAD)
336# define TTHREAD_TLS_DECLARE(type,name)
337# define TTHREAD_TLS_INIT(type,name,value) static __declspec(thread) type name = (value)
338# define TTHREAD_TLS_SET(type,name,value) name = (value)
339# define TTHREAD_TLS_GET(type,name) (name)
340# define TTHREAD_TLS_FREE(name)
342#elif defined(R__HAS_PTHREAD)
347# define TTHREAD_TLS_DECLARE(type,name) \
348 static pthread_key_t _##name##_key; \
349 static void _##name##_key_delete(void * arg) \
351 assert (NULL != arg); \
354 static void _##name##_key_create(void) \
357 _ret = pthread_key_create(&(_##name##_key), _##name##_key_delete); \
359 assert (0 == _ret); \
361 static pthread_once_t _##name##_once = PTHREAD_ONCE_INIT;
363# define TTHREAD_TLS_INIT(type,name,value) \
366 (void) pthread_once(&(_##name##_once), _##name##_key_create); \
367 if ((_ptr = pthread_getspecific(_##name##_key)) == NULL) { \
368 _ptr = malloc(sizeof(type)); \
369 assert (NULL != _ptr); \
370 (void) pthread_setspecific(_##name##_key, _ptr); \
371 *((type*)_ptr) = (value); \
375# define TTHREAD_TLS_SET(type,name,value) \
377 void *_ptr = pthread_getspecific(_##name##_key); \
378 assert (NULL != _ptr); \
379 *((type*)_ptr) = (value); \
382# define TTHREAD_TLS_GET(type,name) \
383 *((type*)pthread_getspecific(_##name##_key))
385# define TTHREAD_TLS_FREE(name) \
386 pthread_key_delete(_##name##_key);
390#error "No Thread Local Storage (TLS) technology for this platform specified."
Binding & operator=(OUT(*fun)(void))
typedef void((*Func_t)())