diff options
author | Pedro Alves <palves@redhat.com> | 2014-10-15 22:44:00 +0100 |
---|---|---|
committer | Pedro Alves <palves@redhat.com> | 2014-10-15 22:54:13 +0100 |
commit | e8032dde10b743253125d7defb5f5503b21c1d26 (patch) | |
tree | 5fff3d0537e28657279d4b86d752718cb4443d42 /gdb/sol-thread.c | |
parent | 6dc54d9124e8ef9ef3611e0ef3eefef5dcd87ee4 (diff) | |
download | gdb-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/sol-thread.c')
-rw-r--r-- | gdb/sol-thread.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c index 88293c3..9993dff 100644 --- a/gdb/sol-thread.c +++ b/gdb/sol-thread.c @@ -624,7 +624,7 @@ check_for_thread_db (void) if (ptid_get_pid (ptid) != -1) inferior_ptid = ptid; - target_find_new_threads (); + target_update_thread_list (); break; default: @@ -1056,11 +1056,11 @@ solaris_pid_to_str (struct target_ops *ops, ptid_t ptid) } -/* Worker bee for find_new_threads. Callback function that gets +/* Worker bee for update_thread_list. Callback function that gets called once per user-level thread (i.e. not for LWP's). */ static int -sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored) +sol_update_thread_list_callback (const td_thrhandle_t *th, void *ignored) { td_err_e retval; td_thrinfo_t ti; @@ -1078,15 +1078,18 @@ sol_find_new_threads_callback (const td_thrhandle_t *th, void *ignored) } static void -sol_find_new_threads (struct target_ops *ops) +sol_update_thread_list (struct target_ops *ops) { struct target_ops *beneath = find_target_beneath (ops); - /* First Find any new LWP's. */ - beneath->to_find_new_threads (beneath); + /* Delete dead threads. */ + prune_threads (); + + /* Find any new LWP's. */ + beneath->to_update_thread_list (beneath); /* Then find any new user-level threads. */ - p_td_ta_thr_iter (main_ta, sol_find_new_threads_callback, (void *) 0, + p_td_ta_thr_iter (main_ta, sol_update_thread_list_callback, (void *) 0, TD_THR_ANY_STATE, TD_THR_LOWEST_PRIORITY, TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS); } @@ -1200,7 +1203,7 @@ sol_get_ada_task_ptid (struct target_ops *self, long lwp, long thread) { /* The list of threads is probably not up to date. Find any thread that is missing from the list, and try again. */ - sol_find_new_threads (¤t_target); + sol_update_thread_list (¤t_target); thread_info = iterate_over_threads (thread_db_find_thread_from_tid, &thread); } @@ -1225,7 +1228,7 @@ init_sol_thread_ops (void) sol_thread_ops.to_mourn_inferior = sol_thread_mourn_inferior; sol_thread_ops.to_thread_alive = sol_thread_alive; sol_thread_ops.to_pid_to_str = solaris_pid_to_str; - sol_thread_ops.to_find_new_threads = sol_find_new_threads; + sol_thread_ops.to_update_thread_list = sol_update_thread_list; sol_thread_ops.to_stratum = thread_stratum; sol_thread_ops.to_get_ada_task_ptid = sol_get_ada_task_ptid; sol_thread_ops.to_magic = OPS_MAGIC; |