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/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() {
     34   void **pd = reinterpret_cast<void**>(&data);
     35   return *pd;
     36 }
     37 void ThreadLocalImpl::removeInstance() {
     38   setInstance(0);
     39 }
     40 }
     41 #else
     42 
     43 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
     44 
     45 #include <cassert>
     46 #include <pthread.h>
     47 #include <stdlib.h>
     48 
     49 namespace llvm {
     50 using namespace sys;
     51 
     52 ThreadLocalImpl::ThreadLocalImpl() : data() {
     53   typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1];
     54   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
     55   int errorcode = pthread_key_create(key, NULL);
     56   assert(errorcode == 0);
     57   (void) errorcode;
     58 }
     59 
     60 ThreadLocalImpl::~ThreadLocalImpl() {
     61   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
     62   int errorcode = pthread_key_delete(*key);
     63   assert(errorcode == 0);
     64   (void) errorcode;
     65 }
     66 
     67 void ThreadLocalImpl::setInstance(const void* d) {
     68   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
     69   int errorcode = pthread_setspecific(*key, d);
     70   assert(errorcode == 0);
     71   (void) errorcode;
     72 }
     73 
     74 const void* ThreadLocalImpl::getInstance() {
     75   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
     76   return pthread_getspecific(*key);
     77 }
     78 
     79 void ThreadLocalImpl::removeInstance() {
     80   setInstance(0);
     81 }
     82 
     83 }
     84 
     85 #elif defined(LLVM_ON_UNIX)
     86 #include "Unix/ThreadLocal.inc"
     87 #elif defined( LLVM_ON_WIN32)
     88 #include "Windows/ThreadLocal.inc"
     89 #else
     90 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
     91 #endif
     92 #endif
     93