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