Wed Jan 13 14:59:02 1999 Michael Snyder <msnyder@cleaver.cygnus.com>

* infrun.c (set/show scheduler-locking) New command.  Set a
          mode bit that will control how GDB attempts to control thread
          scheduling for step, continue, etc.  (resume): make use of
          the schedule-locking mode.
        * target.h (struct target_ops): new field to_has_thread_control.
        * sol-thread.c: initialize target_ops to_has_thread_control.
        * procfs.c: ditto.
        * target.c: ditto.
        * m3-nat.c: ditto.
        * remote.c: ditto.
        * hpux-thread.c: ditto.
This commit is contained in:
Michael Snyder 1999-01-13 23:53:30 +00:00
parent ea377ea4c0
commit 3ab2abae9a
8 changed files with 73 additions and 6 deletions

View File

@ -650,6 +650,7 @@ struct target_ops hpux_thread_ops = {
1, /* to_has_stack */
1, /* to_has_registers */
1, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */

View File

@ -598,6 +598,28 @@ resume_cleanups (arg)
normal_stop ();
}
static char schedlock_off[] = "off";
static char schedlock_on[] = "on";
static char schedlock_step[] = "step";
static char *scheduler_mode = schedlock_off;
static char *scheduler_enums[] = {schedlock_off, schedlock_on, schedlock_step};
static void
set_schedlock_func (args, from_tty, c)
char *args;
int from_tty;
struct cmd_list_element *c;
{
if (c->type == set_cmd)
if (!target_can_lock_scheduler)
{
scheduler_mode = schedlock_off;
error ("Target '%s' cannot support this command.",
target_shortname);
}
}
/* Resume the inferior, but allow a QUIT. This is useful if the user
wants to interrupt some lengthy single-stepping operation
(for child processes, the SIGINT goes to the inferior, and so
@ -714,10 +736,16 @@ resume (step, sig)
}
else
#endif /* HPUXHPPA */
{
/* Vanilla resume. */
if ((scheduler_mode == schedlock_on) ||
(scheduler_mode == schedlock_step && step != 0))
target_resume (inferior_pid, step, sig);
else
target_resume (-1, step, sig);
}
}
discard_cleanups (old_cleanups);
}
@ -3688,4 +3716,18 @@ By default, the debugger will follow the parent process.",
add_show_from_set (c, &showlist);
set_follow_fork_mode_command ("parent", 0, NULL);
c = add_set_enum_cmd ("scheduler-locking", class_run,
scheduler_enums, /* array of string names */
(char *) &scheduler_mode, /* current mode */
"Set mode for locking scheduler during execution.\n\
off == no locking (threads may preempt at any time)\n\
on == full locking (no thread except the current thread may run)\n\
step == scheduler locked during every single-step operation.\n\
In this mode, no other thread may run during a step command.\n\
Other threads may run while stepping over a function call ('next').",
&setlist);
c->function.sfunc = set_schedlock_func; /* traps on target vector */
add_show_from_set (c, &showlist);
}

View File

@ -4595,6 +4595,7 @@ struct target_ops m3_ops = {
1, /* to_has_stack */
1, /* to_has_registers */
1, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */

View File

@ -5816,6 +5816,7 @@ struct target_ops procfs_ops = {
1, /* to_has_stack */
1, /* to_has_registers */
1, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */

View File

@ -3185,6 +3185,7 @@ Specify the serial device it is connected to (e.g. /dev/ttya).";
remote_ops.to_has_stack = 1;
remote_ops.to_has_registers = 1;
remote_ops.to_has_execution = 1;
remote_ops.to_has_thread_control = tc_schedlock; /* can lock scheduler */
remote_ops.to_magic = OPS_MAGIC;
}

View File

@ -1569,6 +1569,7 @@ struct target_ops sol_thread_ops = {
1, /* to_has_stack */
1, /* to_has_registers */
1, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */
@ -1638,6 +1639,7 @@ struct target_ops sol_core_ops = {
1, /* to_has_stack */
1, /* to_has_registers */
0, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* sections */
0, /* sections_end */
OPS_MAGIC /* to_magic */

View File

@ -248,6 +248,7 @@ struct target_ops dummy_target = {
0, /* to_has_stack */
0, /* to_has_registers */
0, /* to_has_execution */
tc_none, /* to_has_thread_control */
0, /* to_sections */
0, /* to_sections_end */
OPS_MAGIC, /* to_magic */
@ -593,6 +594,7 @@ update_current_target ()
INHERIT (to_has_stack, t);
INHERIT (to_has_registers, t);
INHERIT (to_has_execution, t);
INHERIT (to_has_thread_control, t);
INHERIT (to_sections, t);
INHERIT (to_sections_end, t);
INHERIT (to_magic, t);

View File

@ -51,6 +51,12 @@ enum strata {
process_stratum /* Executing processes */
};
enum thread_control_capabilities {
tc_none = 0, /* Default: can't control thread execution. */
tc_schedlock = 1, /* Can lock the thread scheduler. */
tc_switch = 2, /* Can switch the running thread on demand. */
};
/* Stuff for target_wait. */
/* Generally, what has the program done? */
@ -361,6 +367,7 @@ struct target_ops
int to_has_stack;
int to_has_registers;
int to_has_execution;
int to_has_thread_control; /* control thread execution */
struct section_table
*to_sections;
struct section_table
@ -934,6 +941,16 @@ print_section_info PARAMS ((struct target_ops *, bfd *));
#define target_has_execution \
(current_target.to_has_execution)
/* Can the target support the debugger control of thread execution?
a) Can it lock the thread scheduler?
b) Can it switch the currently running thread? */
#define target_can_lock_scheduler \
(current_target.to_has_thread_control & tc_schedlock)
#define target_can_switch_threads \
(current_target.to_has_thread_control & tc_switch)
extern void target_link PARAMS ((char *, CORE_ADDR *));
/* Converts a process id to a string. Usually, the string just contains