* target.h (struct thread_resume): Delete leave_stopped member.
authorPedro Alves <palves@redhat.com>
Wed, 1 Apr 2009 22:29:33 +0000 (22:29 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 1 Apr 2009 22:29:33 +0000 (22:29 +0000)
(struct target_ops): Add a `n' argument to the `resume' callback.
* server.c (start_inferior): Adjust.
(handle_v_cont, myresume): Adjust.
* linux-low.c (check_removed_breakpoint): Adjust to resume
interface change, and to removed leave_stopped field.
(resume_ptr): Delete.
(struct thread_resume_array): New.
(linux_set_resume_request): Add new `arg' parameter.  Adjust to
resume interface change.
(linux_continue_one_thread, linux_queue_one_thread)
(resume_status_pending_p): Check if the resume field is NULL
instead of checking the leave_stopped member.
(linux_resume): Adjust to the target resume interface change.
* spu-low.c (spu_resume): Adjust to the target resume interface
change.
* win32-low.c (win32_detach, win32_resume): Ditto.

gdb/gdbserver/ChangeLog
gdb/gdbserver/linux-low.c
gdb/gdbserver/server.c
gdb/gdbserver/spu-low.c
gdb/gdbserver/target.h
gdb/gdbserver/win32-low.c

index f0e0cdebe3e88529e225c6e721ceba0c6a4a50af..ed70d446d3f147ebc0785d3297b468f58e46e5aa 100644 (file)
@@ -1,3 +1,23 @@
+2009-04-01  Pedro Alves  <pedro@codesourcery.com>
+
+       * target.h (struct thread_resume): Delete leave_stopped member.
+       (struct target_ops): Add a `n' argument to the `resume' callback.
+       * server.c (start_inferior): Adjust.
+       (handle_v_cont, myresume): Adjust.
+       * linux-low.c (check_removed_breakpoint): Adjust to resume
+       interface change, and to removed leave_stopped field.
+       (resume_ptr): Delete.
+       (struct thread_resume_array): New.
+       (linux_set_resume_request): Add new `arg' parameter.  Adjust to
+       resume interface change.
+       (linux_continue_one_thread, linux_queue_one_thread)
+       (resume_status_pending_p): Check if the resume field is NULL
+       instead of checking the leave_stopped member.
+       (linux_resume): Adjust to the target resume interface change.
+       * spu-low.c (spu_resume): Adjust to the target resume interface
+       change.
+       * win32-low.c (win32_detach, win32_resume): Ditto.
+
 2009-04-01  Pedro Alves  <pedro@codesourcery.com>
 
        * linux-low.c (linux_wait_for_event): Don't clear the `stepping'
index ea103f26b5321411b6099ec7caee7caf4379c4b1..c1f533f60a27635746773d7d087de21a0fe528a6 100644 (file)
@@ -116,7 +116,7 @@ static int new_inferior;
 
 static void linux_resume_one_lwp (struct inferior_list_entry *entry,
                                  int step, int signal, siginfo_t *info);
-static void linux_resume (struct thread_resume *resume_info);
+static void linux_resume (struct thread_resume *resume_info, size_t n);
 static void stop_all_lwps (void);
 static int linux_wait_for_event (struct thread_info *child);
 static int check_removed_breakpoint (struct lwp_info *event_child);
@@ -952,8 +952,8 @@ retry:
        {
          struct thread_resume resume_info;
          resume_info.thread = -1;
-         resume_info.step = resume_info.sig = resume_info.leave_stopped = 0;
-         linux_resume (&resume_info);
+         resume_info.step = resume_info.sig = 0;
+         linux_resume (&resume_info, 1);
        }
     }
 
@@ -1247,7 +1247,11 @@ linux_resume_one_lwp (struct inferior_list_entry *entry,
     }
 }
 
-static struct thread_resume *resume_ptr;
+struct thread_resume_array
+{
+  struct thread_resume *resume;
+  size_t n;
+};
 
 /* This function is called once per thread.  We look up the thread
    in RESUME_PTR, and mark the thread with a pointer to the appropriate
@@ -1256,21 +1260,29 @@ static struct thread_resume *resume_ptr;
    This algorithm is O(threads * resume elements), but resume elements
    is small (and will remain small at least until GDB supports thread
    suspension).  */
-static void
-linux_set_resume_request (struct inferior_list_entry *entry)
+static int
+linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 {
   struct lwp_info *lwp;
   struct thread_info *thread;
   int ndx;
+  struct thread_resume_array *r;
 
   thread = (struct thread_info *) entry;
   lwp = get_thread_lwp (thread);
+  r = arg;
 
-  ndx = 0;
-  while (resume_ptr[ndx].thread != -1 && resume_ptr[ndx].thread != entry->id)
-    ndx++;
+  for (ndx = 0; ndx < r->n; ndx++)
+    if (r->resume[ndx].thread == -1 || r->resume[ndx].thread == entry->id)
+      {
+       lwp->resume = &r->resume[ndx];
+       return 0;
+      }
+
+  /* No resume action for this thread.  */
+  lwp->resume = NULL;
 
-  lwp->resume = &resume_ptr[ndx];
+  return 0;
 }
 
 /* This function is called once per thread.  We check the thread's resume
@@ -1289,7 +1301,7 @@ linux_continue_one_thread (struct inferior_list_entry *entry)
   thread = (struct thread_info *) entry;
   lwp = get_thread_lwp (thread);
 
-  if (lwp->resume->leave_stopped)
+  if (lwp->resume == NULL)
     return;
 
   if (lwp->resume->thread == -1
@@ -1320,7 +1332,7 @@ linux_queue_one_thread (struct inferior_list_entry *entry)
   thread = (struct thread_info *) entry;
   lwp = get_thread_lwp (thread);
 
-  if (lwp->resume->leave_stopped)
+  if (lwp->resume == NULL)
     return;
 
   /* If we have a new signal, enqueue the signal.  */
@@ -1354,7 +1366,7 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
 
   /* Processes which will not be resumed are not interesting, because
      we might not wait for them next time through linux_wait.  */
-  if (lwp->resume->leave_stopped)
+  if (lwp->resume == NULL)
     return 0;
 
   /* If this thread has a removed breakpoint, we won't have any
@@ -1375,14 +1387,12 @@ resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
 }
 
 static void
-linux_resume (struct thread_resume *resume_info)
+linux_resume (struct thread_resume *resume_info, size_t n)
 {
   int pending_flag;
+  struct thread_resume_array array = { resume_info, n };
 
-  /* Yes, the use of a global here is rather ugly.  */
-  resume_ptr = resume_info;
-
-  for_each_inferior (&all_threads, linux_set_resume_request);
+  find_inferior (&all_threads, linux_set_resume_request, &array);
 
   /* If there is a thread which would otherwise be resumed, which
      has a pending status, then don't resume any threads - we can just
index aef6be763ff109612c061efa108d7a4e1a6d9e2b..2be5e0e4ba77486a666676947e649cc1af155d8d 100644 (file)
@@ -146,7 +146,6 @@ start_inferior (char **argv, char *statusptr)
       resume_info.thread = -1;
       resume_info.step = 0;
       resume_info.sig = 0;
-      resume_info.leave_stopped = 0;
 
       sig = mywait (statusptr, 0);
       if (*statusptr != 'T')
@@ -154,7 +153,7 @@ start_inferior (char **argv, char *statusptr)
 
       do
        {
-         (*the_target->resume) (&resume_info);
+         (*the_target->resume) (&resume_info, 1);
 
          sig = mywait (statusptr, 0);
          if (*statusptr != 'T')
@@ -1056,7 +1055,8 @@ handle_v_cont (char *own_buf, char *status, int *signal)
 {
   char *p, *q;
   int n = 0, i = 0;
-  struct thread_resume *resume_info, default_action;
+  struct thread_resume *resume_info;
+  struct thread_resume default_action = {0};
 
   /* Count the number of semicolons in the packet.  There should be one
      for every action.  */
@@ -1067,26 +1067,16 @@ handle_v_cont (char *own_buf, char *status, int *signal)
       p++;
       p = strchr (p, ';');
     }
-  /* Allocate room for one extra action, for the default remain-stopped
-     behavior; if no default action is in the list, we'll need the extra
-     slot.  */
-  resume_info = malloc ((n + 1) * sizeof (resume_info[0]));
+
+  resume_info = malloc (n * sizeof (resume_info[0]));
   if (resume_info == NULL)
     goto err;
 
-  default_action.thread = -1;
-  default_action.leave_stopped = 1;
-  default_action.step = 0;
-  default_action.sig = 0;
-
   p = &own_buf[5];
-  i = 0;
   while (*p)
     {
       p++;
 
-      resume_info[i].leave_stopped = 0;
-
       if (p[0] == 's' || p[0] == 'S')
        resume_info[i].step = 1;
       else if (p[0] == 'c' || p[0] == 'C')
@@ -1141,7 +1131,8 @@ handle_v_cont (char *own_buf, char *status, int *signal)
        }
     }
 
-  resume_info[i] = default_action;
+  if (i < n)
+    resume_info[i] = default_action;
 
   /* Still used in occasional places in the backend.  */
   if (n == 1 && resume_info[0].thread != -1)
@@ -1151,7 +1142,7 @@ handle_v_cont (char *own_buf, char *status, int *signal)
   set_desired_inferior (0);
 
   enable_async_io ();
-  (*the_target->resume) (resume_info);
+  (*the_target->resume) (resume_info, n);
 
   free (resume_info);
 
@@ -1333,25 +1324,31 @@ myresume (char *own_buf, int step, int *signalp, char *statusp)
   struct thread_resume resume_info[2];
   int n = 0;
   int sig = *signalp;
+  int valid_cont_thread;
 
   set_desired_inferior (0);
 
-  if (step || sig || (cont_thread != 0 && cont_thread != -1))
+  valid_cont_thread = (cont_thread != 0 && cont_thread != -1);
+
+  if (step || sig || valid_cont_thread)
     {
       resume_info[0].thread
        = ((struct inferior_list_entry *) current_inferior)->id;
       resume_info[0].step = step;
       resume_info[0].sig = sig;
-      resume_info[0].leave_stopped = 0;
       n++;
     }
-  resume_info[n].thread = -1;
-  resume_info[n].step = 0;
-  resume_info[n].sig = 0;
-  resume_info[n].leave_stopped = (cont_thread != 0 && cont_thread != -1);
+
+  if (!valid_cont_thread)
+    {
+      resume_info[n].thread = -1;
+      resume_info[n].step = 0;
+      resume_info[n].sig = 0;
+      n++;
+    }
 
   enable_async_io ();
-  (*the_target->resume) (resume_info);
+  (*the_target->resume) (resume_info, n);
   *signalp = mywait (statusp, 1);
   prepare_resume_reply (own_buf, *statusp, *signalp);
   disable_async_io ();
index 12d25e8b19087277e66a6c903ab761a440a29fdc..792241cd8ab009d73f2e030c2964b59cc6ffacae 100644 (file)
@@ -345,24 +345,27 @@ spu_thread_alive (unsigned long tid)
 
 /* Resume process.  */
 static void
-spu_resume (struct thread_resume *resume_info)
+spu_resume (struct thread_resume *resume_info, size_t n)
 {
-  while (resume_info->thread != -1
-        && resume_info->thread != current_tid)
-    resume_info++;
+  size_t i;
 
-  if (resume_info->leave_stopped)
+  for (i = 0; i < n; i++)
+    if (resume_info[i].thread == -1
+       || resume_info[i].thread == current_tid)
+      break;
+
+  if (i == n)
     return;
 
   /* We don't support hardware single-stepping right now, assume
      GDB knows to use software single-stepping.  */
-  if (resume_info->step)
+  if (resume_info[i].step)
     fprintf (stderr, "Hardware single-step not supported.\n");
 
   regcache_invalidate ();
 
   errno = 0;
-  ptrace (PTRACE_CONT, current_tid, 0, resume_info->sig);
+  ptrace (PTRACE_CONT, current_tid, 0, resume_info[i].sig);
   if (errno)
     perror_with_name ("ptrace");
 }
index ca0135f59e1b89430fe6700bead84afb85a6e1b6..5bd589654c6bbe054c3dae4a24b59c68ec80b7b2 100644 (file)
 #ifndef TARGET_H
 #define TARGET_H
 
-/* This structure describes how to resume a particular thread (or
-   all threads) based on the client's request.  If thread is -1, then
-   this entry applies to all threads.  These are generally passed around
-   as an array, and terminated by a thread == -1 entry.  */
+/* This structure describes how to resume a particular thread (or all
+   threads) based on the client's request.  If thread is -1, then this
+   entry applies to all threads.  These are passed around as an
+   array.  */
 
 struct thread_resume
 {
   unsigned long thread;
 
-  /* If non-zero, leave this thread stopped.  */
-  int leave_stopped;
-
   /* If non-zero, we want to single-step.  */
   int step;
 
@@ -83,7 +80,7 @@ struct target_ops
 
   /* Resume the inferior process.  */
 
-  void (*resume) (struct thread_resume *resume_info);
+  void (*resume) (struct thread_resume *resume_info, size_t n);
 
   /* Wait for the inferior process to change state.
 
index db9a95ecfbb4cb652e306425088e93103fb1964c..7c63ff44e8eb7e565529f9e6e7c9fe51404b4dc1 100644 (file)
@@ -90,7 +90,7 @@ typedef BOOL WINAPI (*winapi_DebugSetProcessKillOnExit) (BOOL KillOnExit);
 typedef BOOL WINAPI (*winapi_DebugBreakProcess) (HANDLE);
 typedef BOOL WINAPI (*winapi_GenerateConsoleCtrlEvent) (DWORD, DWORD);
 
-static void win32_resume (struct thread_resume *resume_info);
+static void win32_resume (struct thread_resume *resume_info, size_t n);
 
 /* Get the thread ID from the current selected inferior (the current
    thread).  */
@@ -726,8 +726,7 @@ win32_detach (void)
     resume.thread = -1;
     resume.step = 0;
     resume.sig = 0;
-    resume.leave_stopped = 0;
-    win32_resume (&resume);
+    win32_resume (&resume, 1);
   }
 
   if (!DebugActiveProcessStop (current_process_id))
@@ -771,7 +770,7 @@ win32_thread_alive (unsigned long tid)
 /* Resume the inferior process.  RESUME_INFO describes how we want
    to resume.  */
 static void
-win32_resume (struct thread_resume *resume_info)
+win32_resume (struct thread_resume *resume_info, size_t n)
 {
   DWORD tid;
   enum target_signal sig;
@@ -782,9 +781,9 @@ win32_resume (struct thread_resume *resume_info)
   /* This handles the very limited set of resume packets that GDB can
      currently produce.  */
 
-  if (resume_info[0].thread == -1)
+  if (n == 1 && resume_info[0].thread == -1)
     tid = -1;
-  else if (resume_info[1].thread == -1 && !resume_info[1].leave_stopped)
+  else if (n > 1)
     tid = -1;
   else
     /* Yes, we're ignoring resume_info[0].thread.  It'd be tricky to make