[03/10] Use gdb::function_view in iterate_over_threads

Message ID 20250225-source-cache-hash-v1-3-f937ce22b0e9@tromey.com
State New
Headers
Series Some simple changes to use gdb's unordered set and map |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gdb_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gdb_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gdb_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_gdb_check--master-arm success Test passed

Commit Message

Tom Tromey Feb. 26, 2025, 1:08 a.m. UTC
  This C++-ifies iterate_over_threads, changing it to accept a
gdb::function_view and to return bool.
---
 gdb/aix-thread.c |  15 +++-----
 gdb/breakpoint.c |  16 +++------
 gdb/fbsd-tdep.c  |  10 +++---
 gdb/gdbthread.h  |   4 +--
 gdb/infcmd.c     |  12 +++----
 gdb/infrun.c     |   8 ++---
 gdb/mi/mi-main.c | 102 ++++++++++++++++++++-----------------------------------
 gdb/sol-thread.c |  23 ++++---------
 gdb/thread.c     |   5 ++-
 9 files changed, 70 insertions(+), 125 deletions(-)
  

Comments

Simon Marchi Feb. 26, 2025, 5:18 p.m. UTC | #1
On 2/25/25 8:08 PM, Tom Tromey wrote:
> This C++-ifies iterate_over_threads, changing it to accept a
> gdb::function_view and to return bool.

Looking at this code makes me want to suggest further cleanups, but I'll
avoid doing that because I think your patch is a step forward already.
Just a few suggestions:

> diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
> index 804a72c420594b9af92cf3820944d43b91f3eab9..a1e3d819e63afa8dd8da3d3865e7aabde44db1fc 100644
> --- a/gdb/fbsd-tdep.c
> +++ b/gdb/fbsd-tdep.c
> @@ -637,14 +637,14 @@ fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
>    return len;
>  }
>  
> -static int
> -find_signalled_thread (struct thread_info *info, void *data)
> +static bool
> +find_signalled_thread (struct thread_info *info)
>  {
>    if (info->stop_signal () != GDB_SIGNAL_0
>        && info->ptid.pid () == inferior_ptid.pid ())
> -    return 1;
> +    return true;
>  
> -  return 0;
> +  return false;

I would simplify it as:

  return (info->stop_signal () != GDB_SIGNAL_0
	  && info->ptid.pid () == inferior_ptid.pid ());

> @@ -528,7 +506,12 @@ mi_cmd_target_detach (const char *command, const char *const *argv, int argc)
>  
>        /* Pick any thread in the desired process.  Current
>  	 target_detach detaches from the parent of inferior_ptid.  */
> -      tp = iterate_over_threads (find_thread_of_process, &pid);
> +      tp = iterate_over_threads ([&] (struct thread_info *ti)
> +        {
> +	  if (ti->ptid.pid () == pid && ti->state != THREAD_EXITED)
> +	    return true;
> +	  return false;

Here too:

    return ti->ptid.pid () == pid && ti->state != THREAD_EXITED;

>  ptid_t
>  sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
>  {
> -  struct thread_info *thread_info =
> -    iterate_over_threads (thread_db_find_thread_from_tid, &thread);
> +  struct thread_info *thread_info
> +    = iterate_over_threads ([&] (struct thread_info *thread)
> +       {
> +	 if (thread->ptid.tid () == thread)
> +	   return true;
> +	 return false;

Here too:

  return thread->ptid.tid () == thread;

Simon
  

Patch

diff --git a/gdb/aix-thread.c b/gdb/aix-thread.c
index 4a050cdff108086ca4bd685cb85836c6bbc71539..f38d19d604db80dc1de50b0094b976b5cf46e98c 100644
--- a/gdb/aix-thread.c
+++ b/gdb/aix-thread.c
@@ -867,16 +867,6 @@  sync_threadlists (pid_t pid)
       }
 }
 
-/* Iterate_over_threads() callback for locating a thread, using
-   the TID of its associated kernel thread.  */
-
-static int
-iter_tid (struct thread_info *thread, void *tidp)
-{
-  const pthdb_tid_t tid = *(pthdb_tid_t *)tidp;
-  return thread->ptid.lwp () == tid;
-}
-
 /* Synchronize libpthdebug's state with the inferior and with GDB,
    generate a composite process/thread <pid> for the current thread,
    Return the ptid of the event thread if one can be found, else
@@ -906,7 +896,10 @@  pd_update (pid_t pid)
 
   tid = get_signaled_thread (pid);
   if (tid != 0)
-    thread = iterate_over_threads (iter_tid, &tid);
+    thread = iterate_over_threads ([&] (struct thread_info *thread)
+      {
+	return thread->ptid.lwp () == tid;
+      });
   if (!thread)
     ptid = ptid_t (pid);
   else
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index cf9cd76feb8447742e024050cae55cf2e98538c7..34e32303b02c38a35f0680c06c3020ec66aa3e58 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -11831,16 +11831,6 @@  bpstat_remove_bp_location (bpstat *bps, struct breakpoint *bpt)
       }
 }
 
-/* Callback for iterate_over_threads.  */
-static int
-bpstat_remove_breakpoint_callback (struct thread_info *th, void *data)
-{
-  struct breakpoint *bpt = (struct breakpoint *) data;
-
-  bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
-  return 0;
-}
-
 /* See breakpoint.h.  */
 
 void
@@ -12685,7 +12675,11 @@  delete_breakpoint (struct breakpoint *bpt)
      event-top.c won't do anything, and temporary breakpoints with
      commands won't work.  */
 
-  iterate_over_threads (bpstat_remove_breakpoint_callback, bpt);
+  iterate_over_threads ([&] (struct thread_info *th)
+    {
+      bpstat_remove_bp_location (th->control.stop_bpstat, bpt);
+      return false;
+    });
 
   /* Now that breakpoint is removed from breakpoint list, update the
      global location list.  This will remove locations that used to
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index 804a72c420594b9af92cf3820944d43b91f3eab9..a1e3d819e63afa8dd8da3d3865e7aabde44db1fc 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -637,14 +637,14 @@  fbsd_core_xfer_siginfo (struct gdbarch *gdbarch, gdb_byte *readbuf,
   return len;
 }
 
-static int
-find_signalled_thread (struct thread_info *info, void *data)
+static bool
+find_signalled_thread (struct thread_info *info)
 {
   if (info->stop_signal () != GDB_SIGNAL_0
       && info->ptid.pid () == inferior_ptid.pid ())
-    return 1;
+    return true;
 
-  return 0;
+  return false;
 }
 
 /* Return a byte_vector containing the contents of a core dump note
@@ -718,7 +718,7 @@  fbsd_make_corefile_notes (struct gdbarch *gdbarch, bfd *obfd, int *note_size)
     signalled_thr = curr_thr;
   else
     {
-      signalled_thr = iterate_over_threads (find_signalled_thread, NULL);
+      signalled_thr = iterate_over_threads (find_signalled_thread);
       if (signalled_thr == NULL)
 	signalled_thr = curr_thr;
     }
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index ee62153551f37d177a43739921ea8f531866a19a..6cffd86bc581f39e890ab770c4e1326f7a30de64 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -734,8 +734,8 @@  void thread_change_ptid (process_stratum_target *targ,
 
 /* Iterator function to call a user-provided callback function
    once for each known thread.  */
-typedef int (*thread_callback_func) (struct thread_info *, void *);
-extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
+typedef gdb::function_view<bool (struct thread_info *)> thread_callback_func;
+extern struct thread_info *iterate_over_threads (thread_callback_func);
 
 /* Pull in the internals of the inferiors/threads ranges and
    iterators.  Must be done after struct thread_info is defined.  */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 00703e44b7b5e7e070eb2080f96323d68f163609..c428d6ec16af7438fa09fef5d46684b3505d72f6 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -530,8 +530,8 @@  starti_command (const char *args, int from_tty)
   run_command_1 (args, from_tty, RUN_STOP_AT_FIRST_INSN);
 } 
 
-static int
-proceed_thread_callback (struct thread_info *thread, void *arg)
+static bool
+proceed_thread_callback (struct thread_info *thread)
 {
   /* We go through all threads individually instead of compressing
      into a single target `resume_all' request, because some threads
@@ -543,15 +543,15 @@  proceed_thread_callback (struct thread_info *thread, void *arg)
      thread stopped until I say otherwise', then we can optimize
      this.  */
   if (thread->state != THREAD_STOPPED)
-    return 0;
+    return false;
 
   if (!thread->inf->has_execution ())
-    return 0;
+    return false;
 
   switch_to_thread (thread);
   clear_proceed_status (0);
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
-  return 0;
+  return false;
 }
 
 static void
@@ -608,7 +608,7 @@  continue_1 (int all_threads)
       scoped_disable_commit_resumed disable_commit_resumed
 	("continue all threads in non-stop");
 
-      iterate_over_threads (proceed_thread_callback, nullptr);
+      iterate_over_threads (proceed_thread_callback);
 
       if (current_ui->prompt_state == PROMPT_BLOCKED)
 	{
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 79fa31e5ee24e42377d768b300bf8096b933827b..9f5b3d473f8a552924eed5a9125e56ca70c05b5f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -6671,9 +6671,8 @@  restart_threads (struct thread_info *event_thread, inferior *inf)
 /* Callback for iterate_over_threads.  Find a resumed thread that has
    a pending waitstatus.  */
 
-static int
-resumed_thread_with_pending_status (struct thread_info *tp,
-				    void *arg)
+static bool
+resumed_thread_with_pending_status (struct thread_info *tp)
 {
   return tp->resumed () && tp->has_pending_waitstatus ();
 }
@@ -6751,8 +6750,7 @@  finish_step_over (struct execution_control_state *ecs)
       if (ecs->ws.kind () == TARGET_WAITKIND_THREAD_EXITED)
        return 0;
 
-      pending = iterate_over_threads (resumed_thread_with_pending_status,
-				      nullptr);
+      pending = iterate_over_threads (resumed_thread_with_pending_status);
       if (pending != nullptr)
 	{
 	  struct thread_info *tp = ecs->event_thread;
diff --git a/gdb/mi/mi-main.c b/gdb/mi/mi-main.c
index 446a4f479bd7579ee36c097b3018625e3cdedfb5..96237c33b0db5092c80ddbf9bb1f7319a12b6157 100644
--- a/gdb/mi/mi-main.c
+++ b/gdb/mi/mi-main.c
@@ -250,15 +250,6 @@  proceed_thread (struct thread_info *thread, int pid)
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
 }
 
-static int
-proceed_thread_callback (struct thread_info *thread, void *arg)
-{
-  int pid = *(int *)arg;
-
-  proceed_thread (thread, pid);
-  return 0;
-}
-
 static void
 exec_continue (const char *const *argv, int argc)
 {
@@ -288,7 +279,11 @@  exec_continue (const char *const *argv, int argc)
 	      pid = inf->pid;
 	    }
 
-	  iterate_over_threads (proceed_thread_callback, &pid);
+	  iterate_over_threads ([&] (struct thread_info *thread)
+	    {
+	      proceed_thread (thread, pid);
+	      return false;
+	    });
 	  disable_commit_resumed.reset_and_commit ();
 	}
       else
@@ -341,21 +336,6 @@  mi_cmd_exec_continue (const char *command, const char *const *argv, int argc)
     exec_continue (argv, argc);
 }
 
-static int
-interrupt_thread_callback (struct thread_info *thread, void *arg)
-{
-  int pid = *(int *)arg;
-
-  if (thread->state != THREAD_RUNNING)
-    return 0;
-
-  if (thread->ptid.pid () != pid)
-    return 0;
-
-  target_stop (thread->ptid);
-  return 0;
-}
-
 /* Interrupt the execution of the target.  Note how we must play
    around with the token variables, in order to display the current
    token in the result of the interrupt command, and the previous
@@ -385,7 +365,17 @@  mi_cmd_exec_interrupt (const char *command, const char *const *argv, int argc)
       scoped_disable_commit_resumed disable_commit_resumed
 	("interrupting all threads of thread group");
 
-      iterate_over_threads (interrupt_thread_callback, &inf->pid);
+      iterate_over_threads ([&] (struct thread_info *thread)
+        {
+	  if (thread->state != THREAD_RUNNING)
+	    return false;
+
+	  if (thread->ptid.pid () != inf->pid)
+	    return false;
+
+	  target_stop (thread->ptid);
+	  return false;
+	});
     }
   else
     {
@@ -478,18 +468,6 @@  mi_cmd_exec_run (const char *command, const char *const *argv, int argc)
     }
 }
 
-
-static int
-find_thread_of_process (struct thread_info *ti, void *p)
-{
-  int pid = *(int *)p;
-
-  if (ti->ptid.pid () == pid && ti->state != THREAD_EXITED)
-    return 1;
-
-  return 0;
-}
-
 void
 mi_cmd_target_detach (const char *command, const char *const *argv, int argc)
 {
@@ -528,7 +506,12 @@  mi_cmd_target_detach (const char *command, const char *const *argv, int argc)
 
       /* Pick any thread in the desired process.  Current
 	 target_detach detaches from the parent of inferior_ptid.  */
-      tp = iterate_over_threads (find_thread_of_process, &pid);
+      tp = iterate_over_threads ([&] (struct thread_info *ti)
+        {
+	  if (ti->ptid.pid () == pid && ti->state != THREAD_EXITED)
+	    return true;
+	  return false;
+	});
       if (!tp)
 	error (_("Thread group is empty"));
 
@@ -600,28 +583,6 @@  mi_cmd_thread_info (const char *command, const char *const *argv, int argc)
   print_thread_info (current_uiout, argv[0], -1);
 }
 
-struct collect_cores_data
-{
-  int pid;
-  std::set<int> cores;
-};
-
-static int
-collect_cores (struct thread_info *ti, void *xdata)
-{
-  struct collect_cores_data *data = (struct collect_cores_data *) xdata;
-
-  if (ti->ptid.pid () == data->pid)
-    {
-      int core = target_core_of_thread (ti->ptid);
-
-      if (core != -1)
-	data->cores.insert (core);
-    }
-
-  return 0;
-}
-
 static void
 print_one_inferior (struct inferior *inferior, bool recurse,
 		    const std::set<int> &ids)
@@ -630,7 +591,7 @@  print_one_inferior (struct inferior *inferior, bool recurse,
 
   if (ids.empty () || (ids.find (inferior->pid) != ids.end ()))
     {
-      struct collect_cores_data data;
+      std::set<int> cores;
       ui_out_emit_tuple tuple_emitter (uiout, NULL);
 
       uiout->field_fmt ("id", "i%d", inferior->num);
@@ -646,15 +607,24 @@  print_one_inferior (struct inferior *inferior, bool recurse,
 
       if (inferior->pid != 0)
 	{
-	  data.pid = inferior->pid;
-	  iterate_over_threads (collect_cores, &data);
+	  iterate_over_threads ([&] (struct thread_info *ti)
+	    {
+	      if (ti->ptid.pid () == inferior->pid)
+		{
+		  int core = target_core_of_thread (ti->ptid);
+
+		  if (core != -1)
+		    cores.insert (core);
+		}
+	      return false;
+	    });
 	}
 
-      if (!data.cores.empty ())
+      if (!cores.empty ())
 	{
 	  ui_out_emit_list list_emitter (uiout, "cores");
 
-	  for (int b : data.cores)
+	  for (int b : cores)
 	    uiout->field_signed (NULL, b);
 	}
 
diff --git a/gdb/sol-thread.c b/gdb/sol-thread.c
index db86079b3fa667429403c6f1dbf2c66e0a55bb17..820b6f77819fb5c8245ae2509e8462fc97eb24d7 100644
--- a/gdb/sol-thread.c
+++ b/gdb/sol-thread.c
@@ -1108,25 +1108,16 @@  info_solthreads (const char *args, int from_tty)
 		    TD_SIGNO_MASK, TD_THR_ANY_USER_FLAGS);
 }
 
-/* Callback routine used to find a thread based on the TID part of
-   its PTID.  */
-
-static int
-thread_db_find_thread_from_tid (struct thread_info *thread, void *data)
-{
-  ULONGEST *tid = (ULONGEST *) data;
-
-  if (thread->ptid.tid () == *tid)
-    return 1;
-
-  return 0;
-}
-
 ptid_t
 sol_thread_target::get_ada_task_ptid (long lwp, ULONGEST thread)
 {
-  struct thread_info *thread_info =
-    iterate_over_threads (thread_db_find_thread_from_tid, &thread);
+  struct thread_info *thread_info
+    = iterate_over_threads ([&] (struct thread_info *thread)
+       {
+	 if (thread->ptid.tid () == thread)
+	   return true;
+	 return false;
+       });
 
   if (thread_info == NULL)
     {
diff --git a/gdb/thread.c b/gdb/thread.c
index 5892b158603a7d11cb7c7efc3346f01714797201..8a34671bb6cc0786b63b9a0008b0b0d5eb2a429e 100644
--- a/gdb/thread.c
+++ b/gdb/thread.c
@@ -602,11 +602,10 @@  find_thread_by_handle (gdb::array_view<const gdb_byte> handle,
  */
 
 struct thread_info *
-iterate_over_threads (int (*callback) (struct thread_info *, void *),
-		      void *data)
+iterate_over_threads (gdb::function_view<bool (struct thread_info *)> callback)
 {
   for (thread_info *tp : all_threads_safe ())
-    if ((*callback) (tp, data))
+    if (callback (tp))
       return tp;
 
   return NULL;