Index: inferior.h
===================================================================
RCS file: /cvs/src/src/gdb/inferior.h,v
retrieving revision 1.161
diff -c -p -r1.161 inferior.h
*** inferior.h	21 Jul 2011 23:46:08 -0000	1.161
--- inferior.h	8 Aug 2011 11:23:59 -0000
*************** extern int stop_on_solib_events;
*** 204,209 ****
--- 204,212 ----
  
  extern void start_remote (int from_tty);
  
+ extern struct value *prev_thread_id_make_value (struct gdbarch *,
+                                                 struct internalvar *);
+ 
  extern void normal_stop (void);
  
  extern int signal_stop_state (int);
Index: infrun.c
===================================================================
RCS file: /cvs/src/src/gdb/infrun.c,v
retrieving revision 1.498
diff -c -p -r1.498 infrun.c
*** infrun.c	4 Aug 2011 19:10:12 -0000	1.498
--- infrun.c	8 Aug 2011 11:24:02 -0000
*************** int sync_execution = 0;
*** 125,130 ****
--- 125,136 ----
     when the inferior stopped in a different thread than it had been
     running in.  */
  
+ static ptid_t current_inferior_ptid;
+ 
+ /* Values move from interior_ptid to current_inferior_ptid to
+  * previous_inferior_ptid.  The previous value is exposed to the
+  * user through the $_prev_thread convenience variable.
+  */
  static ptid_t previous_inferior_ptid;
  
  /* Default behavior is to detach newly forked processes (legacy).  */
*************** proceed (CORE_ADDR addr, enum target_sig
*** 2069,2075 ****
      }
  
    /* We'll update this if & when we switch to a new thread.  */
!   previous_inferior_ptid = inferior_ptid;
  
    regcache = get_current_regcache ();
    gdbarch = get_regcache_arch (regcache);
--- 2075,2081 ----
      }
  
    /* We'll update this if & when we switch to a new thread.  */
!   current_inferior_ptid = inferior_ptid;
  
    regcache = get_current_regcache ();
    gdbarch = get_regcache_arch (regcache);
*************** init_wait_for_inferior (void)
*** 2289,2295 ****
  
    target_last_wait_ptid = minus_one_ptid;
  
!   previous_inferior_ptid = inferior_ptid;
    init_infwait_state ();
  
    /* Discard any skipped inlined frames.  */
--- 2295,2301 ----
  
    target_last_wait_ptid = minus_one_ptid;
  
!   current_inferior_ptid = inferior_ptid;
    init_infwait_state ();
  
    /* Discard any skipped inlined frames.  */
*************** handle_inferior_event (struct execution_
*** 3719,3725 ****
  	  switch_to_thread (deferred_step_ptid);
  	  deferred_step_ptid = null_ptid;
  	  /* Suppress spurious "Switching to ..." message.  */
! 	  previous_inferior_ptid = inferior_ptid;
  
  	  resume (1, TARGET_SIGNAL_0);
  	  prepare_to_wait (ecs);
--- 3725,3731 ----
  	  switch_to_thread (deferred_step_ptid);
  	  deferred_step_ptid = null_ptid;
  	  /* Suppress spurious "Switching to ..." message.  */
! 	  current_inferior_ptid = inferior_ptid;
  
  	  resume (1, TARGET_SIGNAL_0);
  	  prepare_to_wait (ecs);
*************** print_no_history_reason (void)
*** 5730,5735 ****
--- 5736,5753 ----
    ui_out_text (current_uiout, "\nNo more reverse-execution history.\n");
  }
  
+ /* Return the previous thread's id.  Return a value of 0 if
+    no previous thread was selected, or it doesn't exist.  */
+ 
+ struct value *
+ prev_thread_id_make_value (struct gdbarch *gdbarch, struct internalvar *var)
+ {
+   struct thread_info *tp = find_thread_ptid (previous_inferior_ptid);
+ 
+   return value_from_longest (builtin_type (gdbarch)->builtin_int,
+                  (tp ? tp->num : 0));
+ }
+ 
  /* Here to return control to GDB when the inferior stops for real.
     Print appropriate messages, remove breakpoints, give terminal our modes.
  
*************** normal_stop (void)
*** 5770,5785 ****
       Note that SIGNALLED here means "exited with a signal", not
       "received a signal".  */
    if (!non_stop
!       && !ptid_equal (previous_inferior_ptid, inferior_ptid)
        && target_has_execution
        && last.kind != TARGET_WAITKIND_SIGNALLED
        && last.kind != TARGET_WAITKIND_EXITED)
      {
        target_terminal_ours_for_output ();
        printf_filtered (_("[Switching to %s]\n"),
! 		       target_pid_to_str (inferior_ptid));
        annotate_thread_changed ();
!       previous_inferior_ptid = inferior_ptid;
      }
  
    if (!breakpoints_always_inserted_mode () && target_has_execution)
--- 5788,5804 ----
       Note that SIGNALLED here means "exited with a signal", not
       "received a signal".  */
    if (!non_stop
!       && !ptid_equal (current_inferior_ptid, inferior_ptid)
        && target_has_execution
        && last.kind != TARGET_WAITKIND_SIGNALLED
        && last.kind != TARGET_WAITKIND_EXITED)
      {
        target_terminal_ours_for_output ();
        printf_filtered (_("[Switching to %s]\n"),
!                target_pid_to_str (inferior_ptid));
        annotate_thread_changed ();
!       previous_inferior_ptid = current_inferior_ptid;
!       current_inferior_ptid = inferior_ptid;
      }
  
    if (!breakpoints_always_inserted_mode () && target_has_execution)
Index: thread.c
===================================================================
RCS file: /cvs/src/src/gdb/thread.c,v
retrieving revision 1.142
diff -c -p -r1.142 thread.c
*** thread.c	4 Aug 2011 19:10:13 -0000	1.142
--- thread.c	8 Aug 2011 11:24:02 -0000
*************** Show printing of thread events (such as 
*** 1498,1501 ****
--- 1498,1502 ----
           &setprintlist, &showprintlist);
  
    create_internalvar_type_lazy ("_thread", thread_id_make_value);
+   create_internalvar_type_lazy ("_prev_thread", prev_thread_id_make_value);
  }
