1//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Unix specific (non-pthread) ThreadLocal class. 11// 12//===----------------------------------------------------------------------===// 13 14//===----------------------------------------------------------------------===// 15//=== WARNING: Implementation here must contain only generic UNIX code that 16//=== is guaranteed to work on *all* UNIX variants. 17//===----------------------------------------------------------------------===// 18 19#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) 20 21#include <cassert> 22#include <cstdlib> 23#include <pthread.h> 24 25namespace llvm { 26 27using namespace sys; 28 29ThreadLocalImpl::ThreadLocalImpl() : data() { 30 static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big"); 31 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 32 int errorcode = pthread_key_create(key, nullptr); 33 assert(errorcode == 0); 34 (void) errorcode; 35} 36 37ThreadLocalImpl::~ThreadLocalImpl() { 38 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 39 int errorcode = pthread_key_delete(*key); 40 assert(errorcode == 0); 41 (void) errorcode; 42} 43 44void ThreadLocalImpl::setInstance(const void* d) { 45 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 46 int errorcode = pthread_setspecific(*key, d); 47 assert(errorcode == 0); 48 (void) errorcode; 49} 50 51void *ThreadLocalImpl::getInstance() { 52 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 53 return pthread_getspecific(*key); 54} 55 56void ThreadLocalImpl::removeInstance() { 57 setInstance(nullptr); 58} 59 60} // end namespace llvm 61#else 62 63namespace llvm { 64 65using namespace sys; 66 67ThreadLocalImpl::ThreadLocalImpl() : data() { } 68ThreadLocalImpl::~ThreadLocalImpl() { } 69void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);} 70void *ThreadLocalImpl::getInstance() { return data; } 71void ThreadLocalImpl::removeInstance() { setInstance(0); } 72 73} // end namespace llvm 74 75#endif 76