aboutsummaryrefslogtreecommitdiff
path: root/gdb/remote.c
diff options
context:
space:
mode:
authorPedro Alves <palves@redhat.com>2014-10-15 22:44:00 +0100
committerPedro Alves <palves@redhat.com>2014-10-15 22:54:13 +0100
commite8032dde10b743253125d7defb5f5503b21c1d26 (patch)
tree5fff3d0537e28657279d4b86d752718cb4443d42 /gdb/remote.c
parent6dc54d9124e8ef9ef3611e0ef3eefef5dcd87ee4 (diff)
downloadgdb-e8032dde10b743253125d7defb5f5503b21c1d26.zip
gdb-e8032dde10b743253125d7defb5f5503b21c1d26.tar.gz
gdb-e8032dde10b743253125d7defb5f5503b21c1d26.tar.bz2
Push pruning old threads down to the target
When GDB wants to sync the thread list with the target's (e.g., due to "info threads"), it calls update_thread_list: update_thread_list (void) { prune_threads (); target_find_new_threads (); update_threads_executing (); } And then prune_threads does: prune_threads (void) { struct thread_info *tp, *next; for (tp = thread_list; tp; tp = next) { next = tp->next; if (!thread_alive (tp)) delete_thread (tp->ptid); } } Calling thread_live on each thread one by one is expensive. E.g., on Linux, it ends up doing kill(SIG0) once for each thread. Not a big deal, but still a bunch of syscalls... With the remote target, it's cumbersome. That thread_alive call ends up generating one T packet per thread: Sending packet: $Tp2141.2150#82...Packet received: OK Sending packet: $Tp2141.214f#b7...Packet received: OK Sending packet: $Tp2141.2141#82...Packet received: OK Sending packet: $qXfer:threads:read::0,fff#03...Packet received: l<threads>\n<thread id="p2141.2141" core="2"/>\n<thread id="p2141.214f" core="1"/>\n<thread id="p2141.2150" core="2"/>\n</threads>\n That seems a bit silly when target_find_new_threads method implementations will always fetch the whole current set of target threads, and then add those that are not in GDB's thread list, to GDB's thread list. This patch thus pushes down the responsibility of pruning dead threads to the target_find_new_threads method instead, so a target may implement pruning dead threads however it wants. Once we do that, target_find_new_threads becomes a misnomer, so the patch renames it to target_update_thread_list. The patch doesn't attempt to do any optimization to any target yet. It simply exports prune_threads, and makes all implementations of target_update_thread_list call that. It's meant to be a no-op. gdb/ 2014-10-15 Pedro Alves <palves@redhat.com> * ada-tasks.c (print_ada_task_info, task_command_1): Adjust. * bsd-uthread.c (bsd_uthread_find_new_threads): Rename to ... (bsd_uthread_update_thread_list): ... this. Call prune_threads. (bsd_uthread_target): Adjust. * corelow.c (core_open): Adjust. * dec-thread.c (dec_thread_find_new_threads): Update comment. (dec_thread_update_thread_list): New function. (init_dec_thread_ops): Adjust. * gdbthread.h (prune_threads): New declaration. * linux-thread-db.c (thread_db_find_new_threads): Rename to ... (thread_db_update_thread_list): ... this. Call prune_threads. (init_thread_db_ops): Adjust. * nto-procfs.c (procfs_find_new_threads): Rename to ... (procfs_update_thread_list): ... this. Call prune_threads. (procfs_attach, procfs_create_inferior, init_procfs_targets): Adjust. * obsd-nat.c (obsd_find_new_threads): Rename to ... (obsd_update_thread_list): ... this. Call prune_threads. (obsd_add_target): Adjust. * procfs.c (procfs_target): Adjust. (procfs_notice_thread): Update comment. (procfs_find_new_threads): Rename to ... (procfs_update_thread_list): ... this. Call prune_threads. * ravenscar-thread.c (ravenscar_update_inferior_ptid): Update comment. (ravenscar_wait): Adjust. (ravenscar_find_new_threads): Rename to ... (ravenscar_update_thread_list): ... this. Call prune_threads. (init_ravenscar_thread_ops): Adjust. * record-btrace.c (record_btrace_find_new_threads): Rename to ... (record_btrace_update_thread_list): ... this. Adjust comment. (init_record_btrace_ops): Adjust. * remote.c (remote_threads_info): Rename to ... (remote_update_thread_list): ... this. Call prune_threads. (remote_start_remote, extended_remote_attach_1, init_remote_ops): Adjust. * sol-thread.c (check_for_thread_db): Adjust. (sol_find_new_threads_callback): Rename to ... (sol_update_thread_list_callback): ... this. (sol_find_new_threads): Rename to ... (sol_update_thread_list): ... this. Call prune_threads. Adjust. (sol_get_ada_task_ptid, init_sol_thread_ops): Adjust. * target-delegates.c: Regenerate. * target.c (target_find_new_threads): Rename to ... (target_update_thread_list): ... this. * target.h (struct target_ops): Rename to_find_new_threads field to to_update_thread_list. (target_find_new_threads): Rename to ... (target_update_thread_list): ... this. * thread.c (prune_threads): Make extern. (update_thread_list): Adjust.
Diffstat (limited to 'gdb/remote.c')
-rw-r--r--gdb/remote.c17
1 files changed, 10 insertions, 7 deletions
diff --git a/gdb/remote.c b/gdb/remote.c
index 3fa835f..cd85fd5 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2753,16 +2753,19 @@ remote_get_threads_with_qthreadinfo (struct target_ops *ops,
return 0;
}
-/* Implement the to_find_new_threads function for the remote
+/* Implement the to_update_thread_list function for the remote
targets. */
static void
-remote_threads_info (struct target_ops *ops)
+remote_update_thread_list (struct target_ops *ops)
{
struct remote_state *rs = get_remote_state ();
struct threads_listing_context context;
struct cleanup *old_chain;
+ /* Delete GDB-side threads no longer found on the target. */
+ prune_threads ();
+
context.items = NULL;
old_chain = make_cleanup (clear_threads_listing_context, &context);
@@ -2776,7 +2779,7 @@ remote_threads_info (struct target_ops *ops)
int i;
struct thread_item *item;
- /* Add threads we don't know about yet to our list. */
+ /* Now add threads we don't know about yet to our list. */
for (i = 0;
VEC_iterate (thread_item_t, context.items, i, item);
++i)
@@ -3424,7 +3427,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
controlling. We default to adding them in the running state.
The '?' query below will then tell us about which threads are
stopped. */
- remote_threads_info (target);
+ remote_update_thread_list (target);
}
else if (packet_support (PACKET_QNonStop) == PACKET_ENABLE)
{
@@ -3476,7 +3479,7 @@ remote_start_remote (int from_tty, struct target_ops *target, int extended_p)
}
/* Fetch thread list. */
- target_find_new_threads ();
+ target_update_thread_list ();
/* Let the stub know that we want it to return the thread. */
set_continue_thread (minus_one_ptid);
@@ -4446,7 +4449,7 @@ extended_remote_attach_1 (struct target_ops *target, const char *args,
struct thread_info *thread;
/* Get list of threads. */
- remote_threads_info (target);
+ remote_update_thread_list (target);
thread = first_thread_of_process (pid);
if (thread)
@@ -11456,7 +11459,7 @@ Specify the serial device it is connected to\n\
remote_ops.to_pass_signals = remote_pass_signals;
remote_ops.to_program_signals = remote_program_signals;
remote_ops.to_thread_alive = remote_thread_alive;
- remote_ops.to_find_new_threads = remote_threads_info;
+ remote_ops.to_update_thread_list = remote_update_thread_list;
remote_ops.to_pid_to_str = remote_pid_to_str;
remote_ops.to_extra_thread_info = remote_threads_extra_info;
remote_ops.to_get_ada_task_ptid = remote_get_ada_task_ptid;