@@ -518,58 +518,7 @@ bool ThreadList::WillResume() {
518
518
519
519
collection::iterator pos, end = m_threads.end ();
520
520
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.
573
522
// if so then pick one and run it.
574
523
575
524
ThreadList run_me_only_list (m_process);
@@ -582,34 +531,90 @@ bool ThreadList::WillResume() {
582
531
// There are two special kinds of thread that have priority for "StopOthers":
583
532
// a "ShouldRunBeforePublicStop thread, or the currently selected thread. If
584
533
// we find one satisfying that critereon, put it here.
585
- ThreadSP stop_others_thread_sp;
586
-
534
+ ThreadSP thread_to_run;
587
535
for (pos = m_threads.begin (); pos != end; ++pos) {
588
536
ThreadSP thread_sp (*pos);
589
537
if (thread_sp->GetResumeState () != eStateSuspended &&
590
538
thread_sp->GetCurrentPlan ()->StopOthers ()) {
591
- if ((*pos) ->IsOperatingSystemPluginThread () &&
592
- !(*pos) ->GetBackingThread ())
539
+ if (thread_sp ->IsOperatingSystemPluginThread () &&
540
+ !thread_sp ->GetBackingThread ())
593
541
continue ;
594
542
595
543
// You can't say "stop others" and also want yourself to be suspended.
596
544
assert (thread_sp->GetCurrentPlan ()->RunState () != eStateSuspended);
597
545
run_me_only_list.AddThread (thread_sp);
598
546
599
547
if (thread_sp == GetSelectedThread ())
600
- stop_others_thread_sp = thread_sp;
601
-
548
+ thread_to_run = thread_sp;
549
+
602
550
if (thread_sp->ShouldRunBeforePublicStop ()) {
603
551
// 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;
605
553
break ;
606
554
}
607
555
}
608
556
}
609
557
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
+
610
615
bool need_to_resume = true ;
611
616
612
- if (run_me_only_list. GetSize ( false ) == 0 ) {
617
+ if (thread_to_run == nullptr ) {
613
618
// Everybody runs as they wish:
614
619
for (pos = m_threads.begin (); pos != end; ++pos) {
615
620
ThreadSP thread_sp (*pos);
@@ -622,19 +627,6 @@ bool ThreadList::WillResume() {
622
627
need_to_resume = false ;
623
628
}
624
629
} 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
-
638
630
for (pos = m_threads.begin (); pos != end; ++pos) {
639
631
ThreadSP thread_sp (*pos);
640
632
if (thread_sp == thread_to_run) {
0 commit comments