1 //===- ThreadLocal.cpp - 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 llvm::sys::ThreadLocal class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/Config/config.h" 15 #include "llvm/Support/ThreadLocal.h" 16 17 //===----------------------------------------------------------------------===// 18 //=== WARNING: Implementation here must contain only TRULY operating system 19 //=== independent code. 20 //===----------------------------------------------------------------------===// 21 22 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 23 // Define all methods as no-ops if threading is explicitly disabled 24 namespace llvm { 25 using namespace sys; 26 ThreadLocalImpl::ThreadLocalImpl() { } 27 ThreadLocalImpl::~ThreadLocalImpl() { } 28 void ThreadLocalImpl::setInstance(const void* d) { 29 typedef int SIZE_TOO_BIG[sizeof(d) <= sizeof(data) ? 1 : -1]; 30 void **pd = reinterpret_cast<void**>(&data); 31 *pd = const_cast<void*>(d); 32 } 33 const void* ThreadLocalImpl::getInstance() { return data; } 34 void ThreadLocalImpl::removeInstance() { 35 void **pd = reinterpret_cast<void**>(&data); 36 *pd = 0; 37 } 38 } 39 #else 40 41 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) 42 43 #include <cassert> 44 #include <pthread.h> 45 #include <stdlib.h> 46 47 namespace llvm { 48 using namespace sys; 49 50 ThreadLocalImpl::ThreadLocalImpl() : data() { 51 typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1]; 52 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 53 int errorcode = pthread_key_create(key, NULL); 54 assert(errorcode == 0); 55 (void) errorcode; 56 } 57 58 ThreadLocalImpl::~ThreadLocalImpl() { 59 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 60 int errorcode = pthread_key_delete(*key); 61 assert(errorcode == 0); 62 (void) errorcode; 63 } 64 65 void ThreadLocalImpl::setInstance(const void* d) { 66 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 67 int errorcode = pthread_setspecific(*key, d); 68 assert(errorcode == 0); 69 (void) errorcode; 70 } 71 72 const void* ThreadLocalImpl::getInstance() { 73 pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 74 return pthread_getspecific(*key); 75 } 76 77 void ThreadLocalImpl::removeInstance() { 78 setInstance(0); 79 } 80 81 } 82 83 #elif defined(LLVM_ON_UNIX) 84 #include "Unix/ThreadLocal.inc" 85 #elif defined( LLVM_ON_WIN32) 86 #include "Windows/ThreadLocal.inc" 87 #else 88 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp 89 #endif 90 #endif 91