/********************* */ /*! \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*)" 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 # 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 ThreadLocalImpl; template class ThreadLocalImpl { 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(reinterpret_cast(t))); } ThreadLocalImpl(const ThreadLocalImpl& tl) { pthread_key_create(&d_key, ThreadLocalImpl::cleanup); pthread_setspecific(d_key, const_cast(reinterpret_cast(static_cast(tl)))); } ThreadLocalImpl& operator=(const T& t) { pthread_setspecific(d_key, const_cast(reinterpret_cast(t))); return *this; } ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) { pthread_setspecific(d_key, const_cast(reinterpret_cast(static_cast(tl)))); return *this; } operator T() const { return static_cast(reinterpret_cast(pthread_getspecific(d_key))); } };/* class ThreadLocalImpl */ template class ThreadLocalImpl { 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(reinterpret_cast(t))); } ThreadLocalImpl(const ThreadLocalImpl& tl) { pthread_key_create(&d_key, ThreadLocalImpl::cleanup); pthread_setspecific(d_key, const_cast(reinterpret_cast(static_cast(tl)))); } ThreadLocalImpl& operator=(const T* t) { pthread_setspecific(d_key, const_cast(reinterpret_cast(t))); return *this; } ThreadLocalImpl& operator=(const ThreadLocalImpl& tl) { pthread_setspecific(d_key, const_cast(reinterpret_cast(static_cast(tl)))); return *this; } operator T*() const { return static_cast(pthread_getspecific(d_key)); } T operator*() { return *static_cast(pthread_getspecific(d_key)); } T* operator->() { return static_cast(pthread_getspecific(d_key)); } };/* class ThreadLocalImpl */ template class ThreadLocalImpl { };/* class ThreadLocalImpl */ template class ThreadLocal : public ThreadLocalImpl { typedef ThreadLocalImpl super; public: ThreadLocal() : super() {} ThreadLocal(const T& t) : super(t) {} ThreadLocal(const ThreadLocal& tl) : super(tl) {} ThreadLocal& operator=(const T& t) { return static_cast< ThreadLocal& >(super::operator=(t)); } ThreadLocal& operator=(const ThreadLocal& tl) { return static_cast< ThreadLocal& >(super::operator=(tl)); } };/* class ThreadLocal */ template class ThreadLocal : public ThreadLocalImpl { typedef ThreadLocalImpl super; public: ThreadLocal() : super() {} ThreadLocal(T* t) : super(t) {} ThreadLocal(const ThreadLocal& tl) : super(tl) {} ThreadLocal& operator=(T* t) { return static_cast< ThreadLocal& >(super::operator=(t)); } ThreadLocal& operator=(const ThreadLocal& tl) { return static_cast< ThreadLocal& >(super::operator=(tl)); } // special operators for pointers T& operator*() { return *static_cast(*this); } const T& operator*() const { return *static_cast(*this); } T* operator->() { return static_cast(*this); } const T* operator->() const { return static_cast(*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 */ }/* CVC4 namespace */ #endif /* @CVC4_TLS_SUPPORTED@ */ #endif /* __CVC4__TLS_H */