X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fgdbthread.h;h=825a7f6b51007d890ba60e9cc74b61c93f79a1c3;hb=268a13a5a3f7c6b9b6ffc5ac2d1b24eb41f3fbdc;hp=051041948569632e27261064f39f83410fa73de1;hpb=34c6591498f4363ef2c71d683cdaaa33d6a6ad64;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h index 0510419485..825a7f6b51 100644 --- a/gdb/gdbserver/gdbthread.h +++ b/gdb/gdbserver/gdbthread.h @@ -1,5 +1,5 @@ /* Multi-thread control defs for remote server for GDB. - Copyright (C) 1993-2015 Free Software Foundation, Inc. + Copyright (C) 1993-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -16,19 +16,21 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef GDB_THREAD_H -#define GDB_THREAD_H +#ifndef GDBSERVER_GDBTHREAD_H +#define GDBSERVER_GDBTHREAD_H +#include "gdbsupport/common-gdbthread.h" #include "inferiors.h" +#include + 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; @@ -71,11 +73,13 @@ struct thread_info struct btrace_target_info *btrace; }; -extern struct inferior_list all_threads; +extern std::list 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); @@ -84,7 +88,140 @@ 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 +static thread_info * +find_thread (Func func) +{ + std::list::iterator next, cur = all_threads.begin (); + + while (cur != all_threads.end ()) + { + next = cur; + next++; + + if (func (*cur)) + return *cur; + + cur = next; + } + + return NULL; +} + +/* Like the above, but only consider threads with pid PID. */ + +template +static thread_info * +find_thread (int pid, Func func) +{ + return find_thread ([&] (thread_info *thread) + { + return thread->id.pid () == pid && func (thread); + }); +} + +/* Find the first thread that matches FILTER for which FUNC returns true. + Return NULL if no thread satisfying these conditions is found. */ + +template +static thread_info * +find_thread (ptid_t filter, Func func) +{ + return find_thread ([&] (thread_info *thread) { + return thread->id.matches (filter) && func (thread); + }); +} + +/* Invoke FUNC for each thread. */ + +template +static void +for_each_thread (Func func) +{ + std::list::iterator next, cur = all_threads.begin (); + + while (cur != all_threads.end ()) + { + next = cur; + next++; + func (*cur); + cur = next; + } +} + +/* Like the above, but only consider threads with pid PID. */ + +template +static void +for_each_thread (int pid, Func func) +{ + for_each_thread ([&] (thread_info *thread) + { + if (pid == thread->id.pid ()) + func (thread); + }); +} + +/* Find the a random thread for which FUNC (THREAD) returns true. If + no entry is found then return NULL. */ + +template +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 *thr_arg) { + return func (thr_arg) && (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->id; +} + +/* Get the pid of THREAD. */ + +static inline int +pid_of (const thread_info *thread) +{ + return thread->id.pid (); +} + +/* Get the lwp of THREAD. */ + +static inline long +lwpid_of (const thread_info *thread) +{ + return thread->id.lwp (); +} -#endif /* GDB_THREAD_H */ +#endif /* GDBSERVER_GDBTHREAD_H */