Skip to content

Commit 85c339c

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm, isolates] Set Isolate::mutator_thread_ under the thread registry lock.
Fixes data race with read in Isolate::ScheduleInterrupts. TEST=tsan Bug: #59649 Change-Id: I89dc54160f9c63ef5bdd9704a24e6eaeee1b3f4a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/398543 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent 546eff8 commit 85c339c

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

runtime/vm/thread.cc

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,8 @@ void Thread::ExitIsolate(bool isolate_shutdown) {
474474
thread->ResetMutatorState();
475475
thread->ResetState();
476476
SuspendDartMutatorThreadInternal(thread, VMTag::kInvalidTagId);
477-
FreeActiveThread(thread, /*bypass_safepoint=*/false);
477+
FreeActiveThread(thread, isolate, /*is_dart_mutator=*/true,
478+
/*bypass_safepoint=*/false);
478479
}
479480

480481
// To let VM's thread pool (if we run on it) know that this thread is
@@ -488,7 +489,7 @@ void Thread::ExitIsolate(bool isolate_shutdown) {
488489
bool Thread::EnterIsolateGroupAsHelper(IsolateGroup* isolate_group,
489490
TaskKind kind,
490491
bool bypass_safepoint) {
491-
Thread* thread = AddActiveThread(isolate_group, nullptr,
492+
Thread* thread = AddActiveThread(isolate_group, /*isolate=*/nullptr,
492493
/*is_dart_mutator=*/false, bypass_safepoint);
493494
if (thread != nullptr) {
494495
thread->SetupState(kind);
@@ -512,13 +513,14 @@ void Thread::ExitIsolateGroupAsHelper(bool bypass_safepoint) {
512513
thread->ResetMutatorState();
513514
thread->ResetState();
514515
SuspendThreadInternal(thread, VMTag::kInvalidTagId);
515-
FreeActiveThread(thread, bypass_safepoint);
516+
FreeActiveThread(thread, /*isolate=*/nullptr, /*is_dart_mutator=*/false,
517+
bypass_safepoint);
516518
}
517519

518520
bool Thread::EnterIsolateGroupAsNonMutator(IsolateGroup* isolate_group,
519521
TaskKind kind) {
520522
Thread* thread =
521-
AddActiveThread(isolate_group, nullptr,
523+
AddActiveThread(isolate_group, /*isolate=*/nullptr,
522524
/*is_dart_mutator=*/false, /*bypass_safepoint=*/true);
523525
if (thread != nullptr) {
524526
thread->SetupState(kind);
@@ -537,7 +539,8 @@ void Thread::ExitIsolateGroupAsNonMutator() {
537539

538540
thread->ResetState();
539541
SuspendThreadInternal(thread, VMTag::kInvalidTagId);
540-
FreeActiveThread(thread, /*bypass_safepoint=*/true);
542+
FreeActiveThread(thread, /*isolate=*/nullptr, /*is_dart_mutator=*/false,
543+
/*bypass_safepoint=*/true);
541544
}
542545

543546
void Thread::ResumeDartMutatorThreadInternal(Thread* thread) {
@@ -621,6 +624,10 @@ Thread* Thread::AddActiveThread(IsolateGroup* group,
621624
thread->isolate_ = isolate; // May be nullptr.
622625
thread->isolate_group_ = group;
623626
thread->scheduled_dart_mutator_isolate_ = isolate;
627+
if (is_dart_mutator) {
628+
ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread());
629+
isolate->mutator_thread_ = thread;
630+
}
624631

625632
// We start at being at-safepoint (in case any safepoint operation is
626633
// in-progress, we'll check into it once leaving the safepoint)
@@ -632,7 +639,10 @@ Thread* Thread::AddActiveThread(IsolateGroup* group,
632639
return thread;
633640
}
634641

635-
void Thread::FreeActiveThread(Thread* thread, bool bypass_safepoint) {
642+
void Thread::FreeActiveThread(Thread* thread,
643+
Isolate* isolate,
644+
bool is_dart_mutator,
645+
bool bypass_safepoint) {
636646
ASSERT(!thread->HasActiveState());
637647
ASSERT(!thread->IsAtSafepoint());
638648

@@ -672,6 +682,10 @@ void Thread::FreeActiveThread(Thread* thread, bool bypass_safepoint) {
672682
thread->isolate_ = nullptr;
673683
thread->isolate_group_ = nullptr;
674684
thread->scheduled_dart_mutator_isolate_ = nullptr;
685+
if (is_dart_mutator) {
686+
ASSERT(thread_registry->threads_lock()->IsOwnedByCurrentThread());
687+
isolate->mutator_thread_ = nullptr;
688+
}
675689
thread->set_execution_state(Thread::kThreadInNative);
676690
thread->stack_limit_.store(0);
677691
thread->safepoint_state_ = 0;
@@ -1454,7 +1468,6 @@ void Thread::ResetMutatorState() {
14541468

14551469
void Thread::SetupDartMutatorState(Isolate* isolate) {
14561470
field_table_values_ = isolate->field_table_->table();
1457-
isolate->mutator_thread_ = this;
14581471

14591472
SetupDartMutatorStateDependingOnSnapshot(isolate->group());
14601473
}
@@ -1490,7 +1503,6 @@ void Thread::SetupDartMutatorStateDependingOnSnapshot(IsolateGroup* group) {
14901503
void Thread::ResetDartMutatorState(Isolate* isolate) {
14911504
ASSERT(execution_state() == Thread::kThreadInVM);
14921505

1493-
isolate->mutator_thread_ = nullptr;
14941506
is_unwind_in_progress_ = false;
14951507

14961508
field_table_values_ = nullptr;

runtime/vm/thread.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,10 @@ class Thread : public ThreadState {
14811481
// Releases a active mutator threads from the thread registry.
14821482
//
14831483
// Thread needs to be at-safepoint.
1484-
static void FreeActiveThread(Thread* thread, bool bypass_safepoint);
1484+
static void FreeActiveThread(Thread* thread,
1485+
Isolate* isolate,
1486+
bool is_dart_mutator,
1487+
bool bypass_safepoint);
14851488

14861489
static void SetCurrent(Thread* current) { OSThread::SetCurrentTLS(current); }
14871490

0 commit comments

Comments
 (0)