Ref gdb/11763 - can't stop a running simulator:

o	Provide poll_quit callback to simulators
		so that they can poll for SIGINT on
		clueless OS's.

	o	Add sim_stop to simulators so that clients
		can request a halt (eg gdbtk's STOP button)
		Works for PPC!

	o	Re-arange remote-sim.c so that the
		hard work is moved from gdbsim_resume()
		to gdbsim_wait() (where it should be).
This commit is contained in:
Andrew Cagney
1997-04-18 12:24:52 +00:00
parent 2d3588808f
commit 8517f62b16
20 changed files with 693 additions and 40 deletions

View File

@@ -1,3 +1,25 @@
Fri Apr 18 16:52:41 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.c (init_callbacks): Initialize poll_quit and magic
fields of gdb_callback.
(gdbsim_stop): Add gdbsim_stop to list of supported client
operations.
(gdbsim_wait, gdbsim_resume): Move call to sim_resume into
sim_wait where gdb is in a position to handle a long running
function.
(gdbsim_cntrl_c): New function. Wrap the sim_resume call in a
SIGINT handler.
(gdb_os_poll_quit): New function. Check for a quit pending on the
console.
start-sanitize-gdbtk
Wed Apr 16 12:33:06 1997 Andrew Cagney <cagney@b1.cygnus.com>
* Makefile.in (install-only): Make list of gdbtcl files to install
explicit - was picking up files such as CVS ChangeLog etc.
(install-only): Don't blindly create the directory.
end-sanitize-gdbtk
Thu Apr 17 14:30:04 1997 Per Bothner <bothner@deneb.cygnus.com>
* defs.h (enum language): Add language_java.

View File

@@ -546,11 +546,13 @@ install-only:
$(INSTALL_DATA) $(srcdir)/gdb.1 $(man1dir)/$$transformed_name.1
# start-sanitize-gdbtk
if [ x"$(ENABLE_GDBTK)" != x ] ; then \
echo "Making directory gdbtcl"; \
mkdir $(datadir)/gdbtcl; \
chmod 755 $(datadir)/gdbtcl; \
if [ ! -d $(datadir)/gdbtcl ]; then \
echo "Making directory gdbtcl"; \
mkdir $(datadir)/gdbtcl; \
chmod 755 $(datadir)/gdbtcl; \
fi ; \
cd $(srcdir)/gdbtcl ; \
for i in * ; \
for i in asm.tcl break.xbm breakpoint.tcl command.tcl copyright.tcl expr.tcl file.tcl main.tcl register.tcl source.tcl stop2.gif tclIndex ; \
do \
$(INSTALL_DATA) $$i $(datadir)/gdbtcl/$$i ; \
done ; \

View File

@@ -52,6 +52,8 @@ static int gdb_os_write_stderr PARAMS ((host_callback *, const char *, int));
static void gdb_os_flush_stderr PARAMS ((host_callback *));
static int gdb_os_poll_quit PARAMS ((host_callback *));
/* printf_filtered is depreciated */
static void gdb_os_printf_filtered PARAMS ((host_callback *, const char *, ...));
@@ -92,6 +94,8 @@ static void gdbsim_files_info PARAMS ((struct target_ops *target));
static void gdbsim_mourn_inferior PARAMS ((void));
static void gdbsim_stop PARAMS ((void));
static void simulator_command PARAMS ((char *args, int from_tty));
/* Naming convention:
@@ -155,7 +159,10 @@ init_callbacks ()
gdb_callback.vprintf_filtered = gdb_os_vprintf_filtered;
gdb_callback.evprintf_filtered = gdb_os_evprintf_filtered;
gdb_callback.error = gdb_os_error;
gdb_callback.poll_quit = gdb_os_poll_quit;
gdb_callback.magic = HOST_CALLBACK_MAGIC;
sim_set_callbacks (gdbsim_desc, &gdb_callback);
callbacks_initialized = 1;
}
}
@@ -236,6 +243,26 @@ gdb_os_flush_stderr (p)
gdb_flush (gdb_stderr);
}
/* GDB version of os_poll_quit callback.
Taken from gdb/util.c - should be in a library */
static int
gdb_os_poll_quit (p)
host_callback *p;
{
notice_quit ();
if (quit_flag)
{
quit_flag = 0; /* we've stolen it */
return 1;
}
else if (immediate_quit)
{
return 1;
}
return 0;
}
/* GDB version of printf_filtered callback. */
/* VARARGS */
@@ -564,6 +591,9 @@ gdbsim_detach (args,from_tty)
or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
to the target, or zero for no signal. */
static enum target_signal resume_siggnal;
static int resume_step;
static void
gdbsim_resume (pid, step, siggnal)
int pid, step;
@@ -575,25 +605,55 @@ gdbsim_resume (pid, step, siggnal)
if (sr_get_debug ())
printf_filtered ("gdbsim_resume: step %d, signal %d\n", step, siggnal);
sim_resume (gdbsim_desc, step, target_signal_to_host (siggnal));
resume_siggnal = siggnal;
resume_step = step;
}
/* Notify the simulator of an asynchronous request to stop.
Since some simulators can not stop, help them out.
When stepping, need to also notify the client that it
too should quit */
static void
gdbsim_stop ()
{
if (! sim_stop (gdbsim_desc))
{
error ("gdbsim_stop: simulator failed to stop!\n");
}
}
/* Wait for inferior process to do something. Return pid of child,
or -1 in case of error; store status through argument pointer STATUS,
just as `wait' would. */
just as `wait' would. */
static void (*prev_sigint) ();
static void
gdbsim_cntrl_c (int signo)
{
gdbsim_stop ();
}
static int
gdbsim_wait (pid, status)
int pid;
struct target_waitstatus *status;
{
int sigrc;
enum sim_stop reason;
int sigrc = 0;
enum sim_stop reason = sim_running;
if (sr_get_debug ())
printf_filtered ("gdbsim_wait\n");
prev_sigint = signal (SIGINT, gdbsim_cntrl_c);
sim_resume (gdbsim_desc, resume_step,
target_signal_to_host (resume_siggnal));
signal (SIGINT, prev_sigint);
resume_step = 0;
sim_stop_reason (gdbsim_desc, &reason, &sigrc);
switch (reason)
{
case sim_exited:
@@ -601,10 +661,20 @@ gdbsim_wait (pid, status)
status->value.integer = sigrc;
break;
case sim_stopped:
status->kind = TARGET_WAITKIND_STOPPED;
/* The signal in sigrc is a host signal. That probably
should be fixed. */
status->value.sig = target_signal_from_host (sigrc);
switch (sigrc)
{
case SIGABRT:
quit ();
break;
case SIGINT:
case SIGTRAP:
default:
status->kind = TARGET_WAITKIND_STOPPED;
/* The signal in sigrc is a host signal. That probably
should be fixed. */
status->value.sig = target_signal_from_host (sigrc);
break;
}
break;
case sim_signalled:
status->kind = TARGET_WAITKIND_SIGNALLED;
@@ -745,7 +815,7 @@ struct target_ops gdbsim_ops = {
0, /* to_can_run */
0, /* to_notice_signals */
0, /* to_thread_alive */
0, /* to_stop */
gdbsim_stop, /* to_stop */
process_stratum, /* to_stratum */
NULL, /* to_next */
1, /* to_has_all_memory */

View File

@@ -1,3 +1,17 @@
Fri Apr 18 13:04:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
* remote-sim.h (sim_stop): New interface - asynchronous
notification of a request to stop / suspend the running
simulation.
* remote-sim.h (enum sim_stop): Add sim_running and sim_polling as
states for use internal to simulators.
* callback.h (struct host_callback_strut): Put a magic number at
the end of the struct to allow basic checking.
(struct host_callback_struct ): Add poll_quit - so
that the console etc can be polled at regular intervals.
Thu Apr 17 02:17:12 1997 Doug Evans <dje@canuck.cygnus.com>
* remote-sim.h (struct _bfd): Declare.

View File

@@ -52,6 +52,11 @@ struct host_callback_struct
int (*write_stderr) PARAMS ((host_callback *, const char *, int));
void (*flush_stderr) PARAMS ((host_callback *));
/* When present, call to the client to give it the oportunity to
poll any io devices for a request to quit (indicated by a nonzero
return value). */
int (*poll_quit) PARAMS ((host_callback *));
/* Used when the target has gone away, so we can close open
handles and free memory etc etc. */
int (*shutdown) PARAMS ((host_callback *));
@@ -76,6 +81,12 @@ struct host_callback_struct
int fdmap[MAX_CALLBACK_FDS];
char fdopen[MAX_CALLBACK_FDS];
char alwaysopen[MAX_CALLBACK_FDS];
/* Marker for thse wanting to do sanity checks.
This should remain the last memeber of this struct to help catch
miscompilation errors. */
#define HOST_CALLBACK_MAGIC 4705 /* teds constant */
int magic;
};
extern host_callback default_callback;

View File

@@ -53,8 +53,10 @@ typedef enum {
/* The bfd struct, as an opaque type. */
struct _bfd;
/* Main simulator entry points. */
/* Initialize the simulator. This function is called when the simulator
is selected from the gdb command line.
KIND specifies how the simulator will be used. Currently there are only
@@ -67,6 +69,7 @@ struct _bfd;
SIM_DESC sim_open PARAMS ((SIM_OPEN_KIND kind, char **argv));
/* Terminate usage of the simulator. This may involve freeing target memory
and closing any open files and mmap'd areas. You cannot assume sim_kill
has already been called.
@@ -74,62 +77,90 @@ SIM_DESC sim_open PARAMS ((SIM_OPEN_KIND kind, char **argv));
void sim_close PARAMS ((SIM_DESC sd, int quitting));
/* Load program PROG into the simulator.
If ABFD is non-NULL, the bfd for the file has already been opened.
The result is a return code indicating success. */
SIM_RC sim_load PARAMS ((SIM_DESC sd, char *prog, struct _bfd *abfd, int from_tty));
/* Prepare to run the simulated program.
ARGV and ENV are NULL terminated lists of pointers. */
SIM_RC sim_create_inferior PARAMS ((SIM_DESC sd, char **argv, char **env));
/* Kill the running program.
This may involve closing any open files and deleting any mmap'd areas. */
void sim_kill PARAMS ((SIM_DESC sd));
/* Read LENGTH bytes of the simulated program's memory and store in BUF.
Result is number of bytes read, or zero if error. */
int sim_read PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length));
/* Store LENGTH bytes from BUF in the simulated program's memory.
Result is number of bytes write, or zero if error. */
int sim_write PARAMS ((SIM_DESC sd, SIM_ADDR mem, unsigned char *buf, int length));
/* Fetch register REGNO and store the raw value in BUF. */
void sim_fetch_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf));
/* Store register REGNO from BUF (in raw format). */
void sim_store_register PARAMS ((SIM_DESC sd, int regno, unsigned char *buf));
/* Print whatever statistics the simulator has collected.
VERBOSE is currently unused and must always be zero. */
void sim_info PARAMS ((SIM_DESC sd, int verbose));
/* Fetch why the program stopped.
SIGRC will contain either the argument to exit() or the signal number. */
enum sim_stop { sim_exited, sim_stopped, sim_signalled };
/* Fetch the reason why the program stopped.
SIM_EXITED: The program has terminated. SIGRC indicates the target
dependant exit status.
SIM_STOPPED: Any of a breakpoint (SIGTRAP), a completed step
(SIGTRAP), a sim_stop request (SIGINT), or an internal error
condition (SIGABRT) was encountered.
SIM_SIGNALLED: The simulator encountered target code that requires
the signal SIGRC to be delivered to the simulated program.
SIM_RUNNING, SIM_POLLING: The return of one of these values
indicates a problem internal to the simulator. */
enum sim_stop { sim_running, sim_polling, sim_exited, sim_stopped, sim_signalled };
void sim_stop_reason PARAMS ((SIM_DESC sd, enum sim_stop *reason, int *sigrc));
/* Run (or resume) the program. */
void sim_resume PARAMS ((SIM_DESC sd, int step, int siggnal));
/* Asynchronous request to stop the simulation.
A nonzero return indicates that the simulator is able to handle
the request */
int sim_stop PARAMS ((SIM_DESC sd));
/* Passthru for other commands that the simulator might support.
If SD is NULL, the command is to be interpreted as refering to
the global state, however the simulator defines that. */
void sim_do_command PARAMS ((SIM_DESC sd, char *cmd));
/* Provide simulator with a standard host_callback_struct.
If SD is NULL, the command is to be interpreted as refering to
the global state, however the simulator defines that. */

View File

@@ -1,3 +1,7 @@
Fri Apr 18 13:32:23 1997 Andrew Cagney <cagney@b1.cygnus.com>
* wrapper.c (sim_stop): Stub sim_stop function.
Thu Apr 17 18:33:01 1997 Fred Fish <fnf@cygnus.com>
* arminit.c (ARMul_NewState): Preinitialize the state to

View File

@@ -1,3 +1,19 @@
Fri Apr 18 13:11:36 1997 Andrew Cagney <cagney@b1.cygnus.com>
* run.c (main, cntrl_c): Wrap calls to sim_resume in a SIGINT
handler that calls sim_stop (). Simulators may still be
establishing their own handler.
* sim-events.c (sim_events_poll): Rename from
sim_events_at_large_int. Poll IO.
* sim-io.c (sim_io_poll_quit): New function - pass on a polling
request.
* callback.c (os_poll_quit): New function poll for quit signal
where needed.
(default_callback): Include magic number.
Thu Apr 17 02:25:11 1997 Doug Evans <dje@canuck.cygnus.com>
* aclocal.m4: Check for headers time.h, sys/time.h, sys/resource.h.

View File

@@ -63,12 +63,24 @@ extern int sim_trace PARAMS ((SIM_DESC sd));
extern int getopt ();
static SIM_DESC sd;
static RETSIGTYPE
cntrl_c (int sig)
{
if (! sim_stop (sd))
{
fprintf (stderr, "Quit!\n");
exit (1);
}
}
int
main (ac, av)
int ac;
char **av;
{
RETSIGTYPE (*prev_sigint) ();
bfd *abfd;
asection *s;
int i;
@@ -80,7 +92,6 @@ main (ac, av)
char **prog_args;
enum sim_stop reason;
int sigrc;
SIM_DESC sd;
myname = av[0] + strlen (av[0]);
while (myname > av[0] && myname[-1] != '/')
@@ -207,6 +218,7 @@ main (ac, av)
if (sim_create_inferior (sd, prog_args, NULL) == SIM_RC_FAIL)
exit (1);
prev_sigint = signal (SIGINT, cntrl_c);
if (trace)
{
int done = 0;
@@ -219,6 +231,7 @@ main (ac, av)
{
sim_resume (sd, 0, 0);
}
signal (SIGINT, prev_sigint);
if (verbose)
sim_info (sd, 0);

400
sim/common/sim-events.c Normal file
View File

@@ -0,0 +1,400 @@
/* This file is part of the program psim.
Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _SIM_EVENTS_C_
#define _SIM_EVENTS_C_
#include "sim-main.h"
#include "sim-assert.h"
#include <signal.h>
/* The event queue maintains a single absolute time using two
variables.
TIME_OF_EVENT: this holds the time at which the next event is ment
to occure. If no next event it will hold the time of the last
event.
TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. If an
event is pending, this will be positive. If no future event is
pending this will be negative. This variable is decremented once
for each iteration of a clock cycle.
Initially, the clock is started at time one (0) with TIME_OF_EVENT
== 0 and TIME_FROM_EVENT == 0.
Clearly there is a bug in that this code assumes that the absolute
time counter will never become greater than 2^62.
To avoid the need to use 64bit arithmetic, the event queue always
contains at least one event scheduled every 16 000 ticks. This
limits the time from event counter to values less than
16 000. */
#if !defined (SIM_EVENTS_POLL_RATE)
#define SIM_EVENTS_POLL_RATE 0x4000
#endif
#define _ETRACE sd
#undef ETRACE
#define ETRACE(ARGS) \
do \
{ \
if (WITH_TRACE) \
{ \
if (sd->events.trace) \
{ \
const char *file; \
SIM_FILTER_PATH(file, __FILE__); \
sim_io_printf (sd, "%s:%d: ", file, __LINE__); \
sim_io_printf ARGS; \
} \
} \
} \
while (0)
STATIC_INLINE_SIM_EVENTS\
(void)
sim_events_poll (void *data)
{
/* just re-schedule in 1000 million ticks time */
SIM_DESC sd = data;
sim_events_schedule(sd, SIM_EVENTS_POLL_RATE, sim_events_poll, sd);
sim_io_poll_quit (sd);
}
INLINE_SIM_EVENTS\
(void)
sim_events_init(SIM_DESC sd)
{
sim_events *events = &sd->events;
sim_event *event;
/* drain the interrupt queue */
{
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
sigset_t old_mask;
sigset_t new_mask;
sigfillset(&new_mask);
/*-LOCK-*/ sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
#endif
event = events->held;
while (event != NULL) {
sim_event *dead = event;
event = event->next;
zfree(dead);
}
events->held = NULL;
events->held_end = &events->held;
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-UNLOCK-*/ sigprocmask(SIG_SETMASK, &old_mask, NULL);
#endif
}
/* drain the normal queue */
event = events->queue;
while (event != NULL) {
sim_event *dead = event;
event = event->next;
zfree(dead);
}
events->queue = NULL;
/* wind time back to zero */
events->processing = 0;
events->time_of_event = 0;
events->time_from_event = 0;
/* schedule our initial counter event */
sim_events_schedule(sd, 0, sim_events_poll, sd);
/* from now on, except when the large-int event is being processed
the event queue is non empty */
SIM_ASSERT(events->queue != NULL);
}
INLINE_SIM_EVENTS\
(signed64)
sim_events_time(SIM_DESC sd)
{
sim_events *events = &sd->events;
return events->time_of_event - events->time_from_event;
}
STATIC_INLINE_SIM_EVENTS\
(void)
update_time_from_event(SIM_DESC sd)
{
sim_events *events = &sd->events;
signed64 current_time = sim_events_time(sd);
if (events->queue != NULL) {
events->time_from_event = (events->queue->time_of_event - current_time);
events->time_of_event = events->queue->time_of_event;
}
else {
events->time_of_event = current_time - 1;
events->time_from_event = -1;
}
SIM_ASSERT(current_time == sim_events_time (sd));
SIM_ASSERT((events->time_from_event >= 0) == (events->queue != NULL));
}
STATIC_INLINE_SIM_EVENTS\
(void)
insert_sim_event(SIM_DESC sd,
sim_event *new_event,
signed64 delta)
{
sim_events *events = &sd->events;
sim_event *curr;
sim_event **prev;
signed64 time_of_event;
if (delta < 0)
engine_error (sd, "what is past is past!\n");
/* compute when the event should occure */
time_of_event = sim_events_time(sd) + delta;
/* find the queue insertion point - things are time ordered */
prev = &events->queue;
curr = events->queue;
while (curr != NULL && time_of_event >= curr->time_of_event) {
SIM_ASSERT(curr->next == NULL
|| curr->time_of_event <= curr->next->time_of_event);
prev = &curr->next;
curr = curr->next;
}
SIM_ASSERT(curr == NULL || time_of_event < curr->time_of_event);
/* insert it */
new_event->next = curr;
*prev = new_event;
new_event->time_of_event = time_of_event;
/* adjust the time until the first event */
update_time_from_event(sd);
}
INLINE_SIM_EVENTS\
(sim_event *)
sim_events_schedule(SIM_DESC sd,
signed64 delta_time,
sim_event_handler *handler,
void *data)
{
sim_event *new_event = ZALLOC(sim_event);
new_event->data = data;
new_event->handler = handler;
insert_sim_event(sd, new_event, delta_time);
ETRACE((_ETRACE,
"event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
(long)sim_events_time(sd),
(long)new_event,
(long)new_event->time_of_event,
(long)new_event->handler,
(long)new_event->data));
return new_event;
}
INLINE_SIM_EVENTS\
(sim_event *)
sim_events_schedule_after_signal(SIM_DESC sd,
signed64 delta_time,
sim_event_handler *handler,
void *data)
{
sim_events *events = &sd->events;
sim_event *new_event = ZALLOC(sim_event);
new_event->data = data;
new_event->handler = handler;
new_event->time_of_event = delta_time; /* work it out later */
new_event->next = NULL;
{
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
sigset_t old_mask;
sigset_t new_mask;
sigfillset(&new_mask);
/*-LOCK-*/ sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
#endif
if (events->held == NULL) {
events->held = new_event;
}
else {
*events->held_end = new_event;
}
events->held_end = &new_event->next;
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-UNLOCK-*/ sigprocmask(SIG_SETMASK, &old_mask, NULL);
#endif
}
ETRACE((_ETRACE,
"event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
(long)sim_events_time(sd),
(long)new_event,
(long)new_event->time_of_event,
(long)new_event->handler,
(long)new_event->data));
return new_event;
}
INLINE_SIM_EVENTS\
(void)
sim_events_deschedule(SIM_DESC sd,
sim_event *event_to_remove)
{
sim_events *events = &sd->events;
sim_event *to_remove = (sim_event*)event_to_remove;
SIM_ASSERT((events->time_from_event >= 0) == (events->queue != NULL));
if (event_to_remove != NULL) {
sim_event *current;
sim_event **ptr_to_current;
for (ptr_to_current = &events->queue, current = *ptr_to_current;
current != NULL && current != to_remove;
ptr_to_current = &current->next, current = *ptr_to_current);
if (current == to_remove) {
*ptr_to_current = current->next;
ETRACE((_ETRACE,
"event descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
(long)sim_events_time(sd),
(long)event_to_remove,
(long)current->time_of_event,
(long)current->handler,
(long)current->data));
zfree(current);
update_time_from_event(sd);
}
else {
ETRACE((_ETRACE,
"event descheduled at %ld - tag 0x%lx - not found\n",
(long)sim_events_time(sd),
(long)event_to_remove));
}
}
SIM_ASSERT((events->time_from_event >= 0) == (events->queue != NULL));
}
INLINE_SIM_EVENTS\
(int)
sim_events_tick(SIM_DESC sd)
{
sim_events *events = &sd->events;
/* we should only be here when the previous tick has been fully
processed */
SIM_ASSERT(!events->processing && events->queue != NULL);
/* Advance the time but *only* if there is nothing to process */
if (events->time_from_event == 0)
return 1;
else if (events->held != NULL)
return 1;
else {
events->time_from_event -= 1;
return 0;
}
}
INLINE_SIM_EVENTS\
(void)
sim_events_process(SIM_DESC sd)
{
sim_events *events = &sd->events;
signed64 event_time = sim_events_time(sd);
/* something to do */
SIM_ASSERT(events->time_from_event == 0 || events->held != NULL);
SIM_ASSERT(events->queue != NULL);
/* move any events that were queued by any signal handlers onto the
real event queue. */
if (events->held != NULL) {
sim_event *held_events;
sim_event *curr_event;
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-LOCK-*/
sigset_t old_mask;
sigset_t new_mask;
sigfillset(&new_mask);
sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
#endif
held_events = events->held;
events->held = NULL;
events->held_end = &events->held;
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-UNLOCK-*/
sigprocmask(SIG_SETMASK, &old_mask, NULL);
#endif
do {
curr_event = held_events;
held_events = curr_event->next;
insert_sim_event(sd, curr_event, curr_event->time_of_event);
} while (held_events != NULL);
}
/* consume all events for this or earlier times. Be careful to
allow a new event to appear under our feet */
events->processing = 1;
while (events->queue->time_of_event <= event_time) {
sim_event *to_do = events->queue;
sim_event_handler *handler = to_do->handler;
void *data = to_do->data;
events->queue = to_do->next;
ETRACE((_ETRACE,
"event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx\n",
(long)event_time,
(long)to_do,
(long)handler,
(long)data));
zfree (to_do);
handler (data);
}
events->processing = 0;
/* re-caculate time for new events - advance the time */
update_time_from_event(sd);
SIM_ASSERT(events->time_from_event > 0 && events->queue != NULL);
events->time_from_event -= 1;
}
#endif

View File

@@ -1,3 +1,7 @@
Fri Apr 18 13:39:01 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_stop): New function.
Thu Apr 17 02:42:00 1997 Doug Evans <dje@canuck.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-load.o.

View File

@@ -616,6 +616,15 @@ sim_ctrl_c()
}
int
sim_stop (sd)
SIM_DESC sd;
{
stop_simulator = 1;
return 1;
}
/* Run (or resume) the program. */
void
sim_resume (sd, step, siggnal)

View File

@@ -1,3 +1,8 @@
Fri Apr 18 14:30:09 1997 Andrew Cagney <cagney@b1.cygnus.com>
* compile.c (sim_resume): Use poll_quit callback.
(sim_stop): New function.
Thu Apr 17 03:06:39 1997 Doug Evans <dje@canuck.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-load.o.

View File

@@ -1,3 +1,7 @@
Fri Apr 18 14:04:04 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_stop): Add stub function.
Thu Apr 17 03:26:59 1997 Doug Evans <dje@canuck.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-load.o.

View File

@@ -1,3 +1,26 @@
Fri Apr 18 17:03:09 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim_calls.c (sim_stop_reason): Simplify. Was running implies
stopped/SIGINT. Exit implies a status code.
* psim.c (cntrl_c_simulation): From main.c. Event function that
halts the simulator.
(psim_stop): New. Asynchronously schedule a stop simulator event.
(psim_run_until_stop): Delete. Made redundant by psim_stop.
* main.c (cntrl_c): Update.
(cntrl_c_simulation): Moved to psim.c.
* sim_calls.c (sim_stop): New function. Use psim_stop which
schedules a stop event.
(sim_resume): Drop SIGINT handler, now in gdb/main.c.
(sim_resume): Use psim_run as stop variable no longer needed.
Fri Apr 18 17:03:08 1997 Andrew Cagney <cagney@b1.cygnus.com>
* psim.c (psim_options): Handle -E option correctly.
(psim_usage): Document.
Thu Apr 17 03:28:03 1997 Doug Evans <dje@canuck.cygnus.com>
* psim.c (psim_options): Ignore -E option (sets endianness).

View File

@@ -23,9 +23,12 @@
#include <stdio.h>
#include <fcntl.h>
#include <signal.h>
#include "psim.h"
#include "options.h"
#include "device.h" /* FIXME: psim should provide the interface */
#include "events.h" /* FIXME: psim should provide the interface */
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -149,6 +152,7 @@ sim_io_read_stdin(char *buf,
return sim_io_eof;
break;
case DONT_USE_STDIO:
#if defined(O_NDELAY) && defined(F_GETFL) && defined(F_SETFL)
{
/* check for input */
int flags;
@@ -189,6 +193,7 @@ sim_io_read_stdin(char *buf,
return result;
}
break;
#endif
default:
error("sim_io_read_stdin: invalid switch\n");
break;
@@ -228,6 +233,15 @@ zfree(void *chunk)
free(chunk);
}
/* When a CNTRL-C occures, queue an event to shut down the simulation */
static RETSIGTYPE
cntrl_c(int sig)
{
psim_stop (simulation);
}
int
main(int argc, char **argv)
{
@@ -264,7 +278,12 @@ main(int argc, char **argv)
psim_init(simulation);
psim_stack(simulation, argv, environ);
psim_run(simulation);
{
RETSIGTYPE (*prev) ();
prev = signal(SIGINT, cntrl_c);
psim_run(simulation);
signal(SIGINT, prev);
}
/* any final clean up */
if (ppc_trace[trace_print_info])

View File

@@ -1,3 +1,8 @@
Fri Apr 18 14:14:49 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_stop): New function.
(sim_resume): Use poll_quit for polling.
Thu Apr 17 03:32:04 1997 Doug Evans <dje@canuck.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-load.o.

View File

@@ -883,6 +883,14 @@ gotcall (from, to)
#define MMASKB ((saved_state.asregs.msize -1) & ~0)
int
sim_stop (sd)
SIM_DESC sd;
{
saved_state.asregs.exception = SIGINT;
return 1;
}
void
sim_resume (sd, step, siggnal)
SIM_DESC sd;
@@ -896,9 +904,7 @@ sim_resume (sd, step, siggnal)
register int prevlock;
register int thislock;
register unsigned int doprofile;
#if defined(__GO32__) || defined(WIN32)
register int pollcount = 0;
#endif
register int little_endian = little_endian_p;
int tick_start = get_now ();
@@ -959,32 +965,16 @@ sim_resume (sd, step, siggnal)
pc += 2;
#ifdef __GO32__
pollcount++;
if (pollcount > 1000)
{
pollcount = 0;
if (kbhit()) {
int k = getkey();
if (k == 1)
saved_state.asregs.exception = SIGINT;
}
}
#endif
/* FIXME: Testing for INSIDE_SIMULATOR is wrong.
Only one copy of interp.o is built. */
#if defined (WIN32) && !defined(INSIDE_SIMULATOR)
pollcount++;
if (pollcount > 1000)
{
pollcount = 0;
if (win32pollquit())
if ((*callback->poll_quit) != NULL
&& (*callback->poll_quit) (sd))
{
control_c();
}
sim_stop (sd);
}
}
#endif
#ifndef ACE_FAST
prevlock = thislock;

View File

@@ -1,3 +1,7 @@
Fri Apr 18 14:17:12 1997 Andrew Cagney <cagney@b1.cygnus.com>
* interp.c (sim_stop): Stub function.
Thu Apr 17 03:53:18 1997 Doug Evans <dje@canuck.cygnus.com>
* Makefile.in (SIM_OBJS): Add sim-load.o.

View File

@@ -568,6 +568,13 @@ time_t start_time;
static void do_interrupt PARAMS ((enum interrupt_type));
int
sim_stop (sd)
SIM_DESC sd;
{
return 0;
}
void
sim_resume (sd, step, siggnal)
SIM_DESC sd;