[PATCH] D14288: [tsan] Alternative ThreadState storage for OS X
Kuba Brecka via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 3 14:28:55 PST 2015
kubabrecka updated this revision to Diff 39114.
kubabrecka added a comment.
Updating patch to address comments.
> This is not async-signal-safe. A thread can receive a signal concurrent with the first call to cur_thread(), and signal handler will also call cur_thread().
I see. Could you please suggest a way to make it async-signal-safe?
http://reviews.llvm.org/D14288
Files:
lib/tsan/rtl/tsan_platform_mac.cc
lib/tsan/rtl/tsan_rtl.cc
lib/tsan/rtl/tsan_rtl.h
Index: lib/tsan/rtl/tsan_rtl.h
===================================================================
--- lib/tsan/rtl/tsan_rtl.h
+++ lib/tsan/rtl/tsan_rtl.h
@@ -409,13 +409,16 @@
uptr tls_addr, uptr tls_size);
};
-#ifndef SANITIZER_GO
+#if !defined(SANITIZER_GO) && !SANITIZER_MAC
__attribute__((tls_model("initial-exec")))
extern THREADLOCAL char cur_thread_placeholder[];
INLINE ThreadState *cur_thread() {
return reinterpret_cast<ThreadState *>(&cur_thread_placeholder);
}
#endif
+#if !defined(SANITIZER_GO) && SANITIZER_MAC
+ThreadState *cur_thread();
+#endif
class ThreadContext : public ThreadContextBase {
public:
Index: lib/tsan/rtl/tsan_rtl.cc
===================================================================
--- lib/tsan/rtl/tsan_rtl.cc
+++ lib/tsan/rtl/tsan_rtl.cc
@@ -44,7 +44,7 @@
namespace __tsan {
-#ifndef SANITIZER_GO
+#if !defined(SANITIZER_GO) && !SANITIZER_MAC
THREADLOCAL char cur_thread_placeholder[sizeof(ThreadState)] ALIGNED(64);
#endif
static char ctx_placeholder[sizeof(Context)] ALIGNED(64);
Index: lib/tsan/rtl/tsan_platform_mac.cc
===================================================================
--- lib/tsan/rtl/tsan_platform_mac.cc
+++ lib/tsan/rtl/tsan_platform_mac.cc
@@ -40,6 +40,37 @@
namespace __tsan {
+#ifndef SANITIZER_GO
+// On OS X, accessing TLVs via __thread or manually by using pthread_key_* is
+// problematic, because there are several places where interceptors are called
+// when TLVs are not accessible (early process startup, thread cleanup, ...).
+// The following provides a "poor man's TLV" implementation, where we use the
+// shadow memory of the pointer returned by pthread_self() to store a pointer to
+// the ThreadState object. The main thread's ThreadState pointer is stored
+// separately in a static variable, because we need to access it even before the
+// shadow memory is set up.
+// TODO(kuba.brecka): This currently leaks the ThreadState objects as we never
+// deallocate them.
+ThreadState *cur_thread() {
+ static uptr main_thread_identity = 0;
+ static ThreadState *main_thread_state = nullptr;
+
+ ThreadState **fake_tls;
+ uptr thread_identity = (uptr)pthread_self();
+ if (thread_identity == main_thread_identity || main_thread_identity == 0) {
+ if (main_thread_identity == 0) main_thread_identity = thread_identity;
+ fake_tls = &main_thread_state;
+ } else {
+ fake_tls = (ThreadState **)MemToShadow(thread_identity);
+ }
+ if (*fake_tls == nullptr) {
+ *fake_tls = (ThreadState *)InternalAlloc(sizeof(ThreadState), nullptr);
+ internal_memset(*fake_tls, 0, sizeof(ThreadState));
+ }
+ return *fake_tls;
+}
+#endif
+
uptr GetShadowMemoryConsumption() {
return 0;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D14288.39114.patch
Type: text/x-patch
Size: 2732 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20151103/de7732c3/attachment.bin>
More information about the llvm-commits
mailing list