This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
[RFC] 05/10 Expose context_switch
- From: Pedro Alves <pedro at codesourcery dot com>
- To: gdb-patches at sourceware dot org
- Date: Tue, 6 May 2008 16:48:48 +0100
- Subject: [RFC] 05/10 Expose context_switch
In non-stop mode, whenever we switch threads, and because each
is handled independently of the others, we need to context-switch
outside of infrun.c (e.g., "thread n" command, thread apply
all, "continue --all").
This patch adds the base support for that.
--
Pedro Alves
2008-05-06 Pedro Alves <pedro@codesourcery.com>
* inferior.h (context_switch_to): Declare.
* infrun.c (ecss): New global.
(wait_for_inferior): Use global ecss.
(async_ecss, async_ecs): Delete.
(fetch_inferior_event): Use global ecss.
(context_switch_to): New.
---
gdb/inferior.h | 2 ++
gdb/infrun.c | 49 +++++++++++++++++++++++++++++--------------------
2 files changed, 31 insertions(+), 20 deletions(-)
Index: src/gdb/inferior.h
===================================================================
--- src.orig/gdb/inferior.h 2008-05-06 03:29:04.000000000 +0100
+++ src/gdb/inferior.h 2008-05-06 03:30:10.000000000 +0100
@@ -132,6 +132,8 @@ extern void clear_proceed_status (void);
extern void proceed (CORE_ADDR, enum target_signal, int);
+extern ptid_t context_switch_to (ptid_t ptid);
+
/* When set, stop the 'step' command if we enter a function which has
no line number information. The normal behavior is that we step
over such function. */
Index: src/gdb/infrun.c
===================================================================
--- src.orig/gdb/infrun.c 2008-05-06 03:24:59.000000000 +0100
+++ src/gdb/infrun.c 2008-05-06 03:27:31.000000000 +0100
@@ -288,6 +288,8 @@ static struct breakpoint *step_resume_br
static ptid_t target_last_wait_ptid;
static struct target_waitstatus target_last_waitstatus;
+struct execution_control_state ecss;
+
/* This is used to remember when a fork, vfork or exec event
was caught by a catchpoint, and thus the event is to be
followed at the next resume of the inferior, and not
@@ -1426,7 +1428,6 @@ void
wait_for_inferior (int treat_exec_as_sigtrap)
{
struct cleanup *old_cleanups;
- struct execution_control_state ecss;
struct execution_control_state *ecs;
if (debug_infrun)
@@ -1437,8 +1438,6 @@ wait_for_inferior (int treat_exec_as_sig
old_cleanups = make_cleanup (delete_step_resume_breakpoint,
&step_resume_breakpoint);
- /* wfi still stays in a loop, so it's OK just to take the address of
- a local to get the ecs pointer. */
ecs = &ecss;
/* Fill in with reasonable starting values. */
@@ -1484,25 +1483,20 @@ wait_for_inferior (int treat_exec_as_sig
event loop whenever a change of state is detected on the file
descriptor corresponding to the target. It can be called more than
once to complete a single execution command. In such cases we need
- to keep the state in a global variable ASYNC_ECSS. If it is the
- last time that this function is called for a single execution
- command, then report to the user that the inferior has stopped, and
- do the necessary cleanups. */
-
-struct execution_control_state async_ecss;
-struct execution_control_state *async_ecs;
+ to keep the state in a global variable ECSS. If it is the last time
+ that this function is called for a single execution command, then
+ report to the user that the inferior has stopped, and do the
+ necessary cleanups. */
void
fetch_inferior_event (void *client_data)
{
- static struct cleanup *old_cleanups;
-
- async_ecs = &async_ecss;
+ struct execution_control_state *ecs = &ecss;
- if (!async_ecs->wait_some_more)
+ if (!ecs->wait_some_more)
{
/* Fill in with reasonable starting values. */
- init_execution_control_state (async_ecs);
+ init_execution_control_state (ecs);
/* We'll update this if & when we switch to a new thread. */
previous_inferior_ptid = inferior_ptid;
@@ -1519,15 +1513,15 @@ fetch_inferior_event (void *client_data)
}
if (deprecated_target_wait_hook)
- async_ecs->ptid =
- deprecated_target_wait_hook (async_ecs->waiton_ptid, async_ecs->wp);
+ ecs->ptid =
+ deprecated_target_wait_hook (ecs->waiton_ptid, ecs->wp);
else
- async_ecs->ptid = target_wait (async_ecs->waiton_ptid, async_ecs->wp);
+ ecs->ptid = target_wait (ecs->waiton_ptid, ecs->wp);
/* Now figure out what to do with the result of the result. */
- handle_inferior_event (async_ecs);
+ handle_inferior_event (ecs);
- if (!async_ecs->wait_some_more)
+ if (!ecs->wait_some_more)
{
delete_step_resume_breakpoint (&step_resume_breakpoint);
@@ -1633,6 +1627,21 @@ context_switch (struct execution_control
switch_to_thread (ecs->ptid);
}
+/* Context switch to thread PTID. */
+ptid_t
+context_switch_to (ptid_t ptid)
+{
+ ptid_t current_ptid = inferior_ptid;
+
+ /* Context switch to the new thread. */
+ if (!ptid_equal (ptid, inferior_ptid))
+ {
+ ecss.ptid = ptid;
+ context_switch (&ecss);
+ }
+ return current_ptid;
+}
+
static void
adjust_pc_after_break (struct execution_control_state *ecs)
{