1*447762daSMichael J. Spencer //===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
2*447762daSMichael J. Spencer //
3*447762daSMichael J. Spencer //                     The LLVM Compiler Infrastructure
4*447762daSMichael J. Spencer //
5*447762daSMichael J. Spencer // This file is distributed under the University of Illinois Open Source
6*447762daSMichael J. Spencer // License. See LICENSE.TXT for details.
7*447762daSMichael J. Spencer //
8*447762daSMichael J. Spencer //===----------------------------------------------------------------------===//
9*447762daSMichael J. Spencer //
10*447762daSMichael J. Spencer // This file implements the llvm::sys::ThreadLocal class.
11*447762daSMichael J. Spencer //
12*447762daSMichael J. Spencer //===----------------------------------------------------------------------===//
13*447762daSMichael J. Spencer 
14*447762daSMichael J. Spencer #include "llvm/Config/config.h"
15*447762daSMichael J. Spencer #include "llvm/Support/ThreadLocal.h"
16*447762daSMichael J. Spencer 
17*447762daSMichael J. Spencer //===----------------------------------------------------------------------===//
18*447762daSMichael J. Spencer //=== WARNING: Implementation here must contain only TRULY operating system
19*447762daSMichael J. Spencer //===          independent code.
20*447762daSMichael J. Spencer //===----------------------------------------------------------------------===//
21*447762daSMichael J. Spencer 
22*447762daSMichael J. Spencer #if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
23*447762daSMichael J. Spencer // Define all methods as no-ops if threading is explicitly disabled
24*447762daSMichael J. Spencer namespace llvm {
25*447762daSMichael J. Spencer using namespace sys;
26*447762daSMichael J. Spencer ThreadLocalImpl::ThreadLocalImpl() { }
27*447762daSMichael J. Spencer ThreadLocalImpl::~ThreadLocalImpl() { }
28*447762daSMichael J. Spencer void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
29*447762daSMichael J. Spencer const void* ThreadLocalImpl::getInstance() { return data; }
30*447762daSMichael J. Spencer void ThreadLocalImpl::removeInstance() { data = 0; }
31*447762daSMichael J. Spencer }
32*447762daSMichael J. Spencer #else
33*447762daSMichael J. Spencer 
34*447762daSMichael J. Spencer #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
35*447762daSMichael J. Spencer 
36*447762daSMichael J. Spencer #include <cassert>
37*447762daSMichael J. Spencer #include <pthread.h>
38*447762daSMichael J. Spencer #include <stdlib.h>
39*447762daSMichael J. Spencer 
40*447762daSMichael J. Spencer namespace llvm {
41*447762daSMichael J. Spencer using namespace sys;
42*447762daSMichael J. Spencer 
43*447762daSMichael J. Spencer ThreadLocalImpl::ThreadLocalImpl() : data(0) {
44*447762daSMichael J. Spencer   pthread_key_t* key = new pthread_key_t;
45*447762daSMichael J. Spencer   int errorcode = pthread_key_create(key, NULL);
46*447762daSMichael J. Spencer   assert(errorcode == 0);
47*447762daSMichael J. Spencer   (void) errorcode;
48*447762daSMichael J. Spencer   data = (void*)key;
49*447762daSMichael J. Spencer }
50*447762daSMichael J. Spencer 
51*447762daSMichael J. Spencer ThreadLocalImpl::~ThreadLocalImpl() {
52*447762daSMichael J. Spencer   pthread_key_t* key = static_cast<pthread_key_t*>(data);
53*447762daSMichael J. Spencer   int errorcode = pthread_key_delete(*key);
54*447762daSMichael J. Spencer   assert(errorcode == 0);
55*447762daSMichael J. Spencer   (void) errorcode;
56*447762daSMichael J. Spencer   delete key;
57*447762daSMichael J. Spencer }
58*447762daSMichael J. Spencer 
59*447762daSMichael J. Spencer void ThreadLocalImpl::setInstance(const void* d) {
60*447762daSMichael J. Spencer   pthread_key_t* key = static_cast<pthread_key_t*>(data);
61*447762daSMichael J. Spencer   int errorcode = pthread_setspecific(*key, d);
62*447762daSMichael J. Spencer   assert(errorcode == 0);
63*447762daSMichael J. Spencer   (void) errorcode;
64*447762daSMichael J. Spencer }
65*447762daSMichael J. Spencer 
66*447762daSMichael J. Spencer const void* ThreadLocalImpl::getInstance() {
67*447762daSMichael J. Spencer   pthread_key_t* key = static_cast<pthread_key_t*>(data);
68*447762daSMichael J. Spencer   return pthread_getspecific(*key);
69*447762daSMichael J. Spencer }
70*447762daSMichael J. Spencer 
71*447762daSMichael J. Spencer void ThreadLocalImpl::removeInstance() {
72*447762daSMichael J. Spencer   setInstance(0);
73*447762daSMichael J. Spencer }
74*447762daSMichael J. Spencer 
75*447762daSMichael J. Spencer }
76*447762daSMichael J. Spencer 
77*447762daSMichael J. Spencer #elif defined(LLVM_ON_UNIX)
78*447762daSMichael J. Spencer #include "Unix/ThreadLocal.inc"
79*447762daSMichael J. Spencer #elif defined( LLVM_ON_WIN32)
80*447762daSMichael J. Spencer #include "Windows/ThreadLocal.inc"
81*447762daSMichael J. Spencer #else
82*447762daSMichael J. Spencer #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp
83*447762daSMichael J. Spencer #endif
84*447762daSMichael J. Spencer #endif
85