summaryrefslogtreecommitdiff
path: root/src/base/tls.h.in
diff options
context:
space:
mode:
Diffstat (limited to 'src/base/tls.h.in')
-rw-r--r--src/base/tls.h.in198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/base/tls.h.in b/src/base/tls.h.in
new file mode 100644
index 000000000..88969e250
--- /dev/null
+++ b/src/base/tls.h.in
@@ -0,0 +1,198 @@
+/********************* */
+/*! \file tls.h.in
+ ** \verbatim
+ ** Original author: ACSYS
+ ** Major contributors: Morgan Deters
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014 New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Header to define CVC4_THREAD whether or not TLS is
+ ** supported by the compiler/runtime platform
+ **
+ ** Header to define CVC4_THREAD whether or not TLS is supported by
+ ** the compiler/runtime platform. If not, an implementation based on
+ ** pthread_getspecific() / pthread_setspecific() is given.
+ **/
+
+#include "cvc4_public.h"
+
+#ifndef __CVC4__TLS_H
+#define __CVC4__TLS_H
+
+// A bit obnoxious: we have to take varargs to support multi-argument
+// template types in the threadlocals.
+// E.g. "CVC4_THREADLOCAL(hash_set<type, hasher>*)" fails otherwise,
+// due to the embedded comma.
+#if @CVC4_TLS_SUPPORTED@
+# define CVC4_THREADLOCAL(__type...) @CVC4_TLS@ __type
+# define CVC4_THREADLOCAL_PUBLIC(__type...) @CVC4_TLS@ CVC4_PUBLIC __type
+# define CVC4_THREADLOCAL_TYPE(__type...) __type
+#else
+# include <pthread.h>
+# define CVC4_THREADLOCAL(__type...) ::CVC4::ThreadLocal< __type >
+# define CVC4_THREADLOCAL_PUBLIC(__type...) CVC4_PUBLIC ::CVC4::ThreadLocal< __type >
+# define CVC4_THREADLOCAL_TYPE(__type...) ::CVC4::ThreadLocal< __type >
+
+namespace CVC4 {
+
+template <class T, bool small>
+class ThreadLocalImpl;
+
+template <class T>
+class ThreadLocalImpl<T, true> {
+ pthread_key_t d_key;
+
+ static void cleanup(void*) {
+ }
+
+public:
+ ThreadLocalImpl() {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ }
+
+ ThreadLocalImpl(const T& t) {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
+ }
+
+ ThreadLocalImpl(const ThreadLocalImpl& tl) {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T&>(tl))));
+ }
+
+ ThreadLocalImpl& operator=(const T& t) {
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
+ return *this;
+ }
+ ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) {
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T&>(tl))));
+ return *this;
+ }
+
+ operator T() const {
+ return static_cast<T>(reinterpret_cast<size_t>(pthread_getspecific(d_key)));
+ }
+};/* class ThreadLocalImpl<T, true> */
+
+template <class T>
+class ThreadLocalImpl<T*, true> {
+ pthread_key_t d_key;
+
+ static void cleanup(void*) {
+ }
+
+public:
+ ThreadLocalImpl() {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ }
+
+ ThreadLocalImpl(const T* t) {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
+ }
+
+ ThreadLocalImpl(const ThreadLocalImpl& tl) {
+ pthread_key_create(&d_key, ThreadLocalImpl::cleanup);
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T*>(tl))));
+ }
+
+ ThreadLocalImpl& operator=(const T* t) {
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(t)));
+ return *this;
+ }
+ ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) {
+ pthread_setspecific(d_key, const_cast<void*>(reinterpret_cast<const void*>(static_cast<const T*>(tl))));
+ return *this;
+ }
+
+ operator T*() const {
+ return static_cast<T*>(pthread_getspecific(d_key));
+ }
+
+ T operator*() {
+ return *static_cast<T*>(pthread_getspecific(d_key));
+ }
+ T* operator->() {
+ return static_cast<T*>(pthread_getspecific(d_key));
+ }
+};/* class ThreadLocalImpl<T*, true> */
+
+template <class T>
+class ThreadLocalImpl<T, false> {
+};/* class ThreadLocalImpl<T, false> */
+
+template <class T>
+class ThreadLocal : public ThreadLocalImpl<T, sizeof(T) <= sizeof(void*)> {
+ typedef ThreadLocalImpl<T, sizeof(T) <= sizeof(void*)> super;
+
+public:
+ ThreadLocal() : super() {}
+ ThreadLocal(const T& t) : super(t) {}
+ ThreadLocal(const ThreadLocal<T>& tl) : super(tl) {}
+
+ ThreadLocal<T>& operator=(const T& t) {
+ return static_cast< ThreadLocal<T>& >(super::operator=(t));
+ }
+ ThreadLocal<T>& operator=(const ThreadLocal<T>& tl) {
+ return static_cast< ThreadLocal<T>& >(super::operator=(tl));
+ }
+};/* class ThreadLocal<T> */
+
+template <class T>
+class ThreadLocal<T*> : public ThreadLocalImpl<T*, sizeof(T*) <= sizeof(void*)> {
+ typedef ThreadLocalImpl<T*, sizeof(T*) <= sizeof(void*)> super;
+
+public:
+ ThreadLocal() : super() {}
+ ThreadLocal(T* t) : super(t) {}
+ ThreadLocal(const ThreadLocal<T*>& tl) : super(tl) {}
+
+ ThreadLocal<T*>& operator=(T* t) {
+ return static_cast< ThreadLocal<T*>& >(super::operator=(t));
+ }
+ ThreadLocal<T*>& operator=(const ThreadLocal<T*>& tl) {
+ return static_cast< ThreadLocal<T*>& >(super::operator=(tl));
+ }
+ // special operators for pointers
+ T& operator*() {
+ return *static_cast<T*>(*this);
+ }
+ const T& operator*() const {
+ return *static_cast<const T*>(*this);
+ }
+ T* operator->() {
+ return static_cast<T*>(*this);
+ }
+ const T* operator->() const {
+ return static_cast<const T*>(*this);
+ }
+ T* operator++() {
+ T* p = *this;
+ *this = ++p;
+ return p;
+ }
+ T* operator++(int) {
+ T* p = *this;
+ *this = p + 1;
+ return p;
+ }
+ T* operator--() {
+ T* p = *this;
+ *this = --p;
+ return p;
+ }
+ T* operator--(int) {
+ T* p = *this;
+ *this = p - 1;
+ return p;
+ }
+};/* class ThreadLocal<T*> */
+
+}/* CVC4 namespace */
+
+#endif /* @CVC4_TLS_SUPPORTED@ */
+
+#endif /* __CVC4__TLS_H */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback