diff options
author | Pedro Alves <palves@redhat.com> | 2016-10-26 11:08:28 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2016-10-26 16:22:50 +0100 |
commit | 85ad3aaf403d2104c82010494d3d4a93a36e2e6f (patch) | |
tree | ffe792616bfdd77915a3c5246e43e9bbdaf7a875 /gdb/target-delegates.c | |
parent | 5a04c4cf5df6d13596e79e7b84520cbe245a5a4d (diff) | |
download | gdb-85ad3aaf403d2104c82010494d3d4a93a36e2e6f.zip gdb-85ad3aaf403d2104c82010494d3d4a93a36e2e6f.tar.gz gdb-85ad3aaf403d2104c82010494d3d4a93a36e2e6f.tar.bz2 |
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-delegates.c')
-rw-r--r-- | gdb/target-delegates.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/gdb/target-delegates.c b/gdb/target-delegates.c index 57e7939..73e45dd 100644 --- a/gdb/target-delegates.c +++ b/gdb/target-delegates.c @@ -109,6 +109,28 @@ debug_resume (struct target_ops *self, ptid_t arg1, int arg2, enum gdb_signal ar fputs_unfiltered (")\n", gdb_stdlog); } +static void +delegate_commit_resume (struct target_ops *self) +{ + self = self->beneath; + self->to_commit_resume (self); +} + +static void +tdefault_commit_resume (struct target_ops *self) +{ +} + +static void +debug_commit_resume (struct target_ops *self) +{ + fprintf_unfiltered (gdb_stdlog, "-> %s->to_commit_resume (...)\n", debug_target.to_shortname); + debug_target.to_commit_resume (&debug_target); + fprintf_unfiltered (gdb_stdlog, "<- %s->to_commit_resume (", debug_target.to_shortname); + target_debug_print_struct_target_ops_p (&debug_target); + fputs_unfiltered (")\n", gdb_stdlog); +} + static ptid_t delegate_wait (struct target_ops *self, ptid_t arg1, struct target_waitstatus *arg2, int arg3) { @@ -4108,6 +4130,8 @@ install_delegators (struct target_ops *ops) ops->to_disconnect = delegate_disconnect; if (ops->to_resume == NULL) ops->to_resume = delegate_resume; + if (ops->to_commit_resume == NULL) + ops->to_commit_resume = delegate_commit_resume; if (ops->to_wait == NULL) ops->to_wait = delegate_wait; if (ops->to_fetch_registers == NULL) @@ -4413,6 +4437,7 @@ install_dummy_methods (struct target_ops *ops) ops->to_detach = tdefault_detach; ops->to_disconnect = tdefault_disconnect; ops->to_resume = tdefault_resume; + ops->to_commit_resume = tdefault_commit_resume; ops->to_wait = default_target_wait; ops->to_fetch_registers = tdefault_fetch_registers; ops->to_store_registers = tdefault_store_registers; @@ -4570,6 +4595,7 @@ init_debug_target (struct target_ops *ops) ops->to_detach = debug_detach; ops->to_disconnect = debug_disconnect; ops->to_resume = debug_resume; + ops->to_commit_resume = debug_commit_resume; ops->to_wait = debug_wait; ops->to_fetch_registers = debug_fetch_registers; ops->to_store_registers = debug_store_registers; |