remote: get rid of all the T packets when syncing the thread list
This commit avoids the prune_threads call in the remote target's target_update_thread_list's implementation, eliminating all the "thread alive" RSP traffic (one packet per thread) whenever we fetch the thread list. IOW, this: Sending packet: $Tp2141.2150#82...Packet received: OK Sending packet: $Tp2141.214f#b7...Packet received: OK Sending packet: $Tp2141.2141#82...Packet received: OK ... more T packets; it's one per previously known live thread ... 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 Becomes: 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 Tested on x86_64 Fedora 20, native gdbserver: - tests the qXfer:threads:read method. Tested on x86_64 Fedora 20, native gdbserver with qXfer:threads:read force-disabled in gdbserver: - So that GDB falls back to the qfThreadInfo/qsThreadInfo method. And also manually smoked tested force disabling both qXfer:threads:read and qfThreadInfo/qsThreadInfo in gdbserver. gdb/ 2014-10-15 Pedro Alves <palves@redhat.com> * gdbthread.h (ALL_NON_EXITED_THREADS_SAFE): New macro. * remote.c (remote_update_thread_list): Skip calling prune_threads if any thread listing method is supported, and instead walk over the set of remote threads listed, deleting those that are not found in GDB's thread list.
This commit is contained in:
parent
e8032dde10
commit
ab970af197
|
@ -1,3 +1,11 @@
|
||||||
|
2014-10-15 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
* gdbthread.h (ALL_NON_EXITED_THREADS_SAFE): New macro.
|
||||||
|
* remote.c (remote_update_thread_list): Skip calling prune_threads
|
||||||
|
if any thread listing method is supported, and instead walk over
|
||||||
|
the set of remote threads listed, deleting those that are not
|
||||||
|
found in GDB's thread list.
|
||||||
|
|
||||||
2014-10-15 Pedro Alves <palves@redhat.com>
|
2014-10-15 Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
* ada-tasks.c (print_ada_task_info, task_command_1): Adjust.
|
* ada-tasks.c (print_ada_task_info, task_command_1): Adjust.
|
||||||
|
|
|
@ -354,6 +354,14 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
|
||||||
for (T = thread_list; T; T = T->next) \
|
for (T = thread_list; T; T = T->next) \
|
||||||
if ((T)->state != THREAD_EXITED)
|
if ((T)->state != THREAD_EXITED)
|
||||||
|
|
||||||
|
/* Like ALL_NON_EXITED_THREADS, but allows deleting the currently
|
||||||
|
iterated thread. */
|
||||||
|
#define ALL_NON_EXITED_THREADS_SAFE(T, TMP) \
|
||||||
|
for ((T) = thread_list; \
|
||||||
|
(T) != NULL ? ((TMP) = (T)->next, 1): 0; \
|
||||||
|
(T) = (TMP)) \
|
||||||
|
if ((T)->state != THREAD_EXITED)
|
||||||
|
|
||||||
extern int thread_count (void);
|
extern int thread_count (void);
|
||||||
|
|
||||||
/* Switch from one thread to another. */
|
/* Switch from one thread to another. */
|
||||||
|
|
38
gdb/remote.c
38
gdb/remote.c
|
@ -2762,9 +2762,7 @@ remote_update_thread_list (struct target_ops *ops)
|
||||||
struct remote_state *rs = get_remote_state ();
|
struct remote_state *rs = get_remote_state ();
|
||||||
struct threads_listing_context context;
|
struct threads_listing_context context;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
|
int got_list = 0;
|
||||||
/* Delete GDB-side threads no longer found on the target. */
|
|
||||||
prune_threads ();
|
|
||||||
|
|
||||||
context.items = NULL;
|
context.items = NULL;
|
||||||
old_chain = make_cleanup (clear_threads_listing_context, &context);
|
old_chain = make_cleanup (clear_threads_listing_context, &context);
|
||||||
|
@ -2778,8 +2776,31 @@ remote_update_thread_list (struct target_ops *ops)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct thread_item *item;
|
struct thread_item *item;
|
||||||
|
struct thread_info *tp, *tmp;
|
||||||
|
|
||||||
/* Now add threads we don't know about yet to our list. */
|
got_list = 1;
|
||||||
|
|
||||||
|
/* CONTEXT now holds the current thread list on the remote
|
||||||
|
target end. Delete GDB-side threads no longer found on the
|
||||||
|
target. */
|
||||||
|
ALL_NON_EXITED_THREADS_SAFE (tp, tmp)
|
||||||
|
{
|
||||||
|
for (i = 0;
|
||||||
|
VEC_iterate (thread_item_t, context.items, i, item);
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
if (ptid_equal (item->ptid, tp->ptid))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == VEC_length (thread_item_t, context.items))
|
||||||
|
{
|
||||||
|
/* Not found. */
|
||||||
|
delete_thread (tp->ptid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* And now add threads we don't know about yet to our list. */
|
||||||
for (i = 0;
|
for (i = 0;
|
||||||
VEC_iterate (thread_item_t, context.items, i, item);
|
VEC_iterate (thread_item_t, context.items, i, item);
|
||||||
++i)
|
++i)
|
||||||
|
@ -2803,6 +2824,15 @@ remote_update_thread_list (struct target_ops *ops)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!got_list)
|
||||||
|
{
|
||||||
|
/* If no thread listing method is supported, then query whether
|
||||||
|
each known thread is alive, one by one, with the T packet.
|
||||||
|
If the target doesn't support threads at all, then this is a
|
||||||
|
no-op. See remote_thread_alive. */
|
||||||
|
prune_threads ();
|
||||||
|
}
|
||||||
|
|
||||||
do_cleanups (old_chain);
|
do_cleanups (old_chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue