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#include "llvm/Config/config.h" 20 21#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) 22 23#include <cassert> 24#include <pthread.h> 25#include <stdlib.h> 26 27namespace llvm { 28using namespace sys; 29 30ThreadLocalImpl::ThreadLocalImpl() : data() { 31 static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big"); 32 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 33 int errorcode = pthread_key_create(key, nullptr); 34 assert(errorcode == 0); 35 (void) errorcode; 36} 37 38ThreadLocalImpl::~ThreadLocalImpl() { 39 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 40 int errorcode = pthread_key_delete(*key); 41 assert(errorcode == 0); 42 (void) errorcode; 43} 44 45void ThreadLocalImpl::setInstance(const void* d) { 46 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 47 int errorcode = pthread_setspecific(*key, d); 48 assert(errorcode == 0); 49 (void) errorcode; 50} 51 52void *ThreadLocalImpl::getInstance() { 53 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 54 return pthread_getspecific(*key); 55} 56 57void ThreadLocalImpl::removeInstance() { 58 setInstance(nullptr); 59} 60 61} 62#else 63namespace llvm { 64using namespace sys; 65ThreadLocalImpl::ThreadLocalImpl() : data() { } 66ThreadLocalImpl::~ThreadLocalImpl() { } 67void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);} 68void *ThreadLocalImpl::getInstance() { return data; } 69void ThreadLocalImpl::removeInstance() { setInstance(0); } 70} 71#endif 72