summaryrefslogtreecommitdiff
path: root/gdb/target.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2016-10-26 11:08:28 +0100
committerPedro Alves <palves@redhat.com>2016-10-26 16:22:50 +0100
commit85ad3aaf403d2104c82010494d3d4a93a36e2e6f (patch)
treeffe792616bfdd77915a3c5246e43e9bbdaf7a875 /gdb/target.c
parent5a04c4cf5df6d13596e79e7b84520cbe245a5a4d (diff)
downloadbinutils-gdb-85ad3aaf403d2104c82010494d3d4a93a36e2e6f.tar.gz
gdb: Coalesce/aggregate (async) vCont packets/actions
Currently, with "maint set target-non-stop on", that is, when gdb connects with the non-stop/asynchronous variant of the remote protocol, even with "set non-stop off", GDB always sends one vCont packet per thread resumed. This patch makes GDB aggregate and coalesce vCont packets, so we send vCont packets like "vCont;s:p1.1;c" in non-stop mode too. Basically, this is done by: - Adding a new target method target_commit_resume that is called after calling target_resume one or more times. When resuming a batch of threads, we'll only call target_commit_resume once after calling target_resume for all threads. - Making the remote target defer sending the actual vCont packet to target_commit_resume. Special care must be taken to avoid sending a vCont action with a "wildcard" thread-id (all threads of process / all threads) when that would resume threads/processes that should not be resumed. See remote_commit_resume comments for details. Unlike all-stop's remote_resume implementation, this handles the case of too many actions resulting in a too-big vCont packet, by flushing the vCont packet and starting a new one. E.g., imagining that the "c" action in: vCont;s:1;c overflows the packet buffer, we split the actions like: vCont;s:1 vCont;c Tested on x86_64 Fedora 20, with and without "maint set target-non-stop on". Also tested with a hack that makes remote_commit_resume flush the vCont packet after every action appended (which caught a few bugs). gdb/ChangeLog: 2016-10-26 Pedro Alves <palves@redhat.com> * inferior.h (ALL_NON_EXITED_INFERIORS): New macro. * infrun.c (do_target_resume): Call target_commit_resume. (proceed): Defer target_commit_resume while looping over threads, resuming them. Call target_commit_resume at the end. * record-btrace.c (record_btrace_commit_resume): New function. (init_record_btrace_ops): Install it as to_commit_resume method. * record-full.c (record_full_commit_resume): New function. (record_full_wait_1): Call the beneath target's to_commit_resume method. (init_record_full_ops): Install record_full_commit_resume as to_commit_resume method. * remote.c (struct private_thread_info) <last_resume_step, last_resume_sig, vcont_resumed>: New fields. (remote_add_thread): Set the new thread's vcont_resumed flag. (demand_private_info): Delete. (get_private_info_thread, get_private_info_ptid): New functions. (remote_update_thread_list): Adjust. (process_initial_stop_replies): Clear the thread's vcont_resumed flag. (remote_resume): If connected in non-stop mode, record the resume request and return early. (struct private_inferior): New. (struct vcont_builder): New. (vcont_builder_restart, vcont_builder_flush) (vcont_builder_push_action): New functions. (MAX_ACTION_SIZE): New macro. (remote_commit_resume): New function. (thread_pending_fork_status, is_pending_fork_parent_thread): New functions. (check_pending_event_prevents_wildcard_vcont_callback) (check_pending_events_prevent_wildcard_vcont): New functions. (process_stop_reply): Adjust. Clear the thread's vcont_resumed flag. (init_remote_ops): Install remote_commit_resume. * target-delegates.c: Regenerate. * target.c (defer_target_commit_resume): New global. (target_commit_resume, make_cleanup_defer_target_commit_resume): New functions. * target.h (struct target_ops) <to_commit_resume>: New field. (target_resume): Update comments. (target_commit_resume): New declaration.
Diffstat (limited to 'gdb/target.c')
-rw-r--r--gdb/target.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/gdb/target.c b/gdb/target.c
index cb89e750866..246d292ab2e 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -2329,6 +2329,34 @@ target_resume (ptid_t ptid, int step, enum gdb_signal signal)
clear_inline_frame_state (ptid);
}
+/* If true, target_commit_resume is a nop. */
+static int defer_target_commit_resume;
+
+/* See target.h. */
+
+void
+target_commit_resume (void)
+{
+ struct target_ops *t;
+
+ if (defer_target_commit_resume)
+ return;
+
+ current_target.to_commit_resume (&current_target);
+}
+
+/* See target.h. */
+
+struct cleanup *
+make_cleanup_defer_target_commit_resume (void)
+{
+ struct cleanup *old_chain;
+
+ old_chain = make_cleanup_restore_integer (&defer_target_commit_resume);
+ defer_target_commit_resume = 1;
+ return old_chain;
+}
+
void
target_pass_signals (int numsigs, unsigned char *pass_signals)
{