Index: src/IceTLS.h |
diff --git a/src/IceTLS.h b/src/IceTLS.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..b0f1a23117d3b0fabe44087d27eac1fd04cc9edf |
--- /dev/null |
+++ b/src/IceTLS.h |
@@ -0,0 +1,79 @@ |
+//===- subzero/src/IceTLS.h - thread_local workaround -----------*- C++ -*-===// |
+// |
+// The Subzero Code Generator |
+// |
+// This file is distributed under the University of Illinois Open Source |
+// License. See LICENSE.TXT for details. |
+// |
+//===----------------------------------------------------------------------===// |
+// |
+// This file defines macros for working around the lack of support for |
+// thread_local in MacOS 10.6. It assumes std::thread is written in |
+// terms of pthread. Define ICE_THREAD_LOCAL_HACK to enable the |
+// pthread workarounds. |
+// |
+//===----------------------------------------------------------------------===// |
+ |
+#ifndef SUBZERO_SRC_ICETLS_H |
+#define SUBZERO_SRC_ICETLS_H |
+ |
+#if defined(_MSC_VER) |
+#define ICE_ATTRIBUTE_TLS __declspec(thread) |
+#else // !_MSC_VER |
+#define ICE_ATTRIBUTE_TLS thread_local |
+#endif // !_MSC_VER |
+ |
+// Defines 4 macros for unifying thread_local and pthread: |
+// |
+// ICE_TLS_DECLARE_FIELD(Type, FieldName): Declare a static |
+// thread_local field inside the current class definition. "Type" |
+// needs to be a pointer type, such as int* or class Foo*. |
+// |
+// ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName): Define a static |
+// thread_local field outside of its class definition, and initialize |
+// it to nullptr. |
+// |
+// ICE_TLS_GET_FIELD(Type, FieldName): Read the value of the static |
+// thread_local field. Must be done within the context of its class. |
+// |
+// ICE_TLS_SET_FIELD(FieldName, Value): Write a value into the static |
+// thread_local field. Must be done within the context of its class. |
+ |
+#ifdef ICE_THREAD_LOCAL_HACK |
+ |
+// For a static thread_local field F of a class C, instead of |
+// declaring and defining C::F, we create two static fields: |
+// static pthread_key_t F__key; |
+// static int F__dummy; |
+// |
+// The F__dummy field is just used to hold the result of the |
+// pthread_key_create() call, which is executed as a static |
+// initializer. The F__key field is used as the argument to |
+// pthread_getspecific() and pthread_setspecific(). |
+ |
+#include <pthread.h> |
+ |
+#define ICE_TLS_DECLARE_FIELD(Type, FieldName) \ |
+ static pthread_key_t FieldName##__key; \ |
+ static int FieldName##__dummy |
+#define ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName) \ |
+ pthread_key_t ClassName::FieldName##__key; \ |
+ int ClassName::FieldName##__dummy = \ |
+ pthread_key_create(&ClassName::FieldName##__key, nullptr) |
+#define ICE_TLS_GET_FIELD(Type, FieldName) \ |
+ static_cast<Type>(pthread_getspecific(FieldName##__key)) |
JF
2015/01/25 04:37:01
Small thing I just thought about to make the diff
Jim Stichnoth
2015/01/25 18:58:40
Very nice, done.
|
+#define ICE_TLS_SET_FIELD(FieldName, Value) \ |
+ pthread_setspecific(FieldName##__key, (Value)) |
+ |
+#else // !ICE_THREAD_LOCAL_HACK |
+ |
+#define ICE_TLS_DECLARE_FIELD(Type, FieldName) \ |
+ static ICE_ATTRIBUTE_TLS Type FieldName |
+#define ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName) \ |
+ ICE_ATTRIBUTE_TLS Type ClassName::FieldName = nullptr |
+#define ICE_TLS_GET_FIELD(Type, FieldName) (FieldName) |
+#define ICE_TLS_SET_FIELD(FieldName, Value) (FieldName = (Value)) |
+ |
+#endif // !ICE_THREAD_LOCAL_HACK |
+ |
+#endif // SUBZERO_SRC_ICETLS_H |