1 /********************* */
4 ** Original author: mdeters
5 ** Major contributors: none
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 prototype.
8 ** Copyright (c) 2009, 2010 The Analysis of Computer Systems Group (ACSys)
9 ** Courant Institute of Mathematical Sciences
10 ** New York University
11 ** See the file COPYING in the top-level source directory for licensing
12 ** information.\endverbatim
14 ** \brief Header to define CVC4_THREAD whether or not TLS is
15 ** supported by the compiler/runtime platform
17 ** Header to define CVC4_THREAD whether or not TLS is supported by
18 ** the compiler/runtime platform. If not, an implementation based on
19 ** pthread_getspecific() / pthread_setspecific() is given.
22 #include "cvc4_public.h"
27 #line 28 "@srcdir@/tls.h.in"
29 // A bit obnoxious: we have to take varargs to support multi-argument
30 // template types in the threadlocals.
31 // E.g. "CVC4_THREADLOCAL(hash_set<type, hasher>*)" fails otherwise,
32 // due to the embedded comma.
33 #if @CVC4_TLS_SUPPORTED@
34 # define CVC4_THREADLOCAL(__type...) @CVC4_TLS@ __type
35 # define CVC4_THREADLOCAL_PUBLIC(__type...) @CVC4_TLS@ CVC4_PUBLIC __type
36 # define CVC4_THREADLOCAL_TYPE(__type...) __type
39 # define CVC4_THREADLOCAL(__type...) ::CVC4::ThreadLocal< __type >
40 # define CVC4_THREADLOCAL_PUBLIC(__type...) CVC4_PUBLIC ::CVC4::ThreadLocal< __type >
41 # define CVC4_THREADLOCAL_TYPE(__type...) ::CVC4::ThreadLocal< __type >
45 template <class T
, bool small
>
46 class ThreadLocalImpl
;
49 class ThreadLocalImpl
<T
, true> {
52 static void cleanup(void*) {
57 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
60 ThreadLocalImpl(const T
& t
) {
61 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
62 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(t
)));
65 ThreadLocalImpl(const ThreadLocalImpl
& tl
) {
66 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
67 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T
&>(tl
))));
70 ThreadLocalImpl
& operator=(const T
& t
) {
71 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(t
)));
74 ThreadLocalImpl
& operator=(const ThreadLocalImpl
& tl
) {
75 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T
&>(tl
))));
80 return static_cast<T
>(reinterpret_cast<size_t>(pthread_getspecific(d_key
)));
82 };/* class ThreadLocalImpl<T, true> */
85 class ThreadLocalImpl
<T
*, true> {
88 static void cleanup(void*) {
93 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
96 ThreadLocalImpl(const T
* t
) {
97 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
98 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(t
)));
101 ThreadLocalImpl(const ThreadLocalImpl
& tl
) {
102 pthread_key_create(&d_key
, ThreadLocalImpl::cleanup
);
103 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T
*>(tl
))));
106 ThreadLocalImpl
& operator=(const T
* t
) {
107 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(t
)));
110 ThreadLocalImpl
& operator=(const ThreadLocalImpl
& tl
) {
111 pthread_setspecific(d_key
, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T
*>(tl
))));
115 operator T
*() const {
116 return static_cast<T
*>(pthread_getspecific(d_key
));
120 return *static_cast<T
*>(pthread_getspecific(d_key
));
123 return static_cast<T
*>(pthread_getspecific(d_key
));
125 };/* class ThreadLocalImpl<T*, true> */
128 class ThreadLocalImpl
<T
, false> {
129 };/* class ThreadLocalImpl<T, false> */
132 class ThreadLocal
: public ThreadLocalImpl
<T
, sizeof(T
) <= sizeof(void*)> {
133 typedef ThreadLocalImpl
<T
, sizeof(T
) <= sizeof(void*)> super
;
136 ThreadLocal() : super() {}
137 ThreadLocal(const T
& t
) : super(t
) {}
138 ThreadLocal(const ThreadLocal
<T
>& tl
) : super(tl
) {}
140 ThreadLocal
<T
>& operator=(const T
& t
) {
141 return static_cast< ThreadLocal
<T
>& >(super::operator=(t
));
143 ThreadLocal
<T
>& operator=(const ThreadLocal
<T
>& tl
) {
144 return static_cast< ThreadLocal
<T
>& >(super::operator=(tl
));
146 };/* class ThreadLocal<T> */
149 class ThreadLocal
<T
*> : public ThreadLocalImpl
<T
*, sizeof(T
*) <= sizeof(void*)> {
150 typedef ThreadLocalImpl
<T
*, sizeof(T
*) <= sizeof(void*)> super
;
153 ThreadLocal() : super() {}
154 ThreadLocal(T
* t
) : super(t
) {}
155 ThreadLocal(const ThreadLocal
<T
*>& tl
) : super(tl
) {}
157 ThreadLocal
<T
*>& operator=(T
* t
) {
158 return static_cast< ThreadLocal
<T
*>& >(super::operator=(t
));
160 ThreadLocal
<T
*>& operator=(const ThreadLocal
<T
*>& tl
) {
161 return static_cast< ThreadLocal
<T
*>& >(super::operator=(tl
));
163 // special operators for pointers
165 return *static_cast<T
*>(*this);
167 const T
& operator*() const {
168 return *static_cast<const T
*>(*this);
171 return static_cast<T
*>(*this);
173 const T
* operator->() const {
174 return static_cast<const T
*>(*this);
196 };/* class ThreadLocal<T*> */
198 }/* CVC4 namespace */
200 #endif /* @CVC4_TLS_SUPPORTED@ */
202 #endif /* _CVC4__TLS_H */