Home | History | Annotate | Download | only in Unix
      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 
     25 namespace llvm {
     26 using namespace sys;
     27 
     28 ThreadLocalImpl::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 
     36 ThreadLocalImpl::~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 
     43 void 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 
     50 void *ThreadLocalImpl::getInstance() {
     51   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
     52   return pthread_getspecific(*key);
     53 }
     54 
     55 void ThreadLocalImpl::removeInstance() {
     56   setInstance(nullptr);
     57 }
     58 
     59 }
     60 #else
     61 namespace llvm {
     62 using namespace sys;
     63 ThreadLocalImpl::ThreadLocalImpl() : data() { }
     64 ThreadLocalImpl::~ThreadLocalImpl() { }
     65 void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
     66 void *ThreadLocalImpl::getInstance() { return data; }
     67 void ThreadLocalImpl::removeInstance() { setInstance(0); }
     68 }
     69 #endif
     70