Non-stop inferior control.
authorPedro Alves <palves@redhat.com>
Wed, 9 Jul 2008 22:42:43 +0000 (22:42 +0000)
committerPedro Alves <palves@redhat.com>
Wed, 9 Jul 2008 22:42:43 +0000 (22:42 +0000)
* infrun.c (resume): In non-stop mode, always resume just one
thread.
(proceed): Don't call prepare_to_proceed in non-stop mode.
(fetch_inferior_event): In non-stop mode, switch context before
handling the event.
(error_is_running, ensure_not_running): New.
(handle_inferior_event): In non-stop mode: Mark only the event
thread as stopped.  Require that the target module manages adding
threads to the thread list.  Assert that there isn't a
deferred_step_ptid set.  Don't switch to infwait_thread_hop_state.
(normal_stop): Only mark not-running if inferior hasn't exited.
In non-stop mode, only mark the event thread.

* thread.c:Include "cli/cli-decode.h".
(print_thread_info): Don't read from a running thread.
Output "(running)" if thread is running.
(switch_to_thread): Don't read stop_pc if thread is executing.
(do_restore_current_thread_cleanup): Don't write to a running
thread.
(thread_apply_all_command): Don't read from a running thread.  In
non-stop mode, do a full context-switch instead of just switching
threads.
(thread_apply_command): In non-stop mode, do a full context-switch
instead of just switching threads.
(do_captured_thread_select): Likewise.  Inform user if selected
thread is running.
(_initialize_thread): Mark "info threads" and "thread" and
async_ok.

* inf-loop.c (inferior_event_handler): In non-stop mode, don't
unregister the target from the event loop.

* infcmd.c (continue_command, step_1, jump_command)
(signal_command): Ensure the selected thread isn't running.
(interrupt_target_command): In non-stop mode, interrupt only the
selected thread.

* inferior.h (error_is_running, ensure_not_running): Declare.

* target.h (struct target_ops): Add ptid argument to the to_stop
member.
(target_stop): Add ptid_t argument.

* target.c (update_current_target): Add ptid argument to to_stop's
type.
(debug_to_stop): Add ptid_t argument.
(debug_to_rcmd): Set to_stop_ptid.

* remote.c (remote_stop): Add ptid_t argument.
(async_remote_interrupt): Add inferior_ptid to target_stop.
* inf-ptrace.c (inf_ptrace_stop): Add ptid argument.

* Makefile.in (thread.o): Depend on $(cli_decode_h).

gdb/ChangeLog
gdb/Makefile.in
gdb/inf-loop.c
gdb/inf-ptrace.c
gdb/infcmd.c
gdb/inferior.h
gdb/infrun.c
gdb/remote.c
gdb/target.c
gdb/target.h
gdb/thread.c

index 42a147a04d48614c7c9fc517ed64bcd0ca793e47..6231f89aa7da92b421bb9b67a276456c3da6e8e8 100644 (file)
@@ -1,3 +1,61 @@
+2008-07-09  Pedro Alves  <pedro@codesourcery.com>
+
+       Non-stop inferior control.
+
+       * infrun.c (resume): In non-stop mode, always resume just one
+       thread.
+       (proceed): Don't call prepare_to_proceed in non-stop mode.
+       (fetch_inferior_event): In non-stop mode, switch context before
+       handling the event.
+       (error_is_running, ensure_not_running): New.
+       (handle_inferior_event): In non-stop mode: Mark only the event
+       thread as stopped.  Require that the target module manages adding
+       threads to the thread list.  Assert that there isn't a
+       deferred_step_ptid set.  Don't switch to infwait_thread_hop_state.
+       (normal_stop): Only mark not-running if inferior hasn't exited.
+       In non-stop mode, only mark the event thread.
+
+       * thread.c:Include "cli/cli-decode.h".
+       (print_thread_info): Don't read from a running thread.
+       Output "(running)" if thread is running.
+       (switch_to_thread): Don't read stop_pc if thread is executing.
+       (do_restore_current_thread_cleanup): Don't write to a running
+       thread.
+       (thread_apply_all_command): Don't read from a running thread.  In
+       non-stop mode, do a full context-switch instead of just switching
+       threads.
+       (thread_apply_command): In non-stop mode, do a full context-switch
+       instead of just switching threads.
+       (do_captured_thread_select): Likewise.  Inform user if selected
+       thread is running.
+       (_initialize_thread): Mark "info threads" and "thread" and
+       async_ok.
+
+       * inf-loop.c (inferior_event_handler): In non-stop mode, don't
+       unregister the target from the event loop.
+
+       * infcmd.c (continue_command, step_1, jump_command)
+       (signal_command): Ensure the selected thread isn't running.
+       (interrupt_target_command): In non-stop mode, interrupt only the
+       selected thread.
+
+       * inferior.h (error_is_running, ensure_not_running): Declare.
+
+       * target.h (struct target_ops): Add ptid argument to the to_stop
+       member.
+       (target_stop): Add ptid_t argument.
+
+       * target.c (update_current_target): Add ptid argument to to_stop's
+       type.
+       (debug_to_stop): Add ptid_t argument.
+       (debug_to_rcmd): Set to_stop_ptid.
+
+       * remote.c (remote_stop): Add ptid_t argument.
+       (async_remote_interrupt): Add inferior_ptid to target_stop.
+       * inf-ptrace.c (inf_ptrace_stop): Add ptid argument.
+
+       * Makefile.in (thread.o): Depend on $(cli_decode_h).
+
 2008-07-09  Pedro Alves  <pedro@codesourcery.com>
 
        Don't rely on ecs->wait_for_more.
index d041e30fc7344766fed6df637573d0d86bfbcee9..efa18ea1622d99199e0b1b286c2afb83bd96ad69 100644 (file)
@@ -2921,7 +2921,7 @@ target-memory.o: target-memory.c $(defs_h) $(vec_h) $(target_h) \
 thread.o: thread.c $(defs_h) $(symtab_h) $(frame_h) $(inferior_h) \
        $(environ_h) $(value_h) $(target_h) $(gdbthread_h) $(exceptions_h) \
        $(command_h) $(gdbcmd_h) $(regcache_h) $(gdb_h) $(gdb_string_h) \
-       $(ui_out_h) $(observer_h) $(annotate_h)
+       $(ui_out_h) $(observer_h) $(annotate_h) $(cli_decode_h)
 top.o: top.c $(defs_h) $(gdbcmd_h) $(call_cmds_h) $(cli_cmds_h) \
        $(cli_script_h) $(cli_setshow_h) $(cli_decode_h) $(symtab_h) \
        $(inferior_h) $(exceptions_h) $(target_h) $(breakpoint_h) \
index 3f98bfcaa15d2e89d155186616e6f820e66a7e04..94ced19ad980c484e1c7f2b5196bfb63e192c658 100644 (file)
@@ -73,11 +73,15 @@ inferior_event_handler (enum inferior_event_type event_type,
       break;
 
     case INF_EXEC_COMPLETE:
-      /* Unregister the inferior from the event loop. This is done so that
-        when the inferior is not running we don't get distracted by
-        spurious inferior output.  */
-      if (target_has_execution)
-       target_async (NULL, 0);
+
+      if (!non_stop)
+       {
+         /* Unregister the inferior from the event loop. This is done
+            so that when the inferior is not running we don't get
+            distracted by spurious inferior output.  */
+         if (target_has_execution)
+           target_async (NULL, 0);
+       }
 
       /* The call to async_enable_stdin below resets 'sync_execution'.
         However, if sync_execution is 1 now, we also need to show the
index e4f0d1ded406560bae09005be8a22850c6eceb5c..ee2c8fa397daab5705c73553e0915dc10ea9311b 100644 (file)
@@ -297,7 +297,7 @@ inf_ptrace_kill (void)
 /* Stop the inferior.  */
 
 static void
-inf_ptrace_stop (void)
+inf_ptrace_stop (ptid_t ptid)
 {
   /* Send a SIGINT to the process group.  This acts just like the user
      typed a ^C on the controlling terminal.  Note that using a
index fead6d16a7aa8cd953d48325495c4ef6aadc8f4e..db03cf27938c71877c05df3b66b6ffd45dfc3bf4 100644 (file)
@@ -613,6 +613,7 @@ continue_command (char *proc_count_exp, int from_tty)
 {
   int async_exec = 0;
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background. */
   if (proc_count_exp != NULL)
@@ -714,6 +715,7 @@ step_1 (int skip_subroutines, int single_inst, char *count_string)
   int thread = -1;
 
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   if (count_string)
     async_exec = strip_bg_char (&count_string);
@@ -936,6 +938,7 @@ jump_command (char *arg, int from_tty)
   int async_exec = 0;
 
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background. */
   if (arg != NULL)
@@ -1036,6 +1039,7 @@ signal_command (char *signum_exp, int from_tty)
 
   dont_repeat ();              /* Too dangerous.  */
   ERROR_NO_INFERIOR;
+  ensure_not_running ();
 
   /* Find out whether we must run in the background.  */
   if (signum_exp != NULL)
@@ -2102,7 +2106,8 @@ interrupt_target_command (char *args, int from_tty)
   if (target_can_async_p ())
     {
       dont_repeat ();          /* Not for the faint of heart */
-      target_stop ();
+
+      target_stop (inferior_ptid);
     }
 }
 
index e89fb74b978bad14e369e1845c87017226d6a141..60d0352f9adc53a04c7bcdc814ad2125b1806df4 100644 (file)
@@ -245,6 +245,12 @@ extern void get_last_target_status(ptid_t *ptid,
 
 extern void follow_inferior_reset_breakpoints (void);
 
+/* Throw an error indicating the current thread is running.  */
+extern void error_is_running (void);
+
+/* Calls error_is_running if the current thread is running.  */
+extern void ensure_not_running (void);
+
 /* From infcmd.c */
 
 extern void tty_command (char *, int);
index fdf17a35222a5fc19d72236e896b053b68d7f739..f74b945eb421b1e0b431887a150597a7a0890524 100644 (file)
@@ -1056,9 +1056,15 @@ a command like `return' or `jump' to continue execution."));
          resume_ptid = inferior_ptid;
        }
 
-      if ((scheduler_mode == schedlock_on)
-         || (scheduler_mode == schedlock_step
-             && (step || singlestep_breakpoints_inserted_p)))
+      if (non_stop)
+       {
+         /* With non-stop mode on, threads are always handled
+            individually.  */
+         resume_ptid = inferior_ptid;
+       }
+      else if ((scheduler_mode == schedlock_on)
+              || (scheduler_mode == schedlock_step
+                  && (step || singlestep_breakpoints_inserted_p)))
        {
          /* User-settable 'scheduler' mode requires solo thread resume. */
          resume_ptid = inferior_ptid;
@@ -1219,19 +1225,27 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
                        "infrun: proceed (addr=0x%s, signal=%d, step=%d)\n",
                        paddr_nz (addr), siggnal, step);
 
-  /* In a multi-threaded task we may select another thread
-     and then continue or step.
-
-     But if the old thread was stopped at a breakpoint, it
-     will immediately cause another breakpoint stop without
-     any execution (i.e. it will report a breakpoint hit
-     incorrectly).  So we must step over it first.
-
-     prepare_to_proceed checks the current thread against the thread
-     that reported the most recent event.  If a step-over is required
-     it returns TRUE and sets the current thread to the old thread. */
-  if (prepare_to_proceed (step))
-    oneproc = 1;
+  if (non_stop)
+    /* In non-stop, each thread is handled individually.  The context
+       must already be set to the right thread here.  */
+    ;
+  else
+    {
+      /* In a multi-threaded task we may select another thread and
+        then continue or step.
+
+        But if the old thread was stopped at a breakpoint, it will
+        immediately cause another breakpoint stop without any
+        execution (i.e. it will report a breakpoint hit incorrectly).
+        So we must step over it first.
+
+        prepare_to_proceed checks the current thread against the
+        thread that reported the most recent event.  If a step-over
+        is required it returns TRUE and sets the current thread to
+        the old thread. */
+      if (prepare_to_proceed (step))
+       oneproc = 1;
+    }
 
   if (oneproc)
     {
@@ -1535,6 +1549,15 @@ fetch_inferior_event (void *client_data)
   else
     ecs->ptid = target_wait (waiton_ptid, &ecs->ws);
 
+  if (non_stop
+      && ecs->ws.kind != TARGET_WAITKIND_IGNORE
+      && ecs->ws.kind != TARGET_WAITKIND_EXITED
+      && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED)
+    /* In non-stop mode, each thread is handled individually.  Switch
+       early, so the global state is set correctly for this
+       thread.  */
+    context_switch (ecs->ptid);
+
   /* Now figure out what to do with the result of the result.  */
   handle_inferior_event (ecs);
 
@@ -1745,6 +1768,20 @@ init_infwait_state (void)
   infwait_state = infwait_normal_state;
 }
 
+void
+error_is_running (void)
+{
+  error (_("\
+Cannot execute this command while the selected thread is running."));
+}
+
+void
+ensure_not_running (void)
+{
+  if (is_running (inferior_ptid))
+    error_is_running ();
+}
+
 /* Given an execution control state that has been freshly filled in
    by an event from the inferior, figure out what it means and take
    appropriate action.  */
@@ -1818,10 +1855,16 @@ handle_inferior_event (struct execution_control_state *ecs)
       && ecs->ws.kind != TARGET_WAITKIND_SIGNALLED && ecs->new_thread_event)
     add_thread (ecs->ptid);
 
-  /* Mark all threads as not-executing.  In non-stop, this should be
-     adjusted to only mark ecs->ptid.  */
   if (ecs->ws.kind != TARGET_WAITKIND_IGNORE)
-    set_executing (pid_to_ptid (-1), 0);
+    {
+      /* Mark the non-executing threads accordingly.  */
+      if (!non_stop
+         || ecs->ws.kind == TARGET_WAITKIND_EXITED
+         || ecs->ws.kind == TARGET_WAITKIND_SIGNALLED)
+       set_executing (pid_to_ptid (-1), 0);
+      else
+       set_executing (ecs->ptid, 0);
+    }
 
   switch (ecs->ws.kind)
     {
@@ -2059,15 +2102,22 @@ handle_inferior_event (struct execution_control_state *ecs)
       return;
     }
 
-  /* We may want to consider not doing a resume here in order to give
-     the user a chance to play with the new thread.  It might be good
-     to make that a user-settable option.  */
-
-  /* At this point, all threads are stopped (happens automatically in
-     either the OS or the native code).  Therefore we need to continue
-     all threads in order to make progress.  */
   if (ecs->new_thread_event)
     {
+      if (non_stop)
+       /* Non-stop assumes that the target handles adding new threads
+          to the thread list.  */
+       internal_error (__FILE__, __LINE__, "\
+targets should add new threads to the thread list themselves in non-stop mode.");
+
+      /* We may want to consider not doing a resume here in order to
+        give the user a chance to play with the new thread.  It might
+        be good to make that a user-settable option.  */
+
+      /* At this point, all threads are stopped (happens automatically
+        in either the OS or the native code).  Therefore we need to
+        continue all threads in order to make progress.  */
+
       target_resume (RESUME_ALL, 0, TARGET_SIGNAL_0);
       prepare_to_wait (ecs);
       return;
@@ -2134,6 +2184,9 @@ handle_inferior_event (struct execution_control_state *ecs)
 
   if (!ptid_equal (deferred_step_ptid, null_ptid))
     {
+      /* In non-stop mode, there's never a deferred_step_ptid set.  */
+      gdb_assert (!non_stop);
+
       /* If we stopped for some other reason than single-stepping, ignore
         the fact that we were supposed to switch back.  */
       if (stop_signal == TARGET_SIGNAL_TRAP)
@@ -2282,8 +2335,13 @@ handle_inferior_event (struct execution_control_state *ecs)
              if (!ptid_equal (inferior_ptid, ecs->ptid))
                context_switch (ecs->ptid);
 
-             waiton_ptid = ecs->ptid;
-             infwait_state = infwait_thread_hop_state;
+             if (!non_stop)
+               {
+                 /* Only need to require the next event from this
+                    thread in all-stop mode.  */
+                 waiton_ptid = ecs->ptid;
+                 infwait_state = infwait_thread_hop_state;
+               }
 
              tss->stepping_over_breakpoint = 1;
              keep_going (ecs);
@@ -3838,7 +3896,16 @@ done:
   /* Delete the breakpoint we stopped at, if it wants to be deleted.
      Delete any breakpoint that is to be deleted at the next stop.  */
   breakpoint_auto_delete (stop_bpstat);
-  set_running (pid_to_ptid (-1), 0);
+
+  if (target_has_execution
+      && last.kind != TARGET_WAITKIND_SIGNALLED
+      && last.kind != TARGET_WAITKIND_EXITED)
+    {
+      if (!non_stop)
+       set_running (pid_to_ptid (-1), 0);
+      else
+       set_running (inferior_ptid, 0);
+    }
 }
 
 static int
index 4792cada24a9d7e8214edaf78fd271a8e10e568b..14e04da7ba9711309520b3f6ec921cff2a28c220 100644 (file)
@@ -155,7 +155,7 @@ static void init_remote_ops (void);
 
 static void init_extended_remote_ops (void);
 
-static void remote_stop (void);
+static void remote_stop (ptid_t);
 
 static int ishex (int ch, int *val);
 
@@ -3269,7 +3269,7 @@ async_remote_interrupt (gdb_client_data arg)
   if (remote_debug)
     fprintf_unfiltered (gdb_stdlog, "remote_interrupt called\n");
 
-  target_stop ();
+  target_stop (inferior_ptid);
 }
 
 /* Perform interrupt, if the first attempt did not succeed. Just give
@@ -3323,7 +3323,7 @@ remote_interrupt_twice (int signo)
    interrupt is requested, either by the command line or the GUI, we
    will eventually end up here.  */
 static void
-remote_stop (void)
+remote_stop (ptid_t ptid)
 {
   /* Send a break or a ^C, depending on user preference.  */
   if (remote_debug)
index 6e7108035b942476383e7d0071d480171545ef8c..461cfe390c22362cc5adf3701ef2453d76f7d47c 100644 (file)
@@ -165,7 +165,7 @@ static void debug_to_notice_signals (ptid_t);
 
 static int debug_to_thread_alive (ptid_t);
 
-static void debug_to_stop (void);
+static void debug_to_stop (ptid_t);
 
 /* NOTE: cagney/2004-09-29: Many targets reference this variable in
    wierd and mysterious ways.  Putting the variable here lets those
@@ -630,7 +630,7 @@ update_current_target (void)
            (char *(*) (struct thread_info *))
            return_zero);
   de_fault (to_stop,
-           (void (*) (void))
+           (void (*) (ptid_t))
            target_ignore);
   current_target.to_xfer_partial = current_xfer_partial;
   de_fault (to_rcmd,
@@ -2997,11 +2997,12 @@ debug_to_find_new_threads (void)
 }
 
 static void
-debug_to_stop (void)
+debug_to_stop (ptid_t ptid)
 {
-  debug_target.to_stop ();
+  debug_target.to_stop (ptid);
 
-  fprintf_unfiltered (gdb_stdlog, "target_stop ()\n");
+  fprintf_unfiltered (gdb_stdlog, "target_stop (%s)\n",
+                     target_pid_to_str (ptid));
 }
 
 static void
index db2d58e44c200671cb5e27cb073c655d7ebc432b..e2425667ea8e307b53a94888152a48cc5a9f091d 100644 (file)
@@ -401,7 +401,7 @@ struct target_ops
     void (*to_find_new_threads) (void);
     char *(*to_pid_to_str) (ptid_t);
     char *(*to_extra_thread_info) (struct thread_info *);
-    void (*to_stop) (void);
+    void (*to_stop) (ptid_t);
     void (*to_rcmd) (char *command, struct ui_file *output);
     char *(*to_pid_to_exec_file) (int pid);
     void (*to_log_command) (const char *);
@@ -906,7 +906,7 @@ int target_follow_fork (int follow_child);
    Unix, this should act like SIGSTOP).  This function is normally
    used by GUIs to implement a stop button.  */
 
-#define target_stop current_target.to_stop
+#define target_stop(ptid) (*current_target.to_stop) (ptid)
 
 /* Send the specified COMMAND to the target's monitor
    (shell,interpreter) for execution.  The result of the query is
index e2f8cd7f3432aa754e458ee254680ae3167b852b..1ae9adfebef23fb3f9c6f5f665a2d7cf6bc6582b 100644 (file)
@@ -42,6 +42,8 @@
 #include "observer.h"
 #include "annotate.h"
 
+#include "cli/cli-decode.h"
+
 /* Definition of struct thread_info exported to gdbthread.h */
 
 /* Prototypes for exported functions. */
@@ -640,9 +642,12 @@ print_thread_info (struct ui_out *uiout, int requested_thread)
   int current_thread = -1;
 
   /* Backup current thread and selected frame.  */
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
-  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
 
+  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
   make_cleanup_ui_out_list_begin_end (uiout, "threads");
 
   prune_threads ();
@@ -677,12 +682,18 @@ print_thread_info (struct ui_out *uiout, int requested_thread)
          ui_out_text (uiout, ")");
        }
       ui_out_text (uiout, "  ");
-      /* That switch put us at the top of the stack (leaf frame).  */
-      switch_to_thread (tp->ptid);
-      print_stack_frame (get_selected_frame (NULL), 
-                        /* For MI output, print frame level.  */
-                        ui_out_is_mi_like_p (uiout),
-                        LOCATION);
+      if (tp->running_)
+       ui_out_text (uiout, "(running)\n");
+      else
+       {
+         /* The switch below puts us at the top of the stack (leaf
+            frame).  */
+         switch_to_thread (tp->ptid);
+         print_stack_frame (get_selected_frame (NULL),
+                            /* For MI output, print frame level.  */
+                            ui_out_is_mi_like_p (uiout),
+                            LOCATION);
+       }
 
       do_cleanups (chain2);
     }
@@ -698,6 +709,9 @@ print_thread_info (struct ui_out *uiout, int requested_thread)
        ui_out_field_int (uiout, "current-thread-id", current_thread);
     }
 
+  if (is_running (inferior_ptid))
+    return;
+
   /*  If case we were not able to find the original frame, print the
       new selected frame.  */
   if (frame_find_by_id (saved_frame_id) == NULL)
@@ -736,7 +750,11 @@ switch_to_thread (ptid_t ptid)
   inferior_ptid = ptid;
   reinit_frame_cache ();
   registers_changed ();
-  stop_pc = read_pc ();
+
+  if (!is_executing (ptid))
+    stop_pc = read_pc ();
+  else
+    stop_pc = ~(CORE_ADDR) 0;
 }
 
 static void
@@ -773,7 +791,12 @@ do_restore_current_thread_cleanup (void *arg)
 {
   struct current_thread_cleanup *old = arg;
   restore_current_thread (old->inferior_ptid);
-  restore_selected_frame (old->selected_frame_id);
+
+  /* A command like 'thread apply all $exec_command&' may change the
+     running state of the originally selected thread, so we have to
+     recheck it here.  */
+  if (!is_running (old->inferior_ptid))
+    restore_selected_frame (old->selected_frame_id);
   xfree (old);
 }
 
@@ -801,8 +824,7 @@ static void
 thread_apply_all_command (char *cmd, int from_tty)
 {
   struct thread_info *tp;
-  struct cleanup *old_chain;
-  struct cleanup *saved_cmd_cleanup_chain;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, 0);
   char *saved_cmd;
   struct frame_id saved_frame_id;
   ptid_t current_ptid;
@@ -812,8 +834,12 @@ thread_apply_all_command (char *cmd, int from_tty)
     error (_("Please specify a command following the thread ID list"));
   
   current_ptid = inferior_ptid;
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
-  old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
+
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
+  make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
 
   /* It is safe to update the thread list now, before
      traversing it for "thread apply all".  MVS */
@@ -822,11 +848,15 @@ thread_apply_all_command (char *cmd, int from_tty)
   /* Save a copy of the command in case it is clobbered by
      execute_command */
   saved_cmd = xstrdup (cmd);
-  saved_cmd_cleanup_chain = make_cleanup (xfree, (void *) saved_cmd);
+  make_cleanup (xfree, saved_cmd);
   for (tp = thread_list; tp; tp = tp->next)
     if (thread_alive (tp))
       {
-       switch_to_thread (tp->ptid);
+       if (non_stop)
+         context_switch_to (tp->ptid);
+       else
+         switch_to_thread (tp->ptid);
+
        printf_filtered (_("\nThread %d (%s):\n"),
                         tp->num, target_tid_to_str (inferior_ptid));
        execute_command (cmd, from_tty);
@@ -836,12 +866,10 @@ thread_apply_all_command (char *cmd, int from_tty)
   if (!ptid_equal (current_ptid, inferior_ptid))
     thread_has_changed = 1;
 
-  do_cleanups (saved_cmd_cleanup_chain);
   do_cleanups (old_chain);
   /* Print stack frame only if we changed thread.  */
-  if (thread_has_changed)
+  if (thread_has_changed && !is_running (inferior_ptid))
     print_stack_frame (get_current_frame (), 1, SRC_LINE);
-
 }
 
 static void
@@ -865,7 +893,11 @@ thread_apply_command (char *tidlist, int from_tty)
     error (_("Please specify a command following the thread ID list"));
 
   current_ptid = inferior_ptid;
-  saved_frame_id = get_frame_id (get_selected_frame (NULL));
+
+  if (!is_running (inferior_ptid))
+    saved_frame_id = get_frame_id (get_selected_frame (NULL));
+  else
+    saved_frame_id = null_frame_id;
   old_chain = make_cleanup_restore_current_thread (inferior_ptid, saved_frame_id);
 
   /* Save a copy of the command in case it is clobbered by
@@ -909,7 +941,10 @@ thread_apply_command (char *tidlist, int from_tty)
            warning (_("Thread %d has terminated."), start);
          else
            {
-             switch_to_thread (tp->ptid);
+             if (non_stop)
+               context_switch_to (tp->ptid);
+             else
+               switch_to_thread (tp->ptid);
              printf_filtered (_("\nThread %d (%s):\n"), tp->num,
                               target_tid_to_str (inferior_ptid));
              execute_command (cmd, from_tty);
@@ -977,7 +1012,10 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr)
   if (!thread_alive (tp))
     error (_("Thread ID %d has terminated."), num);
 
-  switch_to_thread (tp->ptid);
+  if (non_stop)
+    context_switch_to (tp->ptid);
+  else
+    switch_to_thread (tp->ptid);
 
   ui_out_text (uiout, "[Switching to thread ");
   ui_out_field_int (uiout, "new-thread-id", pid_to_thread_id (inferior_ptid));
@@ -985,7 +1023,11 @@ do_captured_thread_select (struct ui_out *uiout, void *tidstr)
   ui_out_text (uiout, target_tid_to_str (inferior_ptid));
   ui_out_text (uiout, ")]");
 
-  print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+  if (!tp->running_)
+    print_stack_frame (get_selected_frame (NULL), 1, SRC_AND_LOC);
+  else
+    ui_out_text (uiout, "(running)\n");
+
   return GDB_RC_OK;
 }
 
@@ -1005,14 +1047,17 @@ void
 _initialize_thread (void)
 {
   static struct cmd_list_element *thread_apply_list = NULL;
+  struct cmd_list_element *c;
 
-  add_info ("threads", info_threads_command,
-           _("IDs of currently known threads."));
+  c = add_info ("threads", info_threads_command,
+               _("IDs of currently known threads."));
+  set_cmd_async_ok (c);
 
-  add_prefix_cmd ("thread", class_run, thread_command, _("\
+  c = add_prefix_cmd ("thread", class_run, thread_command, _("\
 Use this command to switch between threads.\n\
 The new thread ID must be currently known."),
-                 &thread_cmd_list, "thread ", 1, &cmdlist);
+                     &thread_cmd_list, "thread ", 1, &cmdlist);
+  set_cmd_async_ok (c);
 
   add_prefix_cmd ("apply", class_run, thread_apply_command,
                  _("Apply a command to a list of threads."),