1447762daSMichael J. Spencer //===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===// 2447762daSMichael J. Spencer // 3447762daSMichael J. Spencer // The LLVM Compiler Infrastructure 4447762daSMichael J. Spencer // 5447762daSMichael J. Spencer // This file is distributed under the University of Illinois Open Source 6447762daSMichael J. Spencer // License. See LICENSE.TXT for details. 7447762daSMichael J. Spencer // 8447762daSMichael J. Spencer //===----------------------------------------------------------------------===// 9447762daSMichael J. Spencer // 10447762daSMichael J. Spencer // This file implements the llvm::sys::ThreadLocal class. 11447762daSMichael J. Spencer // 12447762daSMichael J. Spencer //===----------------------------------------------------------------------===// 13447762daSMichael J. Spencer 14447762daSMichael J. Spencer #include "llvm/Config/config.h" 15447762daSMichael J. Spencer #include "llvm/Support/ThreadLocal.h" 16447762daSMichael J. Spencer 17447762daSMichael J. Spencer //===----------------------------------------------------------------------===// 18447762daSMichael J. Spencer //=== WARNING: Implementation here must contain only TRULY operating system 19447762daSMichael J. Spencer //=== independent code. 20447762daSMichael J. Spencer //===----------------------------------------------------------------------===// 21447762daSMichael J. Spencer 22efddf201SDylan Noblesmith #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 23447762daSMichael J. Spencer // Define all methods as no-ops if threading is explicitly disabled 24447762daSMichael J. Spencer namespace llvm { 25447762daSMichael J. Spencer using namespace sys; 26*fabf8bfdSHans Wennborg ThreadLocalImpl::ThreadLocalImpl() : data() { } 27447762daSMichael J. Spencer ThreadLocalImpl::~ThreadLocalImpl() { } 28444fd426SArgyrios Kyrtzidis void ThreadLocalImpl::setInstance(const void* d) { 29444fd426SArgyrios Kyrtzidis typedef int SIZE_TOO_BIG[sizeof(d) <= sizeof(data) ? 1 : -1]; 30444fd426SArgyrios Kyrtzidis void **pd = reinterpret_cast<void**>(&data); 31444fd426SArgyrios Kyrtzidis *pd = const_cast<void*>(d); 32444fd426SArgyrios Kyrtzidis } 3346785f94SArgyrios Kyrtzidis const void* ThreadLocalImpl::getInstance() { 34444fd426SArgyrios Kyrtzidis void **pd = reinterpret_cast<void**>(&data); 3546785f94SArgyrios Kyrtzidis return *pd; 3646785f94SArgyrios Kyrtzidis } 3746785f94SArgyrios Kyrtzidis void ThreadLocalImpl::removeInstance() { 3846785f94SArgyrios Kyrtzidis setInstance(0); 39444fd426SArgyrios Kyrtzidis } 40447762daSMichael J. Spencer } 41447762daSMichael J. Spencer #else 42447762daSMichael J. Spencer 43447762daSMichael J. Spencer #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) 44447762daSMichael J. Spencer 45447762daSMichael J. Spencer #include <cassert> 46447762daSMichael J. Spencer #include <pthread.h> 47447762daSMichael J. Spencer #include <stdlib.h> 48447762daSMichael J. Spencer 49447762daSMichael J. Spencer namespace llvm { 50447762daSMichael J. Spencer using namespace sys; 51447762daSMichael J. Spencer 52c6dc4d75SArgyrios Kyrtzidis ThreadLocalImpl::ThreadLocalImpl() : data() { 538d19c86cSArgyrios Kyrtzidis typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1]; 548d19c86cSArgyrios Kyrtzidis pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 55447762daSMichael J. Spencer int errorcode = pthread_key_create(key, NULL); 56447762daSMichael J. Spencer assert(errorcode == 0); 57447762daSMichael J. Spencer (void) errorcode; 58447762daSMichael J. Spencer } 59447762daSMichael J. Spencer 60447762daSMichael J. Spencer ThreadLocalImpl::~ThreadLocalImpl() { 618d19c86cSArgyrios Kyrtzidis pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 62447762daSMichael J. Spencer int errorcode = pthread_key_delete(*key); 63447762daSMichael J. Spencer assert(errorcode == 0); 64447762daSMichael J. Spencer (void) errorcode; 65447762daSMichael J. Spencer } 66447762daSMichael J. Spencer 67447762daSMichael J. Spencer void ThreadLocalImpl::setInstance(const void* d) { 688d19c86cSArgyrios Kyrtzidis pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 69447762daSMichael J. Spencer int errorcode = pthread_setspecific(*key, d); 70447762daSMichael J. Spencer assert(errorcode == 0); 71447762daSMichael J. Spencer (void) errorcode; 72447762daSMichael J. Spencer } 73447762daSMichael J. Spencer 74447762daSMichael J. Spencer const void* ThreadLocalImpl::getInstance() { 758d19c86cSArgyrios Kyrtzidis pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data); 76447762daSMichael J. Spencer return pthread_getspecific(*key); 77447762daSMichael J. Spencer } 78447762daSMichael J. Spencer 79447762daSMichael J. Spencer void ThreadLocalImpl::removeInstance() { 80447762daSMichael J. Spencer setInstance(0); 81447762daSMichael J. Spencer } 82447762daSMichael J. Spencer 83447762daSMichael J. Spencer } 84447762daSMichael J. Spencer 85447762daSMichael J. Spencer #elif defined(LLVM_ON_UNIX) 86447762daSMichael J. Spencer #include "Unix/ThreadLocal.inc" 87447762daSMichael J. Spencer #elif defined( LLVM_ON_WIN32) 88447762daSMichael J. Spencer #include "Windows/ThreadLocal.inc" 89447762daSMichael J. Spencer #else 90037fc931SDaniel Dunbar #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp 91447762daSMichael J. Spencer #endif 92447762daSMichael J. Spencer #endif 93