gdb: optimize check for resumed threads with pending wait status in maybe_set_commit_...
authorSimon Marchi <simon.marchi@polymtl.ca>
Fri, 28 May 2021 04:33:35 +0000 (00:33 -0400)
committerSimon Marchi <simon.marchi@polymtl.ca>
Tue, 13 Jul 2021 00:46:53 +0000 (20:46 -0400)
Consider a test case where many threads (thousands) keep hitting a
breakpoint whose condition evaluates to false.
maybe_set_commit_resumed_all_targets is called at each handled event,
when the scoped_disable_commit_resumed object in fetch_inferior_event is
reset_and_commit-ed.  One particularly expensive check in there is
whether the target has at least one resumed thread with a pending wait
status (in which case, we don't want to commit the resumed threads, as
we want to consume this status first).  It is currently implemented as
walking all threads of the target.

Since we now maintain a per-target list of resumed threads with pending
status, we can do this check efficiently, by checking whether that list
is empty or not.

Add the process_stratum_target::has_resumed_with_pending_wait_status
method for this, and use it in maybe_set_commit_resumed_all_targets.

Change-Id: Ia1595baa1b358338f94fc3cb3af7f27092dad5b6

gdb/infrun.c
gdb/process-stratum-target.h

index 6c652ea3677b4f84702fc5f1447419fb606ef895..bec8e83e1936ab2a22e71665175e30e25f30c28c 100644 (file)
@@ -2800,15 +2800,7 @@ maybe_set_commit_resumed_all_targets ()
         status to report, handle it before requiring the target to
         commit its resumed threads: handling the status might lead to
         resuming more threads.  */
-      bool has_thread_with_pending_status = false;
-      for (thread_info *thread : all_non_exited_threads (proc_target))
-       if (thread->resumed () && thread->has_pending_waitstatus ())
-         {
-           has_thread_with_pending_status = true;
-           break;
-         }
-
-      if (has_thread_with_pending_status)
+      if (proc_target->has_resumed_with_pending_wait_status ())
        {
          infrun_debug_printf ("not requesting commit-resumed for target %s, a"
                               " thread has a pending waitstatus",
index f03728088d38ede78c7be49ca8f817f82300da9a..6bd8bc37b5ec1aa1faf979334dd578a9e6c5316d 100644 (file)
@@ -88,6 +88,11 @@ public:
      target's "resumed with pending wait status" list.  */
   void maybe_remove_resumed_with_pending_wait_status (thread_info *thread);
 
+  /* Return true if this target has at least one resumed thread with a pending
+     wait status.  */
+  bool has_resumed_with_pending_wait_status () const
+  { return !m_resumed_with_pending_wait_status.empty (); }
+
   /* The connection number.  Visible in "info connections".  */
   int connection_number = 0;