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 <cstdlib>
23#include <pthread.h>
24
25namespace llvm {
26
27using namespace sys;
28
29ThreadLocalImpl::ThreadLocalImpl() : data() {
30  static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
31  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
32  int errorcode = pthread_key_create(key, nullptr);
33  assert(errorcode == 0);
34  (void) errorcode;
35}
36
37ThreadLocalImpl::~ThreadLocalImpl() {
38  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
39  int errorcode = pthread_key_delete(*key);
40  assert(errorcode == 0);
41  (void) errorcode;
42}
43
44void ThreadLocalImpl::setInstance(const void* d) {
45  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
46  int errorcode = pthread_setspecific(*key, d);
47  assert(errorcode == 0);
48  (void) errorcode;
49}
50
51void *ThreadLocalImpl::getInstance() {
52  pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
53  return pthread_getspecific(*key);
54}
55
56void ThreadLocalImpl::removeInstance() {
57  setInstance(nullptr);
58}
59
60} // end namespace llvm
61#else
62
63namespace llvm {
64
65using namespace sys;
66
67ThreadLocalImpl::ThreadLocalImpl() : data() { }
68ThreadLocalImpl::~ThreadLocalImpl() { }
69void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
70void *ThreadLocalImpl::getInstance() { return data; }
71void ThreadLocalImpl::removeInstance() { setInstance(0); }
72
73} // end namespace llvm
74
75#endif
76