From: Simon Marchi <simon.marchi@polymtl.ca>
To: gdb-patches@sourceware.org
Subject: [PATCH 3/3] gdb: use intrusive_list for linux-nat lwp_list
Date: Sat, 28 Aug 2021 10:58:45 -0400 [thread overview]
Message-ID: <20210828145845.1034686-4-simon.marchi@polymtl.ca> (raw)
In-Reply-To: <20210828145845.1034686-1-simon.marchi@polymtl.ca>
Replace the manually maintained linked list of lwp_info objects with
intrusive_list. Replace the ALL_LWPS macro with all_lwps, which returns
a range. Add all_lwps_safe as well, for use in iterate_over_lwps, which
currently iterates in a safe manner.
Change-Id: I355313502510acc0103f5eaf2fbde80897d6376c
---
gdb/ia64-linux-nat.c | 8 +++-----
gdb/linux-nat.c | 46 ++++++++++++++++++++++---------------------
gdb/linux-nat.h | 35 +++++++++++++++-----------------
gdb/linux-thread-db.c | 3 +--
gdb/mips-linux-nat.c | 7 ++-----
5 files changed, 46 insertions(+), 53 deletions(-)
diff --git a/gdb/ia64-linux-nat.c b/gdb/ia64-linux-nat.c
index 6381e5318e68..371d51f00bba 100644
--- a/gdb/ia64-linux-nat.c
+++ b/gdb/ia64-linux-nat.c
@@ -589,7 +589,6 @@ ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
enum target_hw_bp_type type,
struct expression *cond)
{
- struct lwp_info *lp;
int idx;
long dbr_addr, dbr_mask;
int max_watchpoints = 4;
@@ -630,7 +629,8 @@ ia64_linux_nat_target::insert_watchpoint (CORE_ADDR addr, int len,
debug_registers[2 * idx] = dbr_addr;
debug_registers[2 * idx + 1] = dbr_mask;
- ALL_LWPS (lp)
+
+ for (const lwp_info *lp : all_lwps ())
{
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
enable_watchpoints_in_psr (lp->ptid);
@@ -657,14 +657,12 @@ ia64_linux_nat_target::remove_watchpoint (CORE_ADDR addr, int len,
dbr_mask = debug_registers[2 * idx + 1];
if ((dbr_mask & (0x3UL << 62)) && addr == (CORE_ADDR) dbr_addr)
{
- struct lwp_info *lp;
-
debug_registers[2 * idx] = 0;
debug_registers[2 * idx + 1] = 0;
dbr_addr = 0;
dbr_mask = 0;
- ALL_LWPS (lp)
+ for (const lwp_info *lp : all_lwps ())
store_debug_register_pair (lp->ptid, idx, &dbr_addr, &dbr_mask);
return 0;
diff --git a/gdb/linux-nat.c b/gdb/linux-nat.c
index 930209db6e89..fd01bd9301c0 100644
--- a/gdb/linux-nat.c
+++ b/gdb/linux-nat.c
@@ -421,9 +421,8 @@ static int
num_lwps (int pid)
{
int count = 0;
- struct lwp_info *lp;
- for (lp = lwp_list; lp; lp = lp->next)
+ for (const lwp_info *lp ATTRIBUTE_UNUSED : all_lwps ())
if (lp->ptid.pid () == pid)
count++;
@@ -700,17 +699,31 @@ lwp_lwpid_htab_add_lwp (struct lwp_info *lp)
creation order. This order is assumed in some cases. E.g.,
reaping status after killing alls lwps of a process: the leader LWP
must be reaped last. */
-struct lwp_info *lwp_list;
+
+static intrusive_list<lwp_info> lwp_list;
+
+/* See linux-nat.h. */
+
+lwp_info_range
+all_lwps ()
+{
+ return lwp_info_range (lwp_list.begin ());
+}
+
+/* See linux-nat.h. */
+
+lwp_info_safe_range
+all_lwps_safe ()
+{
+ return lwp_info_safe_range (lwp_list.begin ());
+}
/* Add LP to sorted-by-reverse-creation-order doubly-linked list. */
static void
lwp_list_add (struct lwp_info *lp)
{
- lp->next = lwp_list;
- if (lwp_list != NULL)
- lwp_list->prev = lp;
- lwp_list = lp;
+ lwp_list.push_front (*lp);
}
/* Remove LP from sorted-by-reverse-creation-order doubly-linked
@@ -720,12 +733,7 @@ static void
lwp_list_remove (struct lwp_info *lp)
{
/* Remove from sorted-by-creation-order list. */
- if (lp->next != NULL)
- lp->next->prev = lp->prev;
- if (lp->prev != NULL)
- lp->prev->next = lp->next;
- if (lp == lwp_list)
- lwp_list = lp->next;
+ lwp_list.erase (lwp_list.iterator_to (*lp));
}
\f
@@ -922,12 +930,8 @@ struct lwp_info *
iterate_over_lwps (ptid_t filter,
gdb::function_view<iterate_over_lwps_ftype> callback)
{
- struct lwp_info *lp, *lpnext;
-
- for (lp = lwp_list; lp; lp = lpnext)
+ for (lwp_info *lp : all_lwps_safe ())
{
- lpnext = lp->next;
-
if (lp->ptid.matches (filter))
{
if (callback (lp) != 0)
@@ -3716,8 +3720,6 @@ linux_nat_target::thread_alive (ptid_t ptid)
void
linux_nat_target::update_thread_list ()
{
- struct lwp_info *lwp;
-
/* We add/delete threads from the list as clone/exit events are
processed, so just try deleting exited threads still in the
thread list. */
@@ -3725,7 +3727,7 @@ linux_nat_target::update_thread_list ()
/* Update the processor core that each lwp/thread was last seen
running on. */
- ALL_LWPS (lwp)
+ for (lwp_info *lwp : all_lwps ())
{
/* Avoid accessing /proc if the thread hasn't run since we last
time we fetched the thread's core. Accessing /proc becomes
@@ -3949,7 +3951,7 @@ linux_proc_xfer_memory_partial (gdb_byte *readbuf, const gdb_byte *writebuf,
/* Iterate over LWPs of the current inferior, trying to access
memory through one of them. */
- for (lwp_info *lp = lwp_list; lp != nullptr; lp = lp->next)
+ for (lwp_info *lp : all_lwps ())
{
if (lp->ptid.pid () != cur_pid)
continue;
diff --git a/gdb/linux-nat.h b/gdb/linux-nat.h
index b1b168d2bfee..74b5eddc1365 100644
--- a/gdb/linux-nat.h
+++ b/gdb/linux-nat.h
@@ -196,11 +196,9 @@ extern linux_nat_target *linux_target;
struct arch_lwp_info;
-/* Structure describing an LWP. This is public only for the purposes
- of ALL_LWPS; target-specific code should generally not access it
- directly. */
+/* Structure describing an LWP. */
-struct lwp_info
+struct lwp_info : intrusive_list_node<lwp_info>
{
lwp_info (ptid_t ptid)
: ptid (ptid)
@@ -283,27 +281,26 @@ struct lwp_info
/* Arch-specific additions. */
struct arch_lwp_info *arch_private = nullptr;
-
- /* Previous and next pointers in doubly-linked list of known LWPs,
- sorted by reverse creation order. */
- struct lwp_info *prev = nullptr;
- struct lwp_info *next = nullptr;
};
-/* The global list of LWPs, for ALL_LWPS. Unlike the threads list,
- there is always at least one LWP on the list while the GNU/Linux
- native target is active. */
-extern struct lwp_info *lwp_list;
+/* lwp_info iterator and range types. */
+
+using lwp_info_iterator
+ = reference_to_pointer_iterator<intrusive_list<lwp_info>::iterator>;
+using lwp_info_range = iterator_range<lwp_info_iterator>;
+using lwp_info_safe_range = basic_safe_range<lwp_info_range>;
+
+/* Get an iterable range over all lwps. */
+
+lwp_info_range all_lwps ();
+
+/* Same as the above, but safe against deletion while iterating. */
+
+lwp_info_safe_range all_lwps_safe ();
/* Does the current host support PTRACE_GETREGSET? */
extern enum tribool have_ptrace_getregset;
-/* Iterate over each active thread (light-weight process). */
-#define ALL_LWPS(LP) \
- for ((LP) = lwp_list; \
- (LP) != NULL; \
- (LP) = (LP)->next)
-
/* Called from the LWP layer to inform the thread_db layer that PARENT
spawned CHILD. Both LWPs are currently stopped. This function
does whatever is required to have the child LWP under the
diff --git a/gdb/linux-thread-db.c b/gdb/linux-thread-db.c
index eb2aa5ac409a..aff00dc8d40e 100644
--- a/gdb/linux-thread-db.c
+++ b/gdb/linux-thread-db.c
@@ -920,13 +920,12 @@ try_thread_db_load_1 (struct thread_db_info *info)
if (info->td_ta_thr_iter_p == NULL)
{
- struct lwp_info *lp;
int pid = inferior_ptid.pid ();
thread_info *curr_thread = inferior_thread ();
linux_stop_and_wait_all_lwps ();
- ALL_LWPS (lp)
+ for (const lwp_info *lp : all_lwps ())
if (lp->ptid.pid () == pid)
thread_from_lwp (curr_thread, lp->ptid);
diff --git a/gdb/mips-linux-nat.c b/gdb/mips-linux-nat.c
index b21c7cb2ea68..1088a7dc1b03 100644
--- a/gdb/mips-linux-nat.c
+++ b/gdb/mips-linux-nat.c
@@ -632,12 +632,9 @@ mips_linux_nat_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
static int
write_watchpoint_regs (void)
{
- struct lwp_info *lp;
- int tid;
-
- ALL_LWPS (lp)
+ for (const lwp_info *lp : all_lwps ())
{
- tid = lp->ptid.lwp ();
+ int tid = lp->ptid.lwp ();
if (ptrace (PTRACE_SET_WATCH_REGS, tid, &watch_mirror, NULL) == -1)
perror_with_name (_("Couldn't write debug register"));
}
--
2.33.0
next prev parent reply other threads:[~2021-08-28 14:58 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-28 14:58 [PATCH 0/3] Make lwp_info use intrusive_list Simon Marchi
2021-08-28 14:58 ` [PATCH 1/3] gdb: make lwp_info non-POD Simon Marchi
2021-08-28 14:58 ` [PATCH 2/3] gdb: add destructor to lwp_info Simon Marchi
2021-08-28 14:58 ` Simon Marchi [this message]
2021-09-28 2:34 ` [PATCH 0/3] Make lwp_info use intrusive_list Simon Marchi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210828145845.1034686-4-simon.marchi@polymtl.ca \
--to=simon.marchi@polymtl.ca \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).