[compiler-rt] r319004 - Prevent Thread Exited/Joined events race
Matt Morehouse via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 08:12:37 PST 2017
Looks like this patch is breaking the ppc64be-linux bot
<http://lab.llvm.org:8011/builders/sanitizer-ppc64be-linux/builds/4708>.
Check-tsan is timing out. This may have introduced a deadlock.
On Sun, Nov 26, 2017 at 12:20 PM, Kamil Rytarowski via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: kamil
> Date: Sun Nov 26 12:20:42 2017
> New Revision: 319004
>
> URL: http://llvm.org/viewvc/llvm-project?rev=319004&view=rev
> Log:
> Prevent Thread Exited/Joined events race
>
> Summary:
> Add atomic verification to ensure that Thread is Joined after marking it
> Finished.
>
> It is required for NetBSD in order to prevent Thread Exited/Joined race,
> that may occur when native system libpthread(3) cannot be reliably traced
> in a way to guarantee that the mentioned events happen one after another.
>
> This change fixes at least TSan and LSan on NetBSD.
>
> Sponsored by <The NetBSD Foundation>
>
> Reviewers: joerg, dvyukov, vitalybuka
>
> Reviewed By: dvyukov
>
> Subscribers: llvm-commits, kubamracek, #sanitizers
>
> Tags: #sanitizers
>
> Differential Revision: https://reviews.llvm.org/D40294
>
> Modified:
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> thread_registry.cc
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> sanitizer_common/sanitizer_thread_registry.cc?rev=319004&
> r1=319003&r2=319004&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.cc
> Sun Nov 26 12:20:42 2017
> @@ -21,6 +21,7 @@ ThreadContextBase::ThreadContextBase(u32
> status(ThreadStatusInvalid),
> detached(false), workerthread(false), parent_tid(0), next(0) {
> name[0] = '\0';
> + atomic_store(&thread_destroyed, 0, memory_order_release);
> }
>
> ThreadContextBase::~ThreadContextBase() {
> @@ -44,6 +45,14 @@ void ThreadContextBase::SetDead() {
> OnDead();
> }
>
> +void ThreadContextBase::SetDestroyed() {
> + atomic_store(&thread_destroyed, 1, memory_order_release);
> +}
> +
> +bool ThreadContextBase::GetDestroyed() {
> + return !!atomic_load(&thread_destroyed, memory_order_acquire);
> +}
> +
> void ThreadContextBase::SetJoined(void *arg) {
> // FIXME(dvyukov): print message and continue (it's user error).
> CHECK_EQ(false, detached);
> @@ -85,6 +94,7 @@ void ThreadContextBase::SetCreated(uptr
> void ThreadContextBase::Reset() {
> status = ThreadStatusInvalid;
> SetName(0);
> + atomic_store(&thread_destroyed, 0, memory_order_release);
> OnReset();
> }
>
> @@ -243,16 +253,25 @@ void ThreadRegistry::DetachThread(u32 ti
> }
>
> void ThreadRegistry::JoinThread(u32 tid, void *arg) {
> - BlockingMutexLock l(&mtx_);
> - CHECK_LT(tid, n_contexts_);
> - ThreadContextBase *tctx = threads_[tid];
> - CHECK_NE(tctx, 0);
> - if (tctx->status == ThreadStatusInvalid) {
> - Report("%s: Join of non-existent thread\n", SanitizerToolName);
> - return;
> - }
> - tctx->SetJoined(arg);
> - QuarantinePush(tctx);
> + bool destroyed = false;
> + do {
> + {
> + BlockingMutexLock l(&mtx_);
> + CHECK_LT(tid, n_contexts_);
> + ThreadContextBase *tctx = threads_[tid];
> + CHECK_NE(tctx, 0);
> + if (tctx->status == ThreadStatusInvalid) {
> + Report("%s: Join of non-existent thread\n", SanitizerToolName);
> + return;
> + }
> + if ((destroyed = tctx->GetDestroyed())) {
> + tctx->SetJoined(arg);
> + QuarantinePush(tctx);
> + }
> + }
> + if (!destroyed)
> + internal_sched_yield();
> + } while (!destroyed);
> }
>
> // Normally this is called when the thread is about to exit. If
> @@ -281,6 +300,7 @@ void ThreadRegistry::FinishThread(u32 ti
> tctx->SetDead();
> QuarantinePush(tctx);
> }
> + tctx->SetDestroyed();
> }
>
> void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread,
>
> Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_
> thread_registry.h
> URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/
> sanitizer_common/sanitizer_thread_registry.h?rev=319004&
> r1=319003&r2=319004&view=diff
> ============================================================
> ==================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_thread_registry.h
> Sun Nov 26 12:20:42 2017
> @@ -50,6 +50,8 @@ class ThreadContextBase {
> u32 parent_tid;
> ThreadContextBase *next; // For storing thread contexts in a list.
>
> + atomic_uint32_t thread_destroyed; // To address race of Joined vs
> Finished
> +
> void SetName(const char *new_name);
>
> void SetDead();
> @@ -60,6 +62,9 @@ class ThreadContextBase {
> u32 _parent_tid, void *arg);
> void Reset();
>
> + void SetDestroyed();
> + bool GetDestroyed();
> +
> // The following methods may be overriden by subclasses.
> // Some of them take opaque arg that may be optionally be used
> // by subclasses.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20171127/6f17cceb/attachment.html>
More information about the llvm-commits
mailing list