some fixes for Mac OS
[cvc5.git] / src / util / tls.h.in
1 /********************* */
2 /*! \file tls.h.in
3 ** \verbatim
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
13 **
14 ** \brief Header to define CVC4_THREAD whether or not TLS is
15 ** supported by the compiler/runtime platform
16 **
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.
20 **/
21
22 #include "cvc4_public.h"
23
24 #ifndef __CVC4__TLS_H
25 #define __CVC4__TLS_H
26
27 #line 28 "@srcdir@/tls.h.in"
28
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
37 #else
38 # include <pthread.h>
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 >
42
43 namespace CVC4 {
44
45 template <class T, bool small>
46 class ThreadLocalImpl;
47
48 template <class T>
49 class ThreadLocalImpl<T, true> {
50 pthread_key_t d_key;
51
52 static void cleanup(void*) {
53 }
54
55 public:
56 ThreadLocalImpl() {
57 pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
58 }
59
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)));
63 }
64
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))));
68 }
69
70 ThreadLocalImpl& operator=(const T& t) {
71 pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
72 return *this;
73 }
74 ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) {
75 pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T&>(tl))));
76 return *this;
77 }
78
79 operator T() const {
80 return static_cast<T>(reinterpret_cast<size_t>(pthread_getspecific(d_key)));
81 }
82 };/* class ThreadLocalImpl<T, true> */
83
84 template <class T>
85 class ThreadLocalImpl<T*, true> {
86 pthread_key_t d_key;
87
88 static void cleanup(void*) {
89 }
90
91 public:
92 ThreadLocalImpl() {
93 pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
94 }
95
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)));
99 }
100
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))));
104 }
105
106 ThreadLocalImpl& operator=(const T* t) {
107 pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
108 return *this;
109 }
110 ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) {
111 pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T*>(tl))));
112 return *this;
113 }
114
115 operator T*() const {
116 return static_cast<T*>(pthread_getspecific(d_key));
117 }
118
119 T operator*() {
120 return *static_cast<T*>(pthread_getspecific(d_key));
121 }
122 T* operator->() {
123 return static_cast<T*>(pthread_getspecific(d_key));
124 }
125 };/* class ThreadLocalImpl<T*, true> */
126
127 template <class T>
128 class ThreadLocalImpl<T, false> {
129 };/* class ThreadLocalImpl<T, false> */
130
131 template <class T>
132 class ThreadLocal : public ThreadLocalImpl<T, sizeof(T) <= sizeof(void*)> {
133 typedef ThreadLocalImpl<T, sizeof(T) <= sizeof(void*)> super;
134
135 public:
136 ThreadLocal() : super() {}
137 ThreadLocal(const T& t) : super(t) {}
138 ThreadLocal(const ThreadLocal<T>& tl) : super(tl) {}
139
140 ThreadLocal<T>& operator=(const T& t) {
141 return static_cast< ThreadLocal<T>& >(super::operator=(t));
142 }
143 ThreadLocal<T>& operator=(const ThreadLocal<T>& tl) {
144 return static_cast< ThreadLocal<T>& >(super::operator=(tl));
145 }
146 };/* class ThreadLocal<T> */
147
148 template <class T>
149 class ThreadLocal<T*> : public ThreadLocalImpl<T*, sizeof(T*) <= sizeof(void*)> {
150 typedef ThreadLocalImpl<T*, sizeof(T*) <= sizeof(void*)> super;
151
152 public:
153 ThreadLocal() : super() {}
154 ThreadLocal(T* t) : super(t) {}
155 ThreadLocal(const ThreadLocal<T*>& tl) : super(tl) {}
156
157 ThreadLocal<T*>& operator=(T* t) {
158 return static_cast< ThreadLocal<T*>& >(super::operator=(t));
159 }
160 ThreadLocal<T*>& operator=(const ThreadLocal<T*>& tl) {
161 return static_cast< ThreadLocal<T*>& >(super::operator=(tl));
162 }
163 // special operators for pointers
164 T& operator*() {
165 return *static_cast<T*>(*this);
166 }
167 const T& operator*() const {
168 return *static_cast<const T*>(*this);
169 }
170 T* operator->() {
171 return static_cast<T*>(*this);
172 }
173 const T* operator->() const {
174 return static_cast<const T*>(*this);
175 }
176 T* operator++() {
177 T* p = *this;
178 *this = ++p;
179 return p;
180 }
181 T* operator++(int) {
182 T* p = *this;
183 *this = p + 1;
184 return p;
185 }
186 T* operator--() {
187 T* p = *this;
188 *this = --p;
189 return p;
190 }
191 T* operator--(int) {
192 T* p = *this;
193 *this = p - 1;
194 return p;
195 }
196 };/* class ThreadLocal<T*> */
197
198 }/* CVC4 namespace */
199
200 #endif /* @CVC4_TLS_SUPPORTED@ */
201
202 #endif /* _CVC4__TLS_H */