llvm.org GIT mirror llvm / 793537d
For llvm::sys::ThreadLocalImpl instead of malloc'ing the platform-specific thread local data, embed them in the class using a uint64_t and make sure we get compiler errors if there's a platform where this is not big enough. This makes ThreadLocal more safe for using it in conjunction with CrashRecoveryContext. Related to crash in rdar://11434201. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@158342 91177308-0d34-0410-b5e6-96231b3b80d8 Argyrios Kyrtzidis 8 years ago
3 changed file(s) with 18 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_SYSTEM_THREAD_LOCAL_H
1515
1616 #include "llvm/Support/Threading.h"
17 #include "llvm/Support/DataTypes.h"
1718 #include
1819
1920 namespace llvm {
2122 // ThreadLocalImpl - Common base class of all ThreadLocal instantiations.
2223 // YOU SHOULD NEVER USE THIS DIRECTLY.
2324 class ThreadLocalImpl {
24 void* data;
25 typedef uint64_t ThreadLocalDataTy;
26 /// \brief Platform-specific thread local data.
27 ///
28 /// This is embedded in the class and we avoid malloc'ing/free'ing it,
29 /// to make this class more safe for use along with CrashRecoveryContext.
30 ThreadLocalDataTy data;
2531 public:
2632 ThreadLocalImpl();
2733 virtual ~ThreadLocalImpl();
4040 using namespace sys;
4141
4242 ThreadLocalImpl::ThreadLocalImpl() : data(0) {
43 pthread_key_t* key = new pthread_key_t;
43 typedef int SIZE_TOO_BIG[sizeof(pthread_key_t) <= sizeof(data) ? 1 : -1];
44 pthread_key_t* key = reinterpret_cast(&data);
4445 int errorcode = pthread_key_create(key, NULL);
4546 assert(errorcode == 0);
4647 (void) errorcode;
47 data = (void*)key;
4848 }
4949
5050 ThreadLocalImpl::~ThreadLocalImpl() {
51 pthread_key_t* key = static_cast(data);
51 pthread_key_t* key = reinterpret_cast(&data);
5252 int errorcode = pthread_key_delete(*key);
5353 assert(errorcode == 0);
5454 (void) errorcode;
55 delete key;
5655 }
5756
5857 void ThreadLocalImpl::setInstance(const void* d) {
59 pthread_key_t* key = static_cast(data);
58 pthread_key_t* key = reinterpret_cast(&data);
6059 int errorcode = pthread_setspecific(*key, d);
6160 assert(errorcode == 0);
6261 (void) errorcode;
6362 }
6463
6564 const void* ThreadLocalImpl::getInstance() {
66 pthread_key_t* key = static_cast(data);
65 pthread_key_t* key = reinterpret_cast(&data);
6766 return pthread_getspecific(*key);
6867 }
6968
2121 namespace llvm {
2222 using namespace sys;
2323
24 ThreadLocalImpl::ThreadLocalImpl() {
25 DWORD* tls = new DWORD;
24 ThreadLocalImpl::ThreadLocalImpl() : data(0) {
25 typedef int SIZE_TOO_BIG[sizeof(DWORD) <= sizeof(data) ? 1 : -1];
26 DWORD* tls = reinterpret_cast(&data);
2627 *tls = TlsAlloc();
2728 assert(*tls != TLS_OUT_OF_INDEXES);
28 data = tls;
2929 }
3030
3131 ThreadLocalImpl::~ThreadLocalImpl() {
32 DWORD* tls = static_cast(data);
32 DWORD* tls = reinterpret_cast(&data);
3333 TlsFree(*tls);
34 delete tls;
3534 }
3635
3736 const void* ThreadLocalImpl::getInstance() {
38 DWORD* tls = static_cast(data);
37 DWORD* tls = reinterpret_cast(&data);
3938 return TlsGetValue(*tls);
4039 }
4140
4241 void ThreadLocalImpl::setInstance(const void* d){
43 DWORD* tls = static_cast(data);
42 DWORD* tls = reinterpret_cast(&data);
4443 int errorcode = TlsSetValue(*tls, const_cast(d));
4544 assert(errorcode != 0);
4645 (void)errorcode;