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