1//=== llvm/Support/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file implements the Unix specific (non-pthread) ThreadLocal class. 10// 11//===----------------------------------------------------------------------===// 12 13//===----------------------------------------------------------------------===// 14//=== WARNING: Implementation here must contain only generic UNIX code that 15//=== is guaranteed to work on *all* UNIX variants. 16//===----------------------------------------------------------------------===// 17 18#include "llvm/Config/config.h" 19 20#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC) 21 22#include <cassert> 23#include <pthread.h> 24#include <stdlib.h> 25 26namespace llvm { 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} 61#else 62namespace llvm { 63using namespace sys; 64ThreadLocalImpl::ThreadLocalImpl() : data() { } 65ThreadLocalImpl::~ThreadLocalImpl() { } 66void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);} 67void *ThreadLocalImpl::getInstance() { return data; } 68void ThreadLocalImpl::removeInstance() { setInstance(0); } 69} 70#endif 71