@@ -518,58 +518,7 @@ bool ThreadList::WillResume() {
518518
519519 collection::iterator pos, end = m_threads.end ();
520520
521- // See if any thread wants to run stopping others. If it does, then we won't
522- // setup the other threads for resume, since they aren't going to get a
523- // chance to run. This is necessary because the SetupForResume might add
524- // "StopOthers" plans which would then get to be part of the who-gets-to-run
525- // negotiation, but they're coming in after the fact, and the threads that
526- // are already set up should take priority.
527-
528- bool wants_solo_run = false ;
529-
530- for (pos = m_threads.begin (); pos != end; ++pos) {
531- lldbassert ((*pos)->GetCurrentPlan () &&
532- " thread should not have null thread plan" );
533- if ((*pos)->GetResumeState () != eStateSuspended &&
534- (*pos)->GetCurrentPlan ()->StopOthers ()) {
535- if ((*pos)->IsOperatingSystemPluginThread () &&
536- !(*pos)->GetBackingThread ())
537- continue ;
538- wants_solo_run = true ;
539- break ;
540- }
541- }
542-
543- if (wants_solo_run) {
544- Log *log = GetLog (LLDBLog::Step);
545- if (log && log->GetVerbose ())
546- LLDB_LOGF (log, " Turning on notification of new threads while single "
547- " stepping a thread." );
548- m_process.StartNoticingNewThreads ();
549- } else {
550- Log *log = GetLog (LLDBLog::Step);
551- if (log && log->GetVerbose ())
552- LLDB_LOGF (log, " Turning off notification of new threads while single "
553- " stepping a thread." );
554- m_process.StopNoticingNewThreads ();
555- }
556-
557- // Give all the threads that are likely to run a last chance to set up their
558- // state before we negotiate who is actually going to get a chance to run...
559- // Don't set to resume suspended threads, and if any thread wanted to stop
560- // others, only call setup on the threads that request StopOthers...
561-
562- for (pos = m_threads.begin (); pos != end; ++pos) {
563- if ((*pos)->GetResumeState () != eStateSuspended &&
564- (!wants_solo_run || (*pos)->GetCurrentPlan ()->StopOthers ())) {
565- if ((*pos)->IsOperatingSystemPluginThread () &&
566- !(*pos)->GetBackingThread ())
567- continue ;
568- (*pos)->SetupForResume ();
569- }
570- }
571-
572- // Now go through the threads and see if any thread wants to run just itself.
521+ // Go through the threads and see if any thread wants to run just itself.
573522 // if so then pick one and run it.
574523
575524 ThreadList run_me_only_list (m_process);
@@ -582,34 +531,90 @@ bool ThreadList::WillResume() {
582531 // There are two special kinds of thread that have priority for "StopOthers":
583532 // a "ShouldRunBeforePublicStop thread, or the currently selected thread. If
584533 // we find one satisfying that critereon, put it here.
585- ThreadSP stop_others_thread_sp;
586-
534+ ThreadSP thread_to_run;
587535 for (pos = m_threads.begin (); pos != end; ++pos) {
588536 ThreadSP thread_sp (*pos);
589537 if (thread_sp->GetResumeState () != eStateSuspended &&
590538 thread_sp->GetCurrentPlan ()->StopOthers ()) {
591- if ((*pos) ->IsOperatingSystemPluginThread () &&
592- !(*pos) ->GetBackingThread ())
539+ if (thread_sp ->IsOperatingSystemPluginThread () &&
540+ !thread_sp ->GetBackingThread ())
593541 continue ;
594542
595543 // You can't say "stop others" and also want yourself to be suspended.
596544 assert (thread_sp->GetCurrentPlan ()->RunState () != eStateSuspended);
597545 run_me_only_list.AddThread (thread_sp);
598546
599547 if (thread_sp == GetSelectedThread ())
600- stop_others_thread_sp = thread_sp;
601-
548+ thread_to_run = thread_sp;
549+
602550 if (thread_sp->ShouldRunBeforePublicStop ()) {
603551 // This takes precedence, so if we find one of these, service it:
604- stop_others_thread_sp = thread_sp;
552+ thread_to_run = thread_sp;
605553 break ;
606554 }
607555 }
608556 }
609557
558+ if (run_me_only_list.GetSize (false ) > 0 && !thread_to_run) {
559+ if (run_me_only_list.GetSize (false ) == 1 ) {
560+ thread_to_run = run_me_only_list.GetThreadAtIndex (0 );
561+ } else {
562+ int random_thread =
563+ (int )((run_me_only_list.GetSize (false ) * (double )rand ()) /
564+ (RAND_MAX + 1.0 ));
565+ thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
566+ }
567+ }
568+
569+ // Give all the threads that are likely to run a last chance to set up their
570+ // state before we negotiate who is actually going to get a chance to run...
571+ // Don't set to resume suspended threads, and if any thread wanted to stop
572+ // others, only call setup on the threads that request StopOthers...
573+ if (thread_to_run != nullptr ) {
574+ // See if any thread wants to run stopping others. If it does, then we
575+ // won't setup the other threads for resume, since they aren't going to get
576+ // a chance to run. This is necessary because the SetupForResume might add
577+ // "StopOthers" plans which would then get to be part of the who-gets-to-run
578+ // negotiation, but they're coming in after the fact, and the threads that
579+ // are already set up should take priority.
580+ thread_to_run->SetupForResume ();
581+ } else {
582+ for (pos = m_threads.begin (); pos != end; ++pos) {
583+ ThreadSP thread_sp (*pos);
584+ if (thread_sp->GetResumeState () != eStateSuspended) {
585+ if (thread_sp->IsOperatingSystemPluginThread () &&
586+ !thread_sp->GetBackingThread ())
587+ continue ;
588+ if (thread_sp->SetupForResume ()) {
589+ // You can't say "stop others" and also want yourself to be suspended.
590+ assert (thread_sp->GetCurrentPlan ()->RunState () != eStateSuspended);
591+ thread_to_run = thread_sp;
592+ if (thread_sp->ShouldRunBeforePublicStop ()) {
593+ // This takes precedence, so if we find one of these, service it:
594+ break ;
595+ }
596+ }
597+ }
598+ }
599+ }
600+
601+ if (thread_to_run != nullptr ) {
602+ Log *log = GetLog (LLDBLog::Step);
603+ if (log && log->GetVerbose ())
604+ LLDB_LOGF (log, " Turning on notification of new threads while single "
605+ " stepping a thread." );
606+ m_process.StartNoticingNewThreads ();
607+ } else {
608+ Log *log = GetLog (LLDBLog::Step);
609+ if (log && log->GetVerbose ())
610+ LLDB_LOGF (log, " Turning off notification of new threads while single "
611+ " stepping a thread." );
612+ m_process.StopNoticingNewThreads ();
613+ }
614+
610615 bool need_to_resume = true ;
611616
612- if (run_me_only_list. GetSize ( false ) == 0 ) {
617+ if (thread_to_run == nullptr ) {
613618 // Everybody runs as they wish:
614619 for (pos = m_threads.begin (); pos != end; ++pos) {
615620 ThreadSP thread_sp (*pos);
@@ -622,19 +627,6 @@ bool ThreadList::WillResume() {
622627 need_to_resume = false ;
623628 }
624629 } else {
625- ThreadSP thread_to_run;
626-
627- if (stop_others_thread_sp) {
628- thread_to_run = stop_others_thread_sp;
629- } else if (run_me_only_list.GetSize (false ) == 1 ) {
630- thread_to_run = run_me_only_list.GetThreadAtIndex (0 );
631- } else {
632- int random_thread =
633- (int )((run_me_only_list.GetSize (false ) * (double )rand ()) /
634- (RAND_MAX + 1.0 ));
635- thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
636- }
637-
638630 for (pos = m_threads.begin (); pos != end; ++pos) {
639631 ThreadSP thread_sp (*pos);
640632 if (thread_sp == thread_to_run) {
0 commit comments