LLVM API Documentation

ThreadLocal.cpp
Go to the documentation of this file.
00001 //===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements the llvm::sys::ThreadLocal class.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "llvm/Config/config.h"
00015 #include "llvm/Support/Compiler.h"
00016 #include "llvm/Support/ThreadLocal.h"
00017 
00018 //===----------------------------------------------------------------------===//
00019 //=== WARNING: Implementation here must contain only TRULY operating system
00020 //===          independent code.
00021 //===----------------------------------------------------------------------===//
00022 
00023 #if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
00024 // Define all methods as no-ops if threading is explicitly disabled
00025 namespace llvm {
00026 using namespace sys;
00027 ThreadLocalImpl::ThreadLocalImpl() : data() { }
00028 ThreadLocalImpl::~ThreadLocalImpl() { }
00029 void ThreadLocalImpl::setInstance(const void* d) {
00030   static_assert(sizeof(d) <= sizeof(data), "size too big");
00031   void **pd = reinterpret_cast<void**>(&data);
00032   *pd = const_cast<void*>(d);
00033 }
00034 const void* ThreadLocalImpl::getInstance() {
00035   void **pd = reinterpret_cast<void**>(&data);
00036   return *pd;
00037 }
00038 void ThreadLocalImpl::removeInstance() {
00039   setInstance(0);
00040 }
00041 }
00042 #else
00043 
00044 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
00045 
00046 #include <cassert>
00047 #include <pthread.h>
00048 #include <stdlib.h>
00049 
00050 namespace llvm {
00051 using namespace sys;
00052 
00053 ThreadLocalImpl::ThreadLocalImpl() : data() {
00054   static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
00055   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
00056   int errorcode = pthread_key_create(key, nullptr);
00057   assert(errorcode == 0);
00058   (void) errorcode;
00059 }
00060 
00061 ThreadLocalImpl::~ThreadLocalImpl() {
00062   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
00063   int errorcode = pthread_key_delete(*key);
00064   assert(errorcode == 0);
00065   (void) errorcode;
00066 }
00067 
00068 void ThreadLocalImpl::setInstance(const void* d) {
00069   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
00070   int errorcode = pthread_setspecific(*key, d);
00071   assert(errorcode == 0);
00072   (void) errorcode;
00073 }
00074 
00075 const void* ThreadLocalImpl::getInstance() {
00076   pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
00077   return pthread_getspecific(*key);
00078 }
00079 
00080 void ThreadLocalImpl::removeInstance() {
00081   setInstance(nullptr);
00082 }
00083 
00084 }
00085 
00086 #elif defined(LLVM_ON_UNIX)
00087 #include "Unix/ThreadLocal.inc"
00088 #elif defined( LLVM_ON_WIN32)
00089 #include "Windows/ThreadLocal.inc"
00090 #else
00091 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
00092 #endif
00093 #endif