diff options
author | Simon Marchi <simon.marchi@polymtl.ca> | 2017-10-14 09:11:12 -0400 |
---|---|---|
committer | Simon Marchi <simon.marchi@ericsson.com> | 2017-10-14 09:11:12 -0400 |
commit | 9c80ecd646a604fadcc290fca23b34c9454f5feb (patch) | |
tree | ceef0c74d101d2dc12a83b6487b96f417ea22046 /gdb/gdbserver/gdbthread.h | |
parent | 9179355e655d78cf44ffdfb432e134eabceaebab (diff) | |
download | binutils-9c80ecd646a604fadcc290fca23b34c9454f5feb.zip binutils-9c80ecd646a604fadcc290fca23b34c9454f5feb.tar.gz binutils-9c80ecd646a604fadcc290fca23b34c9454f5feb.tar.bz2 |
gdbserver: use std::list for all_threads
Remove the usage of inferior_list for the all_threads list in
gdbserver. The entry field in thread_info is removed, and replaced by a
simple ptid field.
I added some functions to iterate (for_each_thread) and find threads
(find_thread). However, changing all the users of find_inferior & co to
use these new functions would have made the patch way too big. So I
opted instead to make find_inferior & co some shims, so that the
existing code only needs to be updated minimally. We can then update
the existing code to use the new functions incrementally (I've started
to do the work, but I'll post it afterwards, see [1] if you want a peek).
This patch has been built-tested on all relevant platforms, except
lynx. I also regtested using the native-gdbserver and
native-extended-gdbserver boards on x86.
[1] https://github.com/simark/binutils-gdb/commits/kill-inferior-list-entry
gdb/gdbserver/ChangeLog:
* inferiors.h: (struct inferior_list): Remove.
(struct inferior_list_entry); Remove.
(add_inferior_to_list, clear_inferior_list, one_inferior_p,
A_I_NEXT, ALL_INFERIORS_TYPE, ALL_INFERIORS, remove_inferior,
get_first_inferior): Remove.
(for_each_inferior, for_each_inferior_with_data, find_inferior,
find_inferior_id, find_inferior_in_random): Change signature.
* inferiors.c (all_threads): Change type to
std::list<thread_info *>.
(get_thread): Remove macro.
(find_inferior, find_inferior_id): Change signature, implement
using find_thread.
(find_inferior_in_random): Change signature, implement using
find_thread_in_random.
(for_each_inferior, for_each_inferior_with_data): Change
signature, implement using for_each_thread.
(add_inferior_to_list, remove_inferior): Remove.
(add_thread, get_first_thread, thread_of_pid,
find_any_thread_of_pid, free_one_thread, remove_thread): Update.
(get_first_inferior, one_inferior_p, clear_inferior_list):
Remove.
(clear_inferiors, get_thread_process): Update.
* gdbthread.h: Include <list>.
(struct thread_info) <entry>: Remove field.
<id>: New field.
(all_threads): Change type to std::list<thread_info *>.
(get_first_inferior): Add doc.
(find_thread, for_each_thread, find_thread_in_random): New
functions.
(current_ptid, pid_of, ptid_of, lwpid_of): Update.
* linux-arm-low.c (update_registers_callback): Update.
* linux-low.c (second_thread_of_pid_p): Update.
(kill_one_lwp_callback, linux_detach_lwp_callback,
delete_lwp_callback, status_pending_p_callback, same_lwp,
find_lwp_pid, num_lwps, iterate_over_lwps_filter,
iterate_over_lwps, not_stopped_callback,
resume_stopped_resumed_lwps, count_events_callback,
select_singlestep_lwp_callback, select_event_lwp_callback,
unsuspend_one_lwp, linux_wait_1, send_sigstop_callback,
suspend_and_send_sigstop_callback, wait_for_sigstop,
stuck_in_jump_pad_callback, move_out_of_jump_pad_callback,
lwp_running, linux_set_resume_request, resume_status_pending_p,
need_step_over_p, start_step_over, linux_resume_one_thread,
proceed_one_lwp, unsuspend_and_proceed_one_lwp,
reset_lwp_ptrace_options_callback): Update.
* linux-mips-low.c (update_watch_registers_callback): Update.
* regcache.c (regcache_invalidate_one, regcache_invalidate):
Update.
(free_register_cache_thread_one): Remove.
(regcache_release): Update.
* server.c (handle_btrace_enable_bts, handle_btrace_enable_pt,
handle_qxfer_threads_worker): Update.
(handle_query): Update, use list iterator.
(visit_actioned_threads, handle_pending_status,
queue_stop_reply_callback, gdb_wants_all_threads_stopped,
clear_pending_status_callback, set_pending_status_callback,
find_status_pending_thread_callback, handle_status,
process_serial_event): Update.
* target.c (thread_search_callback): Update.
* thread-db.c (thread_db_get_tls_address): Update.
* tracepoint.c (tracepoint_finished_step, tracepoint_was_hit):
Update.
* win32-i386-low.c (update_debug_registers_callback): Update.
* win32-low.c (delete_thread_info, child_delete_thread,
continue_one_thread, suspend_one_thread,
get_child_debug_event): Adjust.
Diffstat (limited to 'gdb/gdbserver/gdbthread.h')
-rw-r--r-- | gdb/gdbserver/gdbthread.h | 91 |
1 files changed, 83 insertions, 8 deletions
diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h index 93688a3..8ace051 100644 --- a/gdb/gdbserver/gdbthread.h +++ b/gdb/gdbserver/gdbthread.h @@ -22,14 +22,15 @@ #include "common-gdbthread.h" #include "inferiors.h" +#include <list> + struct btrace_target_info; struct regcache; struct thread_info { - /* This must appear first. See inferiors.h. - The list iterator functions assume it. */ - struct inferior_list_entry entry; + /* The id of this thread. */ + ptid_t id; void *target_data; struct regcache *regcache_data; @@ -72,11 +73,13 @@ struct thread_info struct btrace_target_info *btrace; }; -extern struct inferior_list all_threads; +extern std::list<thread_info *> all_threads; void remove_thread (struct thread_info *thread); struct thread_info *add_thread (ptid_t ptid, void *target_data); +/* Return a pointer to the first thread, or NULL if there isn't one. */ + struct thread_info *get_first_thread (void); struct thread_info *find_thread_ptid (ptid_t ptid); @@ -85,15 +88,87 @@ struct thread_info *find_thread_ptid (ptid_t ptid); found. */ struct thread_info *find_any_thread_of_pid (int pid); +/* Find the first thread for which FUNC returns true. Return NULL if no thread + satisfying FUNC is found. */ + +template <typename Func> +static thread_info * +find_thread (Func func) +{ + std::list<thread_info *>::iterator next, cur = all_threads.begin (); + + while (cur != all_threads.end ()) + { + next = cur; + next++; + + if (func (*cur)) + return *cur; + + cur = next; + } + + return NULL; +} + +/* Invoke FUNC for each thread. */ + +template <typename Func> +static void +for_each_thread (Func func) +{ + std::list<thread_info *>::iterator next, cur = all_threads.begin (); + + while (cur != all_threads.end ()) + { + next = cur; + next++; + func (*cur); + cur = next; + } +} + +/* Find the a random thread for which FUNC (THREAD) returns true. If + no entry is found then return NULL. */ + +template <typename Func> +static thread_info * +find_thread_in_random (Func func) +{ + int count = 0; + int random_selector; + + /* First count how many interesting entries we have. */ + for_each_thread ([&] (thread_info *thread) { + if (func (thread)) + count++; + }); + + if (count == 0) + return NULL; + + /* Now randomly pick an entry out of those. */ + random_selector = (int) + ((count * (double) rand ()) / (RAND_MAX + 1.0)); + + thread_info *thread = find_thread ([&] (thread_info *thread) { + return func (thread) && (random_selector-- == 0); + }); + + gdb_assert (thread != NULL); + + return thread; +} + /* Get current thread ID (Linux task ID). */ -#define current_ptid (current_thread->entry.id) +#define current_ptid (current_thread->id) /* Get the ptid of THREAD. */ static inline ptid_t ptid_of (const thread_info *thread) { - return thread->entry.id; + return thread->id; } /* Get the pid of THREAD. */ @@ -101,7 +176,7 @@ ptid_of (const thread_info *thread) static inline int pid_of (const thread_info *thread) { - return thread->entry.id.pid (); + return thread->id.pid (); } /* Get the lwp of THREAD. */ @@ -109,7 +184,7 @@ pid_of (const thread_info *thread) static inline long lwpid_of (const thread_info *thread) { - return thread->entry.id.lwp (); + return thread->id.lwp (); } /* Create a cleanup to restore current_thread. */ |