Add a class for supporting platform independent thread-local storage.

Windows people, please double-check/patch this.

llvm-svn: 74209
This commit is contained in:
Owen Anderson 2009-06-25 21:58:01 +00:00
parent 2d2ee150eb
commit f17f6f06fa
4 changed files with 192 additions and 0 deletions

View File

@ -0,0 +1,41 @@
//===- llvm/System/ThreadLocal.h - Thread Local Data ------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file declares the llvm::sys::ThreadLocal class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_SYSTEM_THREAD_LOCAL_H
#define LLVM_SYSTEM_THREAD_LOCAL_H
#include "llvm/System/Threading.h"
#include <cassert>
namespace llvm {
namespace sys {
class ThreadLocalImpl {
void* data;
public:
ThreadLocalImpl();
virtual ~ThreadLocalImpl();
void setInstance(void* d);
void* getInstance();
};
template<class T>
class ThreadLocal : public ThreadLocalImpl {
public:
ThreadLocal() : ThreadLocalImpl() { }
T* get() { return static_cast<T*>(getInstance()); }
void set(T* d) { setInstance(d); }
};
}
}
#endif

View File

@ -0,0 +1,77 @@
//===- ThreadLocal.cpp - Thread Local Data ----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the llvm::sys::ThreadLocal class.
//
//===----------------------------------------------------------------------===//
#include "llvm/Config/config.h"
#include "llvm/System/ThreadLocal.h"
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
//=== independent code.
//===----------------------------------------------------------------------===//
#if !defined(ENABLE_THREADS) || ENABLE_THREADS == 0
// Define all methods as no-ops if threading is explicitly disabled
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() { }
ThreadLocalImpl::~ThreadLocalImpl() { }
void ThreadLocalImpl::setInstance(void* d) { data = d; }
void* ThreadLocalImpl::getInstance() { return data; }
}
#else
#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
#include <cassert>
#include <pthread.h>
#include <stdlib.h>
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() : data(0) {
pthread_key_t* key = new pthread_key_t;
int errorcode = pthread_key_create(key, NULL);
assert(errorcode == 0);
data = key;
}
ThreadLocalImpl::~ThreadLocalImpl() {
pthread_key_t* key = static_cast<pthread_key_t*>(data);
int errorcode = pthread_key_delete(*key);
assert(errorcode = 0);
delete key;
}
void ThreadLocalImpl::setInstance(void* d) {
pthread_key_t* key = static_cast<pthread_key_t*>(data);
int errorcode = pthread_setspecific(*key, d);
assert(errorcode == 0);
}
void* ThreadLocalImpl::getInstance() {
pthread_key_t* key = static_cast<pthread_key_t*>(data);
return pthread_getspecific(*key);
}
}
#elif defined(LLVM_ON_UNIX)
#include "Unix/ThreadLocal.inc"
#elif defined( LLVM_ON_WIN32)
#include "Win32/ThreadLocal.inc"
#else
#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/ThreadLocal.cpp
#endif
#endif

View File

@ -0,0 +1,25 @@
//=== llvm/System/Unix/ThreadLocal.inc - Unix Thread Local Data -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Unix specific (non-pthread) ThreadLocal class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic UNIX code that
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() { }
ThreadLocalImpl::~ThreadLocalImpl() { }
void ThreadLocalImpl::setInstance(void* d) { data = d; }
void* ThreadLocalImpl::getInstance() { return data; }
}

View File

@ -0,0 +1,49 @@
//= llvm/System/Win32/ThreadLocal.inc - Win32 Thread Local Data -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements the Win32 specific (non-pthread) ThreadLocal class.
//
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only generic Win32 code that
//=== is guaranteed to work on *all* Win32 variants.
//===----------------------------------------------------------------------===//
#include "Win32.h"
#include "llvm/System/ThreadLocal.h"
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() {
DWORD* tls = new DWORD;
*tls = TlsAlloc();
assert(*tls != TLS_OUT_OF_INDEXES);
data = tls;
}
ThreadLocalImpl::~ThreadLocalImpl() {
DWORD* tls = static_cast<DWORD*>(data);
TlsFree(*tls);
delete tls;
}
void* ThreadLocalImpl::getInstance() {
DWORD* tls = static_cast<DWORD*>(data);
return TlsGetValue(*tls);
}
void ThreadLocalImpl::setInstance(void* d){
DWORD* tls = static_cast<DWORD*>(data);
int errorcode = TlsSetValue(*tls, d);
assert(errorcode == 0);
}
}