From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id CF3233858435 for ; Sat, 28 Aug 2021 14:58:49 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org CF3233858435 X-ASG-Debug-ID: 1630162726-0c856e0388104790001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id 9UDSbG8MA1RJ860K (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 28 Aug 2021 10:58:46 -0400 (EDT) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.localdomain (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) by smtp.ebox.ca (Postfix) with ESMTP id 71F21441D66; Sat, 28 Aug 2021 10:58:46 -0400 (EDT) From: Simon Marchi X-Barracuda-RBL-IP: 192.222.157.6 X-Barracuda-Effective-Source-IP: 192-222-157-6.qc.cable.ebox.net[192.222.157.6] X-Barracuda-Apparent-Source-IP: 192.222.157.6 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 X-ASG-Orig-Subj: [PATCH 3/3] gdb: use intrusive_list for linux-nat lwp_list Message-Id: <20210828145845.1034686-4-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20210828145845.1034686-1-simon.marchi@polymtl.ca> References: <20210828145845.1034686-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1630162726 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 8276 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.00 X-Barracuda-Spam-Status: No, SCORE=0.00 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests= X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.92222 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- X-Spam-Status: No, score=-16.5 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_QUARANTINE, KAM_DMARC_STATUS, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_SOFTFAIL, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Aug 2021 14:59:00 -0000 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_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)); } @@ -922,12 +930,8 @@ struct lwp_info * iterate_over_lwps (ptid_t filter, gdb::function_view 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 (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::iterator>; +using lwp_info_range = iterator_range; +using lwp_info_safe_range = basic_safe_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