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
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
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)
106#define TTHREAD_TLS_DECL_IMPL(type, name, ptr, arg) \
107 TTHREAD_TLS(type *) ptr = 0; \
108 if (!ptr) ptr = new type(arg); \
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); \
116#ifndef TTHREAD_TLS_DECL
118#define TTHREAD_TLS_DECL(type, name) \
119 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),)
121#define TTHREAD_TLS_DECL_ARG(type, name, arg) \
122 TTHREAD_TLS_DECL_IMPL(type,name,_R__JOIN_(ptr,__LINE__),arg)
124#define TTHREAD_TLS_DECL_ARG2(type, name, arg1, arg2) \
125 TTHREAD_TLS_DECL_IMPL2(type,name,_R__JOIN_(ptr,__LINE__),arg1,arg2)
129template <
int marker,
typename T>
130T &TTHREAD_TLS_INIT() {
131 TTHREAD_TLS(T*) ptr = NULL;
140template <
int marker,
typename Array,
typename T>
141Array &TTHREAD_TLS_INIT_ARRAY() {
142 TTHREAD_TLS(Array*) ptr = NULL;
151template <
int marker,
typename T,
typename ArgType>
152T &TTHREAD_TLS_INIT(ArgType arg) {
153 TTHREAD_TLS(T*) ptr = NULL;
168#if defined(R__HAS___THREAD)
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)
176#elif defined(R__HAS_DECLSPEC_THREAD)
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)
184#elif defined(R__HAS_PTHREAD)
189# define TTHREAD_TLS_DECLARE(type,name) \
190 static pthread_key_t _##name##_key; \
191 static void _##name##_key_delete(void * arg) \
193 assert (NULL != arg); \
196 static void _##name##_key_create(void) \
199 _ret = pthread_key_create(&(_##name##_key), _##name##_key_delete); \
201 assert (0 == _ret); \
203 static pthread_once_t _##name##_once = PTHREAD_ONCE_INIT;
205# define TTHREAD_TLS_INIT(type,name,value) \
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); \
217# define TTHREAD_TLS_SET(type,name,value) \
219 void *_ptr = pthread_getspecific(_##name##_key); \
220 assert (NULL != _ptr); \
221 *((type*)_ptr) = (value); \
224# define TTHREAD_TLS_GET(type,name) \
225 *((type*)pthread_getspecific(_##name##_key))
227# define TTHREAD_TLS_FREE(name) \
228 pthread_key_delete(_##name##_key);
232#error "No Thread Local Storage (TLS) technology for this platform specified."