+2017-10-14 Simon Marchi <simon.marchi@polymtl.ca>
+
+ * 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.
+
2017-10-14 Simon Marchi <simon.marchi@polymtl.ca>
* gdbthread.h (ptid_of, pid_of, lwpid_of): New functions.
#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;
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);
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. */
static inline int
pid_of (const thread_info *thread)
{
- return thread->entry.id.pid ();
+ return thread->id.pid ();
}
/* Get the lwp of 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. */
#include "dll.h"
std::list<process_info *> all_processes;
-struct inferior_list all_threads;
+std::list<thread_info *> all_threads;
struct thread_info *current_thread;
-#define get_thread(inf) ((struct thread_info *)(inf))
-
/* The current working directory used to start the inferior. */
static const char *current_inferior_cwd = NULL;
-void
-add_inferior_to_list (struct inferior_list *list,
- struct inferior_list_entry *new_inferior)
+thread_info *
+find_inferior (std::list<thread_info *> *thread_list,
+ int (*func) (thread_info *, void *),
+ void *arg)
{
- new_inferior->next = NULL;
- if (list->tail != NULL)
- list->tail->next = new_inferior;
- else
- list->head = new_inferior;
- list->tail = new_inferior;
-}
+ gdb_assert (thread_list == &all_threads);
-/* Invoke ACTION for each inferior in LIST. */
+ return find_thread ([&] (thread_info *thread) {
+ return func (thread, arg);
+ });
+}
-void
-for_each_inferior (struct inferior_list *list,
- void (*action) (struct inferior_list_entry *))
+thread_info *
+find_inferior_id (std::list<thread_info *> *thread_list, ptid_t id)
{
- struct inferior_list_entry *cur = list->head, *next;
-
- while (cur != NULL)
- {
- next = cur->next;
- (*action) (cur);
- cur = next;
- }
-}
+ gdb_assert (thread_list == &all_threads);
-/* Invoke ACTION for each inferior in LIST, passing DATA to ACTION. */
+ return find_thread ([&] (thread_info *thread) {
+ return thread->id == id;
+ });
+}
-void
-for_each_inferior_with_data (struct inferior_list *list,
- void (*action) (struct inferior_list_entry *,
- void *),
- void *data)
+thread_info *
+find_inferior_in_random (std::list<thread_info *> *thread_list,
+ int (*func) (thread_info *, void *),
+ void *arg)
{
- struct inferior_list_entry *cur = list->head, *next;
-
- while (cur != NULL)
- {
- next = cur->next;
- (*action) (cur, data);
- cur = next;
- }
+ gdb_assert (thread_list == &all_threads);
+
+ return find_thread_in_random ([&] (thread_info *thread) {
+ return func (thread, arg);
+ });
}
void
-remove_inferior (struct inferior_list *list,
- struct inferior_list_entry *entry)
+for_each_inferior (std::list<thread_info *> *thread_list,
+ void (*action) (thread_info *))
{
- struct inferior_list_entry **cur;
-
- if (list->head == entry)
- {
- list->head = entry->next;
- if (list->tail == entry)
- list->tail = list->head;
- return;
- }
+ gdb_assert (thread_list == &all_threads);
- cur = &list->head;
- while (*cur && (*cur)->next != entry)
- cur = &(*cur)->next;
-
- if (*cur == NULL)
- return;
+ for_each_thread ([&] (thread_info *thread) {
+ action (thread);
+ });
+}
- (*cur)->next = entry->next;
+void
+for_each_inferior_with_data (std::list<thread_info *> *thread_list,
+ void (*action) (thread_info *, void *),
+ void *data)
+{
+ gdb_assert (thread_list == &all_threads);
- if (list->tail == entry)
- list->tail = *cur;
+ for_each_thread ([&] (thread_info *thread) {
+ action (thread, data);
+ });
}
struct thread_info *
{
struct thread_info *new_thread = XCNEW (struct thread_info);
- new_thread->entry.id = thread_id;
+ new_thread->id = thread_id;
new_thread->last_resume_kind = resume_continue;
new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
- add_inferior_to_list (&all_threads, &new_thread->entry);
+ all_threads.push_back (new_thread);
if (current_thread == NULL)
current_thread = new_thread;
return new_thread;
}
-/* Wrapper around get_first_inferior to return a struct thread_info *. */
+/* See gdbthread.h. */
struct thread_info *
get_first_thread (void)
{
- return (struct thread_info *) get_first_inferior (&all_threads);
+ if (!all_threads.empty ())
+ return all_threads.front ();
+ else
+ return NULL;
}
struct thread_info *
matches a PID. */
static int
-thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
+thread_of_pid (thread_info *entry, void *pid_p)
{
int pid = *(int *) pid_p;
struct thread_info *
find_any_thread_of_pid (int pid)
{
- struct inferior_list_entry *entry;
-
- entry = find_inferior (&all_threads, thread_of_pid, &pid);
-
- return (struct thread_info *) entry;
+ return find_inferior (&all_threads, thread_of_pid, &pid);
}
static void
-free_one_thread (struct inferior_list_entry *inf)
+free_one_thread (thread_info *thread)
{
- struct thread_info *thread = get_thread (inf);
free_register_cache (thread_regcache_data (thread));
free (thread);
}
target_disable_btrace (thread->btrace);
discard_queued_stop_replies (ptid_of (thread));
- remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
- free_one_thread (&thread->entry);
+ all_threads.remove (thread);
+ free_one_thread (thread);
if (current_thread == thread)
current_thread = NULL;
}
-/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
- This is for cases where the caller needs a thread, but doesn't care
- which one. */
-
-struct inferior_list_entry *
-get_first_inferior (struct inferior_list *list)
-{
- if (list->head != NULL)
- return list->head;
- return NULL;
-}
-
-/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
- returns non-zero. If no entry is found then return NULL. */
-
-struct inferior_list_entry *
-find_inferior (struct inferior_list *list,
- int (*func) (struct inferior_list_entry *, void *), void *arg)
-{
- struct inferior_list_entry *inf = list->head;
-
- while (inf != NULL)
- {
- struct inferior_list_entry *next;
-
- next = inf->next;
- if ((*func) (inf, arg))
- return inf;
- inf = next;
- }
-
- return NULL;
-}
-
-/* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
- returns non-zero. If no entry is found then return NULL. */
-
-struct inferior_list_entry *
-find_inferior_in_random (struct inferior_list *list,
- int (*func) (struct inferior_list_entry *, void *),
- void *arg)
-{
- struct inferior_list_entry *inf = list->head;
- int count = 0;
- int random_selector;
-
- /* First count how many interesting entries we have. */
- while (inf != NULL)
- {
- struct inferior_list_entry *next;
-
- next = inf->next;
- if ((*func) (inf, arg))
- count++;
- inf = next;
- }
-
- if (count == 0)
- return NULL;
-
- /* Now randomly pick an entry out of those. */
- random_selector = (int)
- ((count * (double) rand ()) / (RAND_MAX + 1.0));
-
- inf = list->head;
- while (inf != NULL)
- {
- struct inferior_list_entry *next;
-
- next = inf->next;
- if ((*func) (inf, arg) && (random_selector-- == 0))
- return inf;
- inf = next;
- }
-
- gdb_assert_not_reached ("failed to find an inferior in random.");
- return NULL;
-}
-
-struct inferior_list_entry *
-find_inferior_id (struct inferior_list *list, ptid_t id)
-{
- struct inferior_list_entry *inf = list->head;
-
- while (inf != NULL)
- {
- if (ptid_equal (inf->id, id))
- return inf;
- inf = inf->next;
- }
-
- return NULL;
-}
-
void *
thread_target_data (struct thread_info *thread)
{
thread->regcache_data = data;
}
-/* Return true if LIST has exactly one entry. */
-
-int
-one_inferior_p (struct inferior_list *list)
-{
- return list->head != NULL && list->head == list->tail;
-}
-
-/* Reset head,tail of LIST, assuming all entries have already been freed. */
-
-void
-clear_inferior_list (struct inferior_list *list)
-{
- list->head = NULL;
- list->tail = NULL;
-}
-
void
clear_inferiors (void)
{
for_each_inferior (&all_threads, free_one_thread);
- clear_inferior_list (&all_threads);
+ all_threads.clear ();
clear_dlls ();
struct process_info *
get_thread_process (const struct thread_info *thread)
{
- int pid = ptid_get_pid (thread->entry.id);
- return find_process_pid (pid);
+ return find_process_pid (thread->id.pid ());
}
struct process_info *
#include "gdb_vecs.h"
#include <list>
-/* Generic information for tracking a list of ``inferiors'' - threads,
- processes, etc. */
-struct inferior_list
-{
- struct inferior_list_entry *head;
- struct inferior_list_entry *tail;
-};
-struct inferior_list_entry
-{
- ptid_t id;
- struct inferior_list_entry *next;
-};
-
struct thread_info;
struct regcache;
struct target_desc;
extern std::list<process_info *> all_processes;
-void add_inferior_to_list (struct inferior_list *list,
- struct inferior_list_entry *new_inferior);
-void for_each_inferior (struct inferior_list *list,
- void (*action) (struct inferior_list_entry *));
-
-void for_each_inferior_with_data
- (struct inferior_list *list,
- void (*action) (struct inferior_list_entry *, void *),
- void *data);
-
-void clear_inferior_list (struct inferior_list *list);
-
-int one_inferior_p (struct inferior_list *list);
-
-/* Helper for ALL_INFERIORS_TYPE. Gets the next element starting at
- CUR, if CUR is not NULL. */
-#define A_I_NEXT(type, list, cur) \
- ((cur) != NULL \
- ? (type *) ((struct inferior_list_entry *) cur)->next \
- : NULL)
-
-/* Iterate over all inferiors of type TYPE in LIST, open loop
- style. */
-#define ALL_INFERIORS_TYPE(type, list, cur, tmp) \
- for ((cur) = (type *) (list)->head, (tmp) = A_I_NEXT (type, list, cur); \
- (cur) != NULL; \
- (cur) = (tmp), (tmp) = A_I_NEXT (type, list, cur))
-
-/* Iterate over all inferiors in LIST, open loop style. */
-#define ALL_INFERIORS(list, cur, tmp) \
- ALL_INFERIORS_TYPE (struct inferior_list_entry, list, cur, tmp)
-
/* Invoke FUNC for each process. */
template <typename Func>
}
extern struct thread_info *current_thread;
-void remove_inferior (struct inferior_list *list,
- struct inferior_list_entry *entry);
-
-struct inferior_list_entry *get_first_inferior (struct inferior_list *list);
/* Return the first process in the processes list. */
struct process_info *get_first_process (void);
int have_attached_inferiors_p (void);
void clear_inferiors (void);
-struct inferior_list_entry *find_inferior
- (struct inferior_list *,
- int (*func) (struct inferior_list_entry *,
- void *),
- void *arg);
-struct inferior_list_entry *find_inferior_id (struct inferior_list *list,
- ptid_t id);
-struct inferior_list_entry *
- find_inferior_in_random (struct inferior_list *,
- int (*func) (struct inferior_list_entry *,
- void *),
- void *arg);
+
+thread_info *find_inferior (std::list<thread_info *> *thread_list,
+ int (*func) (thread_info *, void *), void *arg);
+thread_info *find_inferior_id (std::list<thread_info *> *thread_list,
+ ptid_t id);
+thread_info *find_inferior_in_random (std::list<thread_info *> *thread_list,
+ int (*func) (thread_info *, void *),
+ void *arg);
+void for_each_inferior (std::list<thread_info *> *thread_list,
+ void (*action) (thread_info *));
+void for_each_inferior_with_data (std::list<thread_info *> *thread_list,
+ void (*action) (thread_info *, void *),
+ void *data);
void *thread_target_data (struct thread_info *);
struct regcache *thread_regcache_data (struct thread_info *);
};
static int
-update_registers_callback (struct inferior_list_entry *entry, void *arg)
+update_registers_callback (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
struct update_registers_data *data = (struct update_registers_data *) arg;
static void complete_ongoing_step_over (void);
static int linux_low_ptrace_options (int attached);
static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
-static int proceed_one_lwp (struct inferior_list_entry *entry, void *except);
+static int proceed_one_lwp (thread_info *thread, void *except);
/* When the event-loop is doing a step-over, this points at the thread
being stepped. */
};
static int
-second_thread_of_pid_p (struct inferior_list_entry *entry, void *args)
+second_thread_of_pid_p (thread_info *thread, void *args)
{
struct counter *counter = (struct counter *) args;
- if (ptid_get_pid (entry->id) == counter->pid)
+ if (thread->id.pid () == counter->pid)
{
if (++counter->count > 1)
return 1;
except the leader. */
static int
-kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
+kill_one_lwp_callback (thread_info *thread, void *args)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int pid = * (int *) args;
- if (ptid_get_pid (entry->id) != pid)
+ if (thread->id.pid () != pid)
return 0;
/* We avoid killing the first thread here, because of a Linux kernel (at
{
if (debug_threads)
debug_printf ("lkop: is last of process %s\n",
- target_pid_to_str (entry->id));
+ target_pid_to_str (thread->id));
return 0;
}
given process. */
static int
-linux_detach_lwp_callback (struct inferior_list_entry *entry, void *args)
+linux_detach_lwp_callback (thread_info *thread, void *args)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int pid = *(int *) args;
int lwpid = lwpid_of (thread);
/* Skip other processes. */
- if (ptid_get_pid (entry->id) != pid)
+ if (thread->id.pid () != pid)
return 0;
/* We don't actually detach from the thread group leader just yet.
If the thread group exits, we must reap the zombie clone lwps
before we're able to reap the leader. */
- if (ptid_get_pid (entry->id) == lwpid)
+ if (thread->id.pid () == lwpid)
return 0;
linux_detach_one_lwp (lwp);
/* Remove all LWPs that belong to process PROC from the lwp list. */
static int
-delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
+delete_lwp_callback (thread_info *thread, void *proc)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
struct process_info *process = (struct process_info *) proc;
/* Return 1 if this lwp has an interesting status pending. */
static int
-status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
+status_pending_p_callback (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
ptid_t ptid = * (ptid_t *) arg;
}
static int
-same_lwp (struct inferior_list_entry *entry, void *data)
+same_lwp (thread_info *thread, void *data)
{
ptid_t ptid = *(ptid_t *) data;
int lwp;
else
lwp = ptid_get_pid (ptid);
- if (ptid_get_lwp (entry->id) == lwp)
+ if (thread->id.lwp () == lwp)
return 1;
return 0;
struct lwp_info *
find_lwp_pid (ptid_t ptid)
{
- struct inferior_list_entry *thread
- = find_inferior (&all_threads, same_lwp, &ptid);
+ thread_info *thread = find_inferior (&all_threads, same_lwp, &ptid);
if (thread == NULL)
return NULL;
- return get_thread_lwp ((struct thread_info *) thread);
+ return get_thread_lwp (thread);
}
/* Return the number of known LWPs in the tgid given by PID. */
static int
num_lwps (int pid)
{
- struct inferior_list_entry *inf, *tmp;
int count = 0;
- ALL_INFERIORS (&all_threads, inf, tmp)
- {
- if (ptid_get_pid (inf->id) == pid)
- count++;
- }
+ for_each_thread ([&] (thread_info *thread) {
+ if (thread->id.pid () == pid)
+ count++;
+ });
return count;
}
find_inferiors should continue iterating. */
static int
-iterate_over_lwps_filter (struct inferior_list_entry *entry, void *args_p)
+iterate_over_lwps_filter (thread_info *thread, void *args_p)
{
struct iterate_over_lwps_args *args
= (struct iterate_over_lwps_args *) args_p;
- if (ptid_match (entry->id, args->filter))
+ if (thread->id.matches (args->filter))
{
- struct thread_info *thr = (struct thread_info *) entry;
- struct lwp_info *lwp = get_thread_lwp (thr);
+ struct lwp_info *lwp = get_thread_lwp (thread);
return (*args->callback) (lwp, args->data);
}
void *data)
{
struct iterate_over_lwps_args args = {filter, callback, data};
- struct inferior_list_entry *entry;
- entry = find_inferior (&all_threads, iterate_over_lwps_filter, &args);
- if (entry == NULL)
+ thread_info *thread = find_inferior (&all_threads, iterate_over_lwps_filter,
+ &args);
+ if (thread == NULL)
return NULL;
- return get_thread_lwp ((struct thread_info *) entry);
+ return get_thread_lwp (thread);
}
/* Detect zombie thread group leaders, and "exit" them. We can't reap
stopped. ARG is a PTID filter. */
static int
-not_stopped_callback (struct inferior_list_entry *entry, void *arg)
+not_stopped_callback (thread_info *thread, void *arg)
{
- struct thread_info *thr = (struct thread_info *) entry;
struct lwp_info *lwp;
ptid_t filter = *(ptid_t *) arg;
- if (!ptid_match (ptid_of (thr), filter))
+ if (!ptid_match (ptid_of (thread), filter))
return 0;
- lwp = get_thread_lwp (thr);
+ lwp = get_thread_lwp (thread);
if (!lwp->stopped)
return 1;
to report, but are resumed from the core's perspective. */
static void
-resume_stopped_resumed_lwps (struct inferior_list_entry *entry)
+resume_stopped_resumed_lwps (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
if (lp->stopped
/* Count the LWP's that have had events. */
static int
-count_events_callback (struct inferior_list_entry *entry, void *data)
+count_events_callback (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
int *count = (int *) data;
/* Select the LWP (if any) that is currently being single-stepped. */
static int
-select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
+select_singlestep_lwp_callback (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
/* Select the Nth LWP that has had an event. */
static int
-select_event_lwp_callback (struct inferior_list_entry *entry, void *data)
+select_event_lwp_callback (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lp = get_thread_lwp (thread);
int *selector = (int *) data;
/* Decrement the suspend count of an LWP. */
static int
-unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
+unsuspend_one_lwp (thread_info *thread, void *except)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
/* Ignore EXCEPT. */
find_inferior (&all_threads, unsuspend_one_lwp, except);
}
-static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry);
-static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry,
- void *data);
-static int lwp_running (struct inferior_list_entry *entry, void *data);
+static void move_out_of_jump_pad_callback (thread_info *thread);
+static int stuck_in_jump_pad_callback (thread_info *thread, void *data);
+static int lwp_running (thread_info *thread, void *data);
static ptid_t linux_wait_1 (ptid_t ptid,
struct target_waitstatus *ourstatus,
int target_options);
{
/* In all-stop, a stop reply cancels all previous resume
requests. Delete all single-step breakpoints. */
- struct inferior_list_entry *inf, *tmp;
- ALL_INFERIORS (&all_threads, inf, tmp)
- {
- struct thread_info *thread = (struct thread_info *) inf;
+ find_thread ([&] (thread_info *thread) {
+ if (has_single_step_breakpoints (thread))
+ {
+ remove_single_step_breakpoints_p = 1;
+ return true;
+ }
- if (has_single_step_breakpoints (thread))
- {
- remove_single_step_breakpoints_p = 1;
- break;
- }
- }
+ return false;
+ });
}
if (remove_single_step_breakpoints_p)
}
else
{
- struct inferior_list_entry *inf, *tmp;
-
- ALL_INFERIORS (&all_threads, inf, tmp)
- {
- struct thread_info *thread = (struct thread_info *) inf;
-
- if (has_single_step_breakpoints (thread))
- delete_single_step_breakpoints (thread);
- }
+ for_each_thread ([] (thread_info *thread){
+ if (has_single_step_breakpoints (thread))
+ delete_single_step_breakpoints (thread);
+ });
}
unstop_all_lwps (0, event_child);
}
static int
-send_sigstop_callback (struct inferior_list_entry *entry, void *except)
+send_sigstop_callback (thread_info *thread, void *except)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
/* Ignore EXCEPT. */
/* Increment the suspend count of an LWP, and stop it, if not stopped
yet. */
static int
-suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
- void *except)
+suspend_and_send_sigstop_callback (thread_info *thread, void *except)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
/* Ignore EXCEPT. */
lwp_suspended_inc (lwp);
- return send_sigstop_callback (entry, except);
+ return send_sigstop_callback (thread, except);
}
static void
saved_thread = current_thread;
if (saved_thread != NULL)
- saved_tid = saved_thread->entry.id;
+ saved_tid = saved_thread->id;
else
saved_tid = null_ptid; /* avoid bogus unused warning */
because she wants to debug it. */
static int
-stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
+stuck_in_jump_pad_callback (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
if (lwp->suspended != 0)
}
static void
-move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
+move_out_of_jump_pad_callback (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct thread_info *saved_thread;
struct lwp_info *lwp = get_thread_lwp (thread);
int *wstat;
}
static int
-lwp_running (struct inferior_list_entry *entry, void *data)
+lwp_running (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
if (lwp_is_marked_dead (lwp))
suspension). */
static int
-linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
+linux_set_resume_request (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int ndx;
struct thread_resume_array *r;
{
ptid_t ptid = r->resume[ndx].thread;
if (ptid_equal (ptid, minus_one_ptid)
- || ptid_equal (ptid, entry->id)
+ || ptid == thread->id
/* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads
of PID'. */
|| (ptid_get_pid (ptid) == pid_of (thread)
reported to GDBserver core, but GDB has not pulled the
event out of the vStopped queue yet, likewise, ignore the
(wildcard) resume request. */
- if (in_queued_stop_replies (entry->id))
+ if (in_queued_stop_replies (thread->id))
{
if (debug_threads)
debug_printf ("not resuming LWP %ld: has queued stop reply\n",
Set *FLAG_P if this lwp has an interesting status pending. */
static int
-resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
+resume_status_pending_p (thread_info *thread, void *flag_p)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
/* LWPs which will not be resumed are not interesting, because
inferior's regcache. */
static int
-need_step_over_p (struct inferior_list_entry *entry, void *dummy)
+need_step_over_p (thread_info *thread, void *dummy)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
struct thread_info *saved_thread;
CORE_ADDR pc;
linux_resume_one_lwp (lwp, step, 0, NULL);
/* Require next event from this LWP. */
- step_over_bkpt = thread->entry.id;
+ step_over_bkpt = thread->id;
return 1;
}
they should be re-issued if necessary. */
static int
-linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
+linux_resume_one_thread (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int leave_all_stopped = * (int *) arg;
int leave_pending;
if (debug_threads)
debug_printf ("resuming LWP %ld\n", lwpid_of (thread));
- proceed_one_lwp (entry, NULL);
+ proceed_one_lwp (thread, NULL);
}
else
{
on that particular thread, and leave all others stopped. */
static int
-proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+proceed_one_lwp (thread_info *thread, void *except)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int step;
}
static int
-unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+unsuspend_and_proceed_one_lwp (thread_info *thread, void *except)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
if (lwp == except)
lwp_suspended_decr (lwp);
- return proceed_one_lwp (entry, except);
+ return proceed_one_lwp (thread, except);
}
/* When we finish a step-over, set threads running again. If there's
options for the specified lwp. */
static int
-reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry,
- void *args)
+reset_lwp_ptrace_options_callback (thread_info *thread, void *args)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
if (!lwp->stopped)
if the lwp's process id is *PID_P. */
static int
-update_watch_registers_callback (struct inferior_list_entry *entry,
- void *pid_p)
+update_watch_registers_callback (thread_info *thread, void *pid_p)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct lwp_info *lwp = get_thread_lwp (thread);
int pid = *(int *) pid_p;
all threads belonging to process PROC. */
static int
-lynx_delete_thread_callback (struct inferior_list_entry *entry, void *proc)
+lynx_delete_thread_callback (thread_info *thread, void *proc)
{
struct process_info *process = (struct process_info *) proc;
- if (ptid_get_pid (entry->id) == pid_of (process))
- {
- struct thread_info *thr = find_thread_ptid (entry->id);
-
- remove_thread (thr);
- }
+ if (thread->id.pid () == pid_of (process))
+ remove_thread (thread);
return 0;
}
}
static int
-regcache_invalidate_one (struct inferior_list_entry *entry,
- void *pid_p)
+regcache_invalidate_one (thread_info *thread, void *pid_p)
{
- struct thread_info *thread = (struct thread_info *) entry;
int pid = *(int *) pid_p;
/* Only invalidate the regcaches of threads of this process. */
- if (ptid_get_pid (entry->id) == pid)
+ if (thread->id.pid () == pid)
regcache_invalidate_thread (thread);
return 0;
regcache_invalidate (void)
{
/* Only update the threads of the current process. */
- int pid = ptid_get_pid (current_thread->entry.id);
+ int pid = current_thread->id.pid ();
regcache_invalidate_pid (pid);
}
}
}
-static void
-free_register_cache_thread_one (struct inferior_list_entry *entry)
-{
- struct thread_info *thread = (struct thread_info *) entry;
-
- free_register_cache_thread (thread);
-}
-
void
regcache_release (void)
{
/* Flush and release all pre-existing register caches. */
- for_each_inferior (&all_threads, free_register_cache_thread_one);
+ for_each_inferior (&all_threads, free_register_cache_thread);
}
#endif
return "E.Btrace already enabled.";
current_btrace_conf.format = BTRACE_FORMAT_BTS;
- thread->btrace = target_enable_btrace (thread->entry.id,
- ¤t_btrace_conf);
+ thread->btrace = target_enable_btrace (thread->id, ¤t_btrace_conf);
if (thread->btrace == NULL)
return "E.Could not enable btrace.";
return "E.Btrace already enabled.";
current_btrace_conf.format = BTRACE_FORMAT_PT;
- thread->btrace = target_enable_btrace (thread->entry.id,
- ¤t_btrace_conf);
+ thread->btrace = target_enable_btrace (thread->id, ¤t_btrace_conf);
if (thread->btrace == NULL)
return "E.Could not enable btrace.";
Emit the XML to describe the thread of INF. */
static void
-handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
+handle_qxfer_threads_worker (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) inf;
struct buffer *buffer = (struct buffer *) arg;
ptid_t ptid = ptid_of (thread);
char ptid_s[100];
static void
handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
{
- static struct inferior_list_entry *thread_ptr;
+ static std::list<thread_info *>::const_iterator thread_iter;
/* Reply the current thread id. */
if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
ptid = general_thread;
else
{
- thread_ptr = get_first_inferior (&all_threads);
- ptid = thread_ptr->id;
+ thread_iter = all_threads.begin ();
+ ptid = (*thread_iter)->id;
}
sprintf (own_buf, "QC");
if (strcmp ("qfThreadInfo", own_buf) == 0)
{
require_running_or_return (own_buf);
- thread_ptr = get_first_inferior (&all_threads);
+ thread_iter = all_threads.begin ();
*own_buf++ = 'm';
- write_ptid (own_buf, thread_ptr->id);
- thread_ptr = thread_ptr->next;
+ ptid_t ptid = (*thread_iter)->id;
+ write_ptid (own_buf, ptid);
+ thread_iter++;
return;
}
if (strcmp ("qsThreadInfo", own_buf) == 0)
{
require_running_or_return (own_buf);
- if (thread_ptr != NULL)
+ if (thread_iter != all_threads.end ())
{
*own_buf++ = 'm';
- write_ptid (own_buf, thread_ptr->id);
- thread_ptr = thread_ptr->next;
+ ptid_t ptid = (*thread_iter)->id;
+ write_ptid (own_buf, ptid);
+ thread_iter++;
return;
}
else
Note: This function is itself a callback for find_inferior. */
static int
-visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
+visit_actioned_threads (thread_info *thread, void *datap)
{
struct visit_actioned_threads_data *data
= (struct visit_actioned_threads_data *) datap;
const struct thread_resume *action = &actions[i];
if (ptid_equal (action->thread, minus_one_ptid)
- || ptid_equal (action->thread, entry->id)
+ || ptid_equal (action->thread, thread->id)
|| ((ptid_get_pid (action->thread)
- == ptid_get_pid (entry->id))
+ == thread->id.pid ())
&& ptid_get_lwp (action->thread) == -1))
{
- struct thread_info *thread = (struct thread_info *) entry;
-
if ((*callback) (action, thread))
return 1;
}
thread->status_pending_p = 0;
last_status = thread->last_status;
- last_ptid = thread->entry.id;
+ last_ptid = thread->id;
prepare_resume_reply (own_buf, last_ptid, &last_status);
return 1;
}
stopped thread. */
static int
-queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
+queue_stop_reply_callback (thread_info *thread, void *arg)
{
- struct thread_info *thread = (struct thread_info *) entry;
-
/* For now, assume targets that don't have this callback also don't
manage the thread's last_status field. */
if (the_target->thread_stopped == NULL)
{
struct vstop_notif *new_notif = XNEW (struct vstop_notif);
- new_notif->ptid = entry->id;
+ new_notif->ptid = thread->id;
new_notif->status = thread->last_status;
/* Pass the last stop reply back to GDB, but don't notify
yet. */
= target_waitstatus_to_string (&thread->last_status);
debug_printf ("Reporting thread %s as already stopped with %s\n",
- target_pid_to_str (entry->id),
+ target_pid_to_str (thread->id),
status_string.c_str ());
}
/* Pass the last stop reply back to GDB, but don't notify
yet. */
- queue_stop_reply (entry->id, &thread->last_status);
+ queue_stop_reply (thread->id, &thread->last_status);
}
}
it. */
static void
-gdb_wants_thread_stopped (struct inferior_list_entry *entry)
+gdb_wants_thread_stopped (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
-
thread->last_resume_kind = resume_stop;
if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
flag. */
static void
-clear_pending_status_callback (struct inferior_list_entry *entry)
+clear_pending_status_callback (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
-
thread->status_pending_p = 0;
}
interesting event, mark it as having a pending event. */
static void
-set_pending_status_callback (struct inferior_list_entry *entry)
+set_pending_status_callback (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
-
if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
|| (thread->last_status.value.sig != GDB_SIGNAL_0
/* A breakpoint, watchpoint or finished step from a previous
pending status to report to GDB. */
static int
-find_status_pending_thread_callback (struct inferior_list_entry *entry, void *data)
+find_status_pending_thread_callback (thread_info *thread, void *data)
{
- struct thread_info *thread = (struct thread_info *) entry;
-
return thread->status_pending_p;
}
}
else
{
- struct inferior_list_entry *thread = NULL;
+ thread_info *thread = NULL;
pause_all (0);
stabilize_threads ();
/* If we're still out of luck, simply pick the first thread in
the thread list. */
if (thread == NULL)
- thread = get_first_inferior (&all_threads);
+ thread = get_first_thread ();
if (thread != NULL)
{
set_desired_thread ();
gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
- prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
+ prepare_resume_reply (own_buf, tp->id, &tp->last_status);
}
else
strcpy (own_buf, "W00");
break;
}
- thread_id = thread->entry.id;
+ thread_id = thread->id;
}
else
{
general_thread);
if (thread == NULL)
thread = get_first_thread ();
- thread_id = thread->entry.id;
+ thread_id = thread->id;
}
general_thread = thread_id;
when accessing memory. */
static int
-thread_search_callback (struct inferior_list_entry *entry, void *args)
+thread_search_callback (thread_info *thread, void *args)
{
- struct thread_info *thread = (struct thread_info *) entry;
struct thread_search *s = (struct thread_search *) args;
- if (ptid_get_pid (entry->id) == ptid_get_pid (s->current_gen_ptid)
+ if (thread->id.pid () == ptid_get_pid (s->current_gen_ptid)
&& mythread_alive (ptid_of (thread)))
{
if (s->stopped == NULL
if (s->first == NULL)
s->first = thread;
- if (s->current == NULL && ptid_equal (s->current_gen_ptid, entry->id))
+ if (s->current == NULL && s->current_gen_ptid == thread->id)
s->current = thread;
}
lwp = get_thread_lwp (thread);
if (!lwp->thread_known)
- find_one_thread (thread->entry.id);
+ find_one_thread (thread->id);
if (!lwp->thread_known)
return TD_NOTHR;
lwp = get_thread_lwp (thread);
- if (!lwp->thread_known && !find_one_thread (thread->entry.id))
+ if (!lwp->thread_known && !find_one_thread (thread->id))
return false;
gdb_assert (lwp->thread_known);
wstep_link = &tinfo->while_stepping;
trace_debug ("Thread %s finished a single-step for tracepoint %d at 0x%s",
- target_pid_to_str (tinfo->entry.id),
+ target_pid_to_str (tinfo->id),
wstep->tp_number, paddress (wstep->tp_address));
ctx.base.type = trap_tracepoint;
{
trace_debug ("NO TRACEPOINT %d at 0x%s FOR THREAD %s!",
wstep->tp_number, paddress (wstep->tp_address),
- target_pid_to_str (tinfo->entry.id));
+ target_pid_to_str (tinfo->id));
/* Unlink. */
*wstep_link = wstep->next;
{
/* The requested numbers of steps have occurred. */
trace_debug ("Thread %s done stepping for tracepoint %d at 0x%s",
- target_pid_to_str (tinfo->entry.id),
+ target_pid_to_str (tinfo->id),
wstep->tp_number, paddress (wstep->tp_address));
/* Unlink the wstep. */
&& tpoint->type != static_tracepoint)
{
trace_debug ("Thread %s at address of tracepoint %d at 0x%s",
- target_pid_to_str (tinfo->entry.id),
+ target_pid_to_str (tinfo->id),
tpoint->number, paddress (tpoint->address));
/* Test the condition if present, and collect if true. */
static struct x86_debug_reg_state debug_reg_state;
static int
-update_debug_registers_callback (struct inferior_list_entry *entry,
- void *pid_p)
+update_debug_registers_callback (thread_info *thr, void *pid_p)
{
- struct thread_info *thr = (struct thread_info *) entry;
win32_thread_info *th = (win32_thread_info *) thread_target_data (thr);
int pid = *(int *) pid_p;
/* Delete a thread from the list of threads. */
static void
-delete_thread_info (struct inferior_list_entry *entry)
+delete_thread_info (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
remove_thread (thread);
static void
child_delete_thread (DWORD pid, DWORD tid)
{
- struct inferior_list_entry *thread;
ptid_t ptid;
/* If the last thread is exiting, just return. */
- if (one_inferior_p (&all_threads))
+ if (all_threads.size () == 1)
return;
ptid = ptid_build (pid, tid, 0);
- thread = find_inferior_id (&all_threads, ptid);
+ thread_info *thread = find_inferior_id (&all_threads, ptid);
if (thread == NULL)
return;
/* Resume all artificially suspended threads if we are continuing
execution. */
static int
-continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
+continue_one_thread (thread_info *thread, void *id_ptr)
{
- struct thread_info *thread = (struct thread_info *) this_thread;
int thread_id = * (int *) id_ptr;
win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
static void
-suspend_one_thread (struct inferior_list_entry *entry)
+suspend_one_thread (thread_info *thread)
{
- struct thread_info *thread = (struct thread_info *) entry;
win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
if (!th->suspended)
child_delete_thread (current_event.dwProcessId,
current_event.dwThreadId);
- current_thread = (struct thread_info *) all_threads.head;
+ current_thread = get_first_thread ();
return 1;
case CREATE_PROCESS_DEBUG_EVENT: