14a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
24a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//
34a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//                     The LLVM Compiler Infrastructure
44a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//
54a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson// This file is distributed under the University of Illinois Open Source
64a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson// License. See LICENSE.TXT for details.
74a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//
84a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===----------------------------------------------------------------------===//
94a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//
104a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson// This file implements the llvm::sys::ThreadLocal class.
114a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//
124a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===----------------------------------------------------------------------===//
134a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
144a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#include "llvm/Config/config.h"
1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Compiler.h"
161f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/ThreadLocal.h"
174a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
184a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===----------------------------------------------------------------------===//
194a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//=== WARNING: Implementation here must contain only TRULY operating system
204a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===          independent code.
214a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson//===----------------------------------------------------------------------===//
224a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
2308b73a30bbb6407c7b48a734a29f65f4c8ddd782Dylan Noblesmith#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
244a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson// Define all methods as no-ops if threading is explicitly disabled
254a28522c1a0828eff097194f31c262ae6d13cefeOwen Andersonnamespace llvm {
264a28522c1a0828eff097194f31c262ae6d13cefeOwen Andersonusing namespace sys;
27b95f36183ccbb26154accc99fd304f6e04075682Bill WendlingThreadLocalImpl::ThreadLocalImpl() : data() { }
284a28522c1a0828eff097194f31c262ae6d13cefeOwen AndersonThreadLocalImpl::~ThreadLocalImpl() { }
291a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidisvoid ThreadLocalImpl::setInstance(const void* d) {
3036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static_assert(sizeof(d) <= sizeof(data), "size too big");
311a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidis  void **pd = reinterpret_cast<void**>(&data);
321a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidis  *pd = const_cast<void*>(d);
331a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidis}
34da72dd2a01a9f3e686699d01f4d40b936a52eab6Argyrios Kyrtzidisconst void* ThreadLocalImpl::getInstance() {
351a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidis  void **pd = reinterpret_cast<void**>(&data);
36da72dd2a01a9f3e686699d01f4d40b936a52eab6Argyrios Kyrtzidis  return *pd;
37da72dd2a01a9f3e686699d01f4d40b936a52eab6Argyrios Kyrtzidis}
38da72dd2a01a9f3e686699d01f4d40b936a52eab6Argyrios Kyrtzidisvoid ThreadLocalImpl::removeInstance() {
39da72dd2a01a9f3e686699d01f4d40b936a52eab6Argyrios Kyrtzidis  setInstance(0);
401a18e9a2c4495052b903481c83616265074c4e91Argyrios Kyrtzidis}
414a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
424a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#else
434a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
4427fcfe1364943dadd99fd0ef5af6793f58acc446Owen Anderson#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
454a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
464a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#include <cassert>
474a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#include <pthread.h>
484a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#include <stdlib.h>
494a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
504a28522c1a0828eff097194f31c262ae6d13cefeOwen Andersonnamespace llvm {
514a28522c1a0828eff097194f31c262ae6d13cefeOwen Andersonusing namespace sys;
524a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
533e61374295693beb0a899af44ccf4b5085dffbf3Argyrios KyrtzidisThreadLocalImpl::ThreadLocalImpl() : data() {
5436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
55793537d21f8aa46458a5733d96816ba8bddeef50Argyrios Kyrtzidis  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  int errorcode = pthread_key_create(key, nullptr);
574a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson  assert(errorcode == 0);
586f8f6066fdeafc75277a73c55cc9b0832d845d0eDaniel Dunbar  (void) errorcode;
594a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
604a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
614a28522c1a0828eff097194f31c262ae6d13cefeOwen AndersonThreadLocalImpl::~ThreadLocalImpl() {
62793537d21f8aa46458a5733d96816ba8bddeef50Argyrios Kyrtzidis  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
634a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson  int errorcode = pthread_key_delete(*key);
647e026b74dd1fdaa81a147488423571c59079d9bbOwen Anderson  assert(errorcode == 0);
656f8f6066fdeafc75277a73c55cc9b0832d845d0eDaniel Dunbar  (void) errorcode;
664a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
674a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
68438d3946afc9ba502d56269d1a1d2c18d38d7e23Owen Andersonvoid ThreadLocalImpl::setInstance(const void* d) {
69793537d21f8aa46458a5733d96816ba8bddeef50Argyrios Kyrtzidis  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
704a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson  int errorcode = pthread_setspecific(*key, d);
714a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson  assert(errorcode == 0);
726f8f6066fdeafc75277a73c55cc9b0832d845d0eDaniel Dunbar  (void) errorcode;
734a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
744a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
75438d3946afc9ba502d56269d1a1d2c18d38d7e23Owen Andersonconst void* ThreadLocalImpl::getInstance() {
76793537d21f8aa46458a5733d96816ba8bddeef50Argyrios Kyrtzidis  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
774a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson  return pthread_getspecific(*key);
784a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
794a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
80826c148aa5af36cca688b7da447bc0b22905d904Owen Andersonvoid ThreadLocalImpl::removeInstance() {
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  setInstance(nullptr);
82826c148aa5af36cca688b7da447bc0b22905d904Owen Anderson}
83826c148aa5af36cca688b7da447bc0b22905d904Owen Anderson
844a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson}
854a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson
864a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#elif defined(LLVM_ON_UNIX)
874a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#include "Unix/ThreadLocal.inc"
884a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#elif defined( LLVM_ON_WIN32)
891f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "Windows/ThreadLocal.inc"
904a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#else
912c607b665dbeb52e2ade86f0e1f191695290da3bDaniel Dunbar#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
924a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#endif
934a28522c1a0828eff097194f31c262ae6d13cefeOwen Anderson#endif
94