This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFC: speed up have_live_inferiors


I would appreciate comments on this patch.
In the absence of comments I will check it in.

I am working on making it possible to lazily read debuginfo.  I think
this is important for a multi-inferior scenario where most processes are
actually uninteresting.

Part of this work is tracking down places that inadvertently require
debuginfo and somehow fixing them.

have_live_inferiors calls make_cleanup_restore_current_thread.
This in turn does a surprising (to me) amount of work, including storing
the selected frame, which in turn might call the inline frame sniffer.

This patch fixes have_live_inferiors by changing to_has_execution to
accept a ptid_t, so that the check can be done without switching
threads.  It also updates all implementations of to_has_execution, of
which there are few.

Built and regtested on x86-64 (compile farm).

Tom

2011-03-01  Tom Tromey  <tromey@redhat.com>

	* target.h (struct target_ops) <to_has_execution>: Add ptid_t
	parameter.
	(target_has_execution_1): Update.
	(target_has_execution_current): Declare.
	(target_has_execution): Call target_has_execution_current.
	(default_child_has_execution): Update.
	* target.c (default_child_has_execution): Add 'the_ptid'
	parameter.
	(target_has_execution_1): Likewise.
	(target_has_execution_current): New function.
	(add_target): Update.
	(init_dummy_target): Update.
	* remote-m32r-sdi.c (m32r_has_execution): New function.
	(init_m32r_ops): Use it.
	* record.c (record_core_has_execution): Now static.  Add
	'the_ptid' parameter.
	* inferior.c (have_live_inferiors): Don't save current thread.
	Use target_has_execution_1.

diff --git a/gdb/inferior.c b/gdb/inferior.c
index 76f81c3..eb33b9a 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -462,28 +462,18 @@ have_inferiors (void)
 int
 have_live_inferiors (void)
 {
-  struct cleanup *old_chain;
   struct inferior *inf;
 
-  old_chain = make_cleanup_restore_current_thread ();
-
   for (inf = inferior_list; inf; inf = inf->next)
     if (inf->pid != 0)
       {
 	struct thread_info *tp;
 	
 	tp = any_thread_of_process (inf->pid);
-	if (tp)
-	  {
-	    switch_to_thread (tp->ptid);
-
-	    if (target_has_execution)
-	      break;
-	  }
+	if (tp && target_has_execution_1 (tp->ptid))
+	  break;
       }
 
-  do_cleanups (old_chain);
-
   return inf != NULL;
 }
 
diff --git a/gdb/record.c b/gdb/record.c
index 784f5fa..cf21779 100644
--- a/gdb/record.c
+++ b/gdb/record.c
@@ -1923,8 +1923,8 @@ record_core_remove_breakpoint (struct gdbarch *gdbarch,
 
 /* "to_has_execution" method for prec over corefile.  */
 
-int
-record_core_has_execution (struct target_ops *ops)
+static int
+record_core_has_execution (struct target_ops *ops, ptid_t the_ptid)
 {
   return 1;
 }
diff --git a/gdb/remote-m32r-sdi.c b/gdb/remote-m32r-sdi.c
index 3247b6f..70d6dd5 100644
--- a/gdb/remote-m32r-sdi.c
+++ b/gdb/remote-m32r-sdi.c
@@ -1610,6 +1610,14 @@ m32r_return_one (struct target_ops *target)
   return 1;
 }
 
+/* Implementation of the to_has_execution method.  */
+
+static int
+m32r_has_execution (struct target_ops *target, ptid_t the_ptid)
+{
+  return 1;
+}
+
 /* Define the target subroutine names.  */
 
 struct target_ops m32r_ops;
@@ -1650,7 +1658,7 @@ init_m32r_ops (void)
   m32r_ops.to_has_memory = m32r_return_one;
   m32r_ops.to_has_stack = m32r_return_one;
   m32r_ops.to_has_registers = m32r_return_one;
-  m32r_ops.to_has_execution = m32r_return_one;
+  m32r_ops.to_has_execution = m32r_has_execution;
   m32r_ops.to_magic = OPS_MAGIC;
 };
 
diff --git a/gdb/target.c b/gdb/target.c
index a4e2ae9..edf7e1c 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -314,11 +314,11 @@ default_child_has_registers (struct target_ops *ops)
 }
 
 int
-default_child_has_execution (struct target_ops *ops)
+default_child_has_execution (struct target_ops *ops, ptid_t the_ptid)
 {
   /* If there's no thread selected, then we can't make it run through
      hoops.  */
-  if (ptid_equal (inferior_ptid, null_ptid))
+  if (ptid_equal (the_ptid, null_ptid))
     return 0;
 
   return 1;
@@ -374,17 +374,23 @@ target_has_registers_1 (void)
 }
 
 int
-target_has_execution_1 (void)
+target_has_execution_1 (ptid_t the_ptid)
 {
   struct target_ops *t;
 
   for (t = current_target.beneath; t != NULL; t = t->beneath)
-    if (t->to_has_execution (t))
+    if (t->to_has_execution (t, the_ptid))
       return 1;
 
   return 0;
 }
 
+int
+target_has_execution_current (void)
+{
+  return target_has_execution_1 (inferior_ptid);
+}
+
 /* Add a possible target architecture to the list.  */
 
 void
@@ -407,7 +413,7 @@ add_target (struct target_ops *t)
     t->to_has_registers = (int (*) (struct target_ops *)) return_zero;
 
   if (t->to_has_execution == NULL)
-    t->to_has_execution = (int (*) (struct target_ops *)) return_zero;
+    t->to_has_execution = (int (*) (struct target_ops *, ptid_t)) return_zero;
 
   if (!target_structs)
     {
@@ -3218,7 +3224,8 @@ init_dummy_target (void)
   dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero;
   dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero;
   dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero;
-  dummy_target.to_has_execution = (int (*) (struct target_ops *)) return_zero;
+  dummy_target.to_has_execution
+    = (int (*) (struct target_ops *, ptid_t)) return_zero;
   dummy_target.to_stopped_by_watchpoint = return_zero;
   dummy_target.to_stopped_data_address =
     (int (*) (struct target_ops *, CORE_ADDR *)) return_zero;
diff --git a/gdb/target.h b/gdb/target.h
index e856dde..e19f7b7 100644
--- a/gdb/target.h
+++ b/gdb/target.h
@@ -510,7 +510,7 @@ struct target_ops
     int (*to_has_memory) (struct target_ops *);
     int (*to_has_stack) (struct target_ops *);
     int (*to_has_registers) (struct target_ops *);
-    int (*to_has_execution) (struct target_ops *);
+    int (*to_has_execution) (struct target_ops *, ptid_t);
     int to_has_thread_control;	/* control thread execution */
     int to_attach_no_wait;
     /* ASYNC target controls */
@@ -1189,8 +1189,13 @@ extern int target_has_registers_1 (void);
    case this will become true after target_create_inferior or
    target_attach.  */
 
-extern int target_has_execution_1 (void);
-#define target_has_execution target_has_execution_1 ()
+extern int target_has_execution_1 (ptid_t);
+
+/* Like target_has_execution_1, but always passes inferior_ptid.  */
+
+extern int target_has_execution_current (void);
+
+#define target_has_execution target_has_execution_current ()
 
 /* Default implementations for process_stratum targets.  Return true
    if there's a selected inferior, false otherwise.  */
@@ -1199,7 +1204,8 @@ extern int default_child_has_all_memory (struct target_ops *ops);
 extern int default_child_has_memory (struct target_ops *ops);
 extern int default_child_has_stack (struct target_ops *ops);
 extern int default_child_has_registers (struct target_ops *ops);
-extern int default_child_has_execution (struct target_ops *ops);
+extern int default_child_has_execution (struct target_ops *ops,
+					ptid_t the_ptid);
 
 /* Can the target support the debugger control of thread execution?
    Can it lock the thread scheduler?  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]