@@ -94,7 +94,7 @@ DEFINE_FLAG_HANDLER(DeterministicModeHandler,
9494
9595DEFINE_FLAG (bool ,
9696 disable_thread_pool_limit,
97- true ,
97+ false ,
9898 " Disables the limit of the thread pool (simulates custom embedder "
9999 " with custom message handler on unlimited number of threads)." );
100100
@@ -380,10 +380,17 @@ IsolateGroup::IsolateGroup(std::shared_ptr<IsolateGroupSource> source,
380380{
381381 FlagsCopyFrom (api_flags);
382382 if (!is_vm_isolate) {
383- thread_pool_.reset (
384- new MutatorThreadPool (this , FLAG_disable_thread_pool_limit
385- ? 0
386- : Scavenger::MaxMutatorThreadCount ()));
383+ intptr_t max_worker_threads;
384+ if (FLAG_disable_thread_pool_limit) {
385+ max_worker_threads = 0 ;
386+ } else {
387+ // There needs to be at least one more thread than active mutators slots
388+ // so that there is a thread waiting in IncreaseMutatorCount (instead of
389+ // unscheduled task sitting in the thread pool's queue) to eventually
390+ // timeout and trigger StealActiveMutators.
391+ max_worker_threads = Scavenger::MaxMutatorThreadCount () + 2 ;
392+ }
393+ thread_pool_.reset (new MutatorThreadPool (this , max_worker_threads));
387394 }
388395 {
389396 WriteRwLocker wl (ThreadState::Current (), isolate_groups_rwlock_);
@@ -587,14 +594,12 @@ void IsolateGroup::set_saved_unlinked_calls(const Array& saved_unlinked_calls) {
587594
588595static constexpr intptr_t kActiveMutatorPreemptionTimeout = 120 ;
589596
590- void IsolateGroup::IncreaseMutatorCount (Isolate* mutator,
591- bool is_nested_reenter) {
592- ASSERT (mutator->group () == this );
593-
597+ void IsolateGroup::IncreaseMutatorCount (Thread* thread,
598+ bool is_nested_reenter,
599+ bool was_stolen) {
594600 // If the mutator was temporarily blocked on a worker thread, we have to
595601 // unblock the worker thread again.
596- if (is_nested_reenter) {
597- ASSERT (mutator->mutator_thread () != nullptr );
602+ if (is_nested_reenter || was_stolen) {
598603 thread_pool ()->MarkCurrentWorkerAsUnBlocked ();
599604 }
600605
@@ -610,17 +615,28 @@ void IsolateGroup::IncreaseMutatorCount(Isolate* mutator,
610615 waiting_mutators_++;
611616 bool timed_out = false ;
612617 if (has_timeout_waiter_) {
613- ml.Wait ();
618+ if (was_stolen) {
619+ ml.WaitWithSafepointCheck (thread);
620+ } else {
621+ ml.Wait ();
622+ }
614623 } else {
615624 has_timeout_waiter_ = true ;
616- timed_out =
617- ml.Wait (kActiveMutatorPreemptionTimeout ) == Monitor::kTimedOut ;
625+ if (was_stolen) {
626+ timed_out = ml.WaitWithSafepointCheck (
627+ thread, kActiveMutatorPreemptionTimeout ) ==
628+ Monitor::kTimedOut ;
629+ } else {
630+ timed_out =
631+ ml.Wait (kActiveMutatorPreemptionTimeout ) == Monitor::kTimedOut ;
632+ }
618633 has_timeout_waiter_ = false ;
619634 }
620635 waiting_mutators_--;
621636
622637 if (timed_out) {
623- active_mutators_ -= thread_registry ()->StealActiveMutators ();
638+ active_mutators_ -=
639+ thread_registry ()->StealActiveMutators (thread_pool ());
624640 ASSERT (active_mutators_ >= 0 );
625641 }
626642 }
@@ -636,39 +652,6 @@ void IsolateGroup::IncreaseMutatorCount(Isolate* mutator,
636652 }
637653}
638654
639- void IsolateGroup::ReincreaseMutatorCount (Thread* thread) {
640- MonitorLocker ml (active_mutators_monitor_.get ());
641- ASSERT (active_mutators_ <= max_active_mutators_);
642- while (active_mutators_ == max_active_mutators_) {
643- waiting_mutators_++;
644- bool timed_out = false ;
645- if (has_timeout_waiter_) {
646- ml.WaitWithSafepointCheck (thread);
647- } else {
648- has_timeout_waiter_ = true ;
649- timed_out =
650- ml.WaitWithSafepointCheck (thread, kActiveMutatorPreemptionTimeout ) ==
651- Monitor::kTimedOut ;
652- has_timeout_waiter_ = false ;
653- }
654- waiting_mutators_--;
655-
656- if (timed_out) {
657- active_mutators_ -= thread_registry ()->StealActiveMutators ();
658- ASSERT (active_mutators_ >= 0 );
659- }
660- }
661- active_mutators_++;
662-
663- // StealActiveMutators may cause multiple slots to become available, but
664- // does not do a NotifyAll to prevent the case of thousands of threads
665- // waking up to claim a ~dozen slots, so we keep notifying while there are
666- // both available slots and waiters.
667- if ((active_mutators_ != max_active_mutators_) && (waiting_mutators_ > 0 )) {
668- ml.Notify ();
669- }
670- }
671-
672655void IsolateGroup::DecreaseMutatorCount (Isolate* mutator, bool is_nested_exit) {
673656 ASSERT (mutator->group () == this );
674657
0 commit comments