54#ifndef ROOT_ThreadLocalStorage
55#define ROOT_ThreadLocalStorage
65#include "RConfigure.h"
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
74#if defined(R__LINUX) || defined(R__AIX)
75# define R__HAS___THREAD
77#if defined(R__SOLARIS) && !defined(R__HAS_PTHREAD)
78# define R__HAS_PTHREAD
81# define R__HAS_DECLSPEC_THREAD
84# define R__HAS_PTHREAD
94# define TTHREAD_TLS(type) static type
95# define TTHREAD_TLS_ARRAY(type,size,name) static type name[size]
96# define TTHREAD_TLS_PTR(name) &name
100# define TTHREAD_TLS(type) thread_local type
101# define TTHREAD_TLS_ARRAY(type,size,name) thread_local type name[size]
102# define TTHREAD_TLS_PTR(name) &name
104# define TTHREAD_TLS_DECL(type, name) thread_local type name
105# define TTHREAD_TLS_DECL_ARG(type, name, arg) thread_local type name(arg)
106# define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) thread_local type name(arg1,arg2)
116#define TTHREAD_TLS_DECL_IMPL(type, name, ptr, arg) \
117 TTHREAD_TLS(type *) ptr = 0; \
118 if (!ptr) ptr = new type(arg); \
121#define TTHREAD_TLS_DECL_IMPL2(type, name, ptr, arg1, arg2) \
122 TTHREAD_TLS(type *) ptr = 0; \
123 if (!ptr) ptr = new type(arg1,arg2); \
126#ifndef TTHREAD_TLS_DECL
128#define TTHREAD_TLS_DECL(type, name) \
129 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),)
131#define TTHREAD_TLS_DECL_ARG(type, name, arg) \
132 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),arg)
134#define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) \
135 TTHREAD_TLS_DECL_IMPL2(type,name,_R__JOIN_(ptr,__LINE__),arg1,arg2)
139template <
int marker,
typename T>
140T &TTHREAD_TLS_INIT() {
141 TTHREAD_TLS(T*) ptr = NULL;
150template <
int marker,
typename Array,
typename T>
151Array &TTHREAD_TLS_INIT_ARRAY() {
152 TTHREAD_TLS(Array*) ptr = NULL;
161template <
int marker,
typename T,
typename ArgType>
162T &TTHREAD_TLS_INIT(ArgType arg) {
163 TTHREAD_TLS(T*) ptr = NULL;
178#if defined(R__HAS___THREAD)
180# define TTHREAD_TLS_DECLARE(type,name)
181# define TTHREAD_TLS_INIT(type,name,value) static __thread type name = (value)
182# define TTHREAD_TLS_SET(type,name,value) name = (value)
183# define TTHREAD_TLS_GET(type,name) (name)
184# define TTHREAD_TLS_FREE(name)
186#elif defined(R__HAS_DECLSPEC_THREAD)
188# define TTHREAD_TLS_DECLARE(type,name)
189# define TTHREAD_TLS_INIT(type,name,value) static __declspec(thread) type name = (value)
190# define TTHREAD_TLS_SET(type,name,value) name = (value)
191# define TTHREAD_TLS_GET(type,name) (name)
192# define TTHREAD_TLS_FREE(name)
194#elif defined(R__HAS_PTHREAD)
199# define TTHREAD_TLS_DECLARE(type,name) \
200 static pthread_key_t _##name##_key; \
201 static void _##name##_key_delete(void * arg) \
203 assert (NULL != arg); \
206 static void _##name##_key_create(void) \
209 _ret = pthread_key_create(&(_##name##_key), _##name##_key_delete); \
211 assert (0 == _ret); \
213 static pthread_once_t _##name##_once = PTHREAD_ONCE_INIT;
215# define TTHREAD_TLS_INIT(type,name,value) \
218 (void) pthread_once(&(_##name##_once), _##name##_key_create); \
219 if ((_ptr = pthread_getspecific(_##name##_key)) == NULL) { \
220 _ptr = malloc(sizeof(type)); \
221 assert (NULL != _ptr); \
222 (void) pthread_setspecific(_##name##_key, _ptr); \
223 *((type*)_ptr) = (value); \
227# define TTHREAD_TLS_SET(type,name,value) \
229 void *_ptr = pthread_getspecific(_##name##_key); \
230 assert (NULL != _ptr); \
231 *((type*)_ptr) = (value); \
234# define TTHREAD_TLS_GET(type,name) \
235 *((type*)pthread_getspecific(_##name##_key))
237# define TTHREAD_TLS_FREE(name) \
238 pthread_key_delete(_##name##_key);
242#error "No Thread Local Storage (TLS) technology for this platform specified."