Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: src/IceTLS.h

Issue 872933002: Subzero: Second attempt at fixing MacOS 10.6 build. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Add llvm:: prefix Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/IceTLS.h
diff --git a/src/IceTLS.h b/src/IceTLS.h
new file mode 100644
index 0000000000000000000000000000000000000000..3fba80307e0a2414572e666e23d94a3796352519
--- /dev/null
+++ b/src/IceTLS.h
@@ -0,0 +1,100 @@
+//===- 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. The field will
+// ultimately be initialized to nullptr.
+//
+// ICE_TLS_INIT_FIELD(FieldName): Ensure the thread_local field is
+// properly initialized. This is intended to be called from within a
+// static method of the field's class after main() starts (to ensure
+// that the pthread library is fully initialized) but before any uses
+// of ICE_TLS_GET_FIELD or ICE_TLS_SET_FIELD.
+//
+// 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.
+
+// TODO(stichnot): Limit this define to only the platforms that
+// absolutely require it. And ideally, eventually remove this hack
+// altogether.
+#define ICE_THREAD_LOCAL_HACK
+#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__initStatus;
+//
+// The F__initStatus field is used to hold the result of the
+// pthread_key_create() call, where a zero value indicates success,
+// and a nonzero value indicates failure or that ICE_TLS_INIT_FIELD()
+// was never called.
+// 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) \
+ typedef Type FieldName##__type; \
+ static pthread_key_t FieldName##__key; \
+ static int FieldName##__initStatus
+#define ICE_TLS_DEFINE_FIELD(Type, ClassName, FieldName) \
+ pthread_key_t ClassName::FieldName##__key; \
+ int ClassName::FieldName##__initStatus = 1;
+#define ICE_TLS_INIT_FIELD(FieldName) \
+ if (FieldName##__initStatus) { \
+ FieldName##__initStatus = pthread_key_create(&FieldName##__key, nullptr); \
+ if (FieldName##__initStatus) \
+ llvm::report_fatal_error("Failed to create pthread key"); \
+ }
+#define ICE_TLS_GET_FIELD(FieldName) \
+ (assert(FieldName##__initStatus == 0), \
+ static_cast<FieldName##__type>(pthread_getspecific(FieldName##__key)))
+#define ICE_TLS_SET_FIELD(FieldName, Value) \
+ (assert(FieldName##__initStatus == 0), \
+ 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_INIT_FIELD(FieldName)
+#define ICE_TLS_GET_FIELD(FieldName) (FieldName)
+#define ICE_TLS_SET_FIELD(FieldName, Value) (FieldName = (Value))
+
+#endif // !ICE_THREAD_LOCAL_HACK
+
+#endif // SUBZERO_SRC_ICETLS_H
« no previous file with comments | « src/IceGlobalContext.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698