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