aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Marchi <simon.marchi@polymtl.ca>2021-05-28 00:33:35 -0400
committerSimon Marchi <simon.marchi@polymtl.ca>2021-07-12 20:46:53 -0400
commit273dadf2c20b93ef579367c42c255fcf4a3a2522 (patch)
treed1870ed8113000565dc093003a46b7bc4182175c
parenta66f72981979a1bda60805b8554e0c78c4a39a21 (diff)
downloadbinutils-273dadf2c20b93ef579367c42c255fcf4a3a2522.zip
binutils-273dadf2c20b93ef579367c42c255fcf4a3a2522.tar.gz
binutils-273dadf2c20b93ef579367c42c255fcf4a3a2522.tar.bz2
gdb: optimize check for resumed threads with pending wait status in maybe_set_commit_resumed_all_targets
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
-rw-r--r--gdb/infrun.c10
-rw-r--r--gdb/process-stratum-target.h5
2 files changed, 6 insertions, 9 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 6c652ea..bec8e83 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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",
diff --git a/gdb/process-stratum-target.h b/gdb/process-stratum-target.h
index f037280..6bd8bc3 100644
--- a/gdb/process-stratum-target.h
+++ b/gdb/process-stratum-target.h
@@ -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;