static struct thread_info *
random_pending_event_thread (inferior *inf, ptid_t waiton_ptid)
{
- int num_events = 0;
+ process_stratum_target *proc_target = inf->process_target ();
+ thread_info *thread
+ = proc_target->random_resumed_with_pending_wait_status (inf, waiton_ptid);
- auto has_event = [&] (thread_info *tp)
+ if (thread == nullptr)
{
- return (tp->ptid.matches (waiton_ptid)
- && tp->resumed ()
- && tp->has_pending_waitstatus ());
- };
-
- /* First see how many events we have. Count only resumed threads
- that have an event pending. */
- for (thread_info *tp : inf->non_exited_threads ())
- if (has_event (tp))
- num_events++;
-
- if (num_events == 0)
- return NULL;
-
- /* Now randomly pick a thread out of those that have had events. */
- int random_selector = (int) ((num_events * (double) rand ())
- / (RAND_MAX + 1.0));
-
- if (num_events > 1)
- infrun_debug_printf ("Found %d events, selecting #%d",
- num_events, random_selector);
+ infrun_debug_printf ("None found.");
+ return nullptr;
+ }
- /* Select the Nth thread that has had an event. */
- for (thread_info *tp : inf->non_exited_threads ())
- if (has_event (tp))
- if (random_selector-- == 0)
- return tp;
+ infrun_debug_printf ("Found %s.", target_pid_to_str (thread->ptid).c_str ());
+ gdb_assert (thread->resumed ());
+ gdb_assert (thread->has_pending_waitstatus ());
- gdb_assert_not_reached ("event thread not found");
+ return thread;
}
/* Wrapper for target_wait that first checks whether threads have
#include "defs.h"
#include "process-stratum-target.h"
#include "inferior.h"
+#include <algorithm>
process_stratum_target::~process_stratum_target ()
{
/* See process-stratum-target.h. */
+thread_info *
+process_stratum_target::random_resumed_with_pending_wait_status
+ (inferior *inf, ptid_t filter_ptid)
+{
+ auto matches = [inf, filter_ptid] (const thread_info &thread)
+ {
+ return thread.inf == inf && thread.ptid.matches (filter_ptid);
+ };
+
+ /* First see how many matching events we have. */
+ const auto &l = m_resumed_with_pending_wait_status;
+ unsigned int count = std::count_if (l.begin (), l.end (), matches);
+
+ if (count == 0)
+ return nullptr;
+
+ /* Now randomly pick a thread out of those that match the criteria. */
+ int random_selector
+ = (int) ((count * (double) rand ()) / (RAND_MAX + 1.0));
+
+ if (count > 1)
+ infrun_debug_printf ("Found %u events, selecting #%d",
+ count, random_selector);
+
+ /* Select the Nth thread that matches. */
+ auto it = std::find_if (l.begin (), l.end (),
+ [&random_selector, &matches]
+ (const thread_info &thread)
+ {
+ if (!matches (thread))
+ return false;
+
+ return random_selector-- == 0;
+ });
+
+ gdb_assert (it != l.end ());
+
+ return &*it;
+}
+
+/* See process-stratum-target.h. */
+
std::set<process_stratum_target *>
all_non_exited_process_targets ()
{
bool has_resumed_with_pending_wait_status () const
{ return !m_resumed_with_pending_wait_status.empty (); }
+ /* Return a random resumed thread with pending wait status belonging to INF
+ and matching FILTER_PTID. */
+ thread_info *random_resumed_with_pending_wait_status
+ (inferior *inf, ptid_t filter_ptid);
+
/* The connection number. Visible in "info connections". */
int connection_number = 0;