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