From fdd64f952debd1000ed87f077f0fea0ea1fb63dd Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Wed, 3 Sep 1997 07:26:11 +0000 Subject: [PATCH] Add support for suspending/resumeing the simulator in sim-modules. Use in sim-events. --- sim/common/ChangeLog | 22 +++++++++ sim/common/sim-base.h | 6 +++ sim/common/sim-events.c | 51 ++++++++++++++++++-- sim/common/sim-events.h | 17 +------ sim/common/sim-module.c | 104 ++++++++++++++++++++++++++++++++++++++-- sim/common/sim-utils.h | 4 +- 6 files changed, 180 insertions(+), 24 deletions(-) diff --git a/sim/common/ChangeLog b/sim/common/ChangeLog index 0e566f4558..70175363bf 100644 --- a/sim/common/ChangeLog +++ b/sim/common/ChangeLog @@ -1,3 +1,25 @@ +Wed Sep 3 10:08:21 1997 Andrew Cagney + + * sim-resume.c (sim_resume): Suspend/resume the simulator. + + * sim-events.c (sim_watch_valid): Compute total elapsed time from + both resumed and previous elapsed time. + (sim_events_init): Set initial_wallclock and current_wallclock to + zero. + (sim_events_install): Install sim_events_suspend and + sim_events_resume. + (sim_events_watch_clock): Allow for suspended simulator when + computing the time of the clock event. + + * sim-events.h (struct _sim_event): Add resume_wallclock, rename + initial_wallclock to elapsed_wallclock, set both to zero. + (sim_events_init, sim_events_uninstall): Delete prototypes. + + * sim-module.h (MODULE_SUSPEND_FN, MODULE_RESUME_FN): Define types. + + * sim-module.c(sim_module_resume, sim_module_suspend): New + functions. + Wed Sep 3 10:08:21 1997 Andrew Cagney * sim-core.c (sim_core_map_attach): Clarify memory overlap error diff --git a/sim/common/sim-base.h b/sim/common/sim-base.h index 12e1a250e4..ef5f1ce941 100644 --- a/sim/common/sim-base.h +++ b/sim/common/sim-base.h @@ -128,6 +128,12 @@ typedef struct { /* List of installed module `uninstall' handlers. */ MODULE_UNINSTALL_LIST *uninstall_list; #define STATE_UNINSTALL_LIST(sd) ((sd)->base.uninstall_list) + /* List of installed module `resume' handlers. */ + MODULE_RESUME_LIST *resume_list; +#define STATE_RESUME_LIST(sd) ((sd)->base.resume_list) + /* List of installed module `suspend' handlers. */ + MODULE_SUSPEND_LIST *suspend_list; +#define STATE_SUSPEND_LIST(sd) ((sd)->base.suspend_list) /* ??? This might be more appropriate in sim_cpu. */ /* Machine tables for this cpu. See sim-model.h. */ diff --git a/sim/common/sim-events.c b/sim/common/sim-events.c index 653cd61d09..713966226f 100644 --- a/sim/common/sim-events.c +++ b/sim/common/sim-events.c @@ -189,6 +189,11 @@ sim_events_poll (SIM_DESC sd, This is called via sim_module_install to install the "events" subsystem into the simulator. */ +STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN) sim_events_uninstall; +STATIC_SIM_EVENTS (MODULE_INIT_FN) sim_events_init; +STATIC_SIM_EVENTS (MODULE_RESUME_FN) sim_events_resume; +STATIC_SIM_EVENTS (MODULE_SUSPEND_FN) sim_events_suspend; + EXTERN_SIM_EVENTS\ (SIM_RC) sim_events_install (SIM_DESC sd) @@ -196,16 +201,46 @@ sim_events_install (SIM_DESC sd) SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); sim_module_add_uninstall_fn (sd, sim_events_uninstall); sim_module_add_init_fn (sd, sim_events_init); + sim_module_add_resume_fn (sd, sim_events_resume); + sim_module_add_suspend_fn (sd, sim_events_suspend); + return SIM_RC_OK; +} + + +/* Suspend/resume the event queue manager when the simulator is not + running */ + +STATIC_SIM_EVENTS\ +(SIM_RC) +sim_events_resume (SIM_DESC sd) +{ + sim_events *events = STATE_EVENTS (sd); + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + SIM_ASSERT (events->resume_wallclock == 0); + events->resume_wallclock = sim_elapsed_time_get (); + return SIM_RC_OK; +} + +STATIC_SIM_EVENTS\ +(SIM_RC) +sim_events_suspend (SIM_DESC sd) +{ + sim_events *events = STATE_EVENTS (sd); + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + SIM_ASSERT (events->resume_wallclock != 0); + events->elapsed_wallclock += sim_elapsed_time_since (events->resume_wallclock); + events->resume_wallclock = 0; return SIM_RC_OK; } /* Uninstall the "events" subsystem from the simulator. */ -EXTERN_SIM_EVENTS\ +STATIC_SIM_EVENTS\ (void) sim_events_uninstall (SIM_DESC sd) { + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* FIXME: free buffers, etc. */ } @@ -285,7 +320,8 @@ sim_events_init (SIM_DESC sd) events->nr_ticks_to_process = 1; /* start by doing queue */ events->time_of_event = 0; events->time_from_event = 0; - events->initial_wallclock = sim_elapsed_time_get (); + events->elapsed_wallclock = 0; + events->resume_wallclock = 0; /* schedule our initial counter event */ sim_events_schedule (sd, 0, sim_events_poll, sd); @@ -453,7 +489,12 @@ sim_events_watch_clock (SIM_DESC sd, new_event->data = data; new_event->handler = handler; /* data */ - new_event->wallclock = (sim_elapsed_time_since (events->initial_wallclock) + delta_ms_time); + if (events->resume_wallclock == 0) + new_event->wallclock = (events->elapsed_wallclock + delta_ms_time); + else + new_event->wallclock = (events->elapsed_wallclock + + sim_elapsed_time_since (events->resume_wallclock) + + delta_ms_time); /* insert */ new_event->next = events->watchpoints; events->watchpoints = new_event; @@ -824,7 +865,9 @@ sim_watch_valid (SIM_DESC sd, case watch_clock: /* wallclock */ { - unsigned long elapsed_time = sim_elapsed_time_since (STATE_EVENTS (sd)->initial_wallclock); + unsigned long elapsed_time = + (sim_elapsed_time_since (STATE_EVENTS (sd)->resume_wallclock) + + STATE_EVENTS (sd)->elapsed_wallclock); return (elapsed_time >= to_do->wallclock); } diff --git a/sim/common/sim-events.h b/sim/common/sim-events.h index dd69f0a05a..6dd1a2f4f9 100644 --- a/sim/common/sim-events.h +++ b/sim/common/sim-events.h @@ -89,7 +89,8 @@ struct _sim_events { sim_event *held; volatile int nr_held; /* timekeeping */ - SIM_ELAPSED_TIME initial_wallclock; + unsigned long elapsed_wallclock; + SIM_ELAPSED_TIME resume_wallclock; signed64 time_of_event; int time_from_event; int trace; @@ -103,20 +104,6 @@ EXTERN_SIM_EVENTS\ (SIM_RC) sim_events_install (SIM_DESC sd); -/* Uninstall the "events" subsystem. */ - -EXTERN_SIM_EVENTS\ -(void) -sim_events_uninstall (SIM_DESC sd); - - - -/* Initialization */ - -EXTERN_SIM_EVENTS\ -(SIM_RC) sim_events_init (SIM_DESC sd); - - /* Set Tracing Level */ EXTERN_SIM_EVENTS\ diff --git a/sim/common/sim-module.c b/sim/common/sim-module.c index b68a4f3edc..9292c37027 100644 --- a/sim/common/sim-module.c +++ b/sim/common/sim-module.c @@ -21,13 +21,27 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "sim-main.h" #include "sim-io.h" #include "sim-options.h" +#include "sim-assert.h" + +#include "libiberty.h" /* List of all modules. */ static MODULE_INSTALL_FN * const modules[] = { standard_install, +#if WITH_ENGINE + sim_engine_install, +#endif +#if WITH_TRACE trace_install, +#endif +#if WITH_PROFILE profile_install, +#endif sim_core_install, + sim_events_install, +#if WITH_WATCHPOINTS + sim_watchpoint_install, +#endif #if WITH_SCACHE scache_install, #endif @@ -48,6 +62,7 @@ static MODULE_INSTALL_FN * const modules[] = { SIM_RC sim_pre_argv_init (SIM_DESC sd, const char *myname) { + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); STATE_MY_NAME (sd) = myname + strlen (myname); while (STATE_MY_NAME (sd) > myname && STATE_MY_NAME (sd)[-1] != '/') --STATE_MY_NAME (sd); @@ -65,6 +80,7 @@ SIM_RC sim_post_argv_init (SIM_DESC sd) { int i; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); if (sim_module_init (sd) != SIM_RC_OK) return SIM_RC_FAIL; @@ -82,6 +98,7 @@ SIM_RC sim_module_install (SIM_DESC sd) { MODULE_INSTALL_FN * const *modp; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); for (modp = modules; *modp != NULL; ++modp) { @@ -98,6 +115,7 @@ SIM_RC sim_module_init (SIM_DESC sd) { MODULE_INIT_LIST *modp; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); for (modp = STATE_INIT_LIST (sd); modp != NULL; modp = modp->next) { @@ -107,32 +125,110 @@ sim_module_init (SIM_DESC sd) return SIM_RC_OK; } +/* Called when ever the simulator is resumed */ + +SIM_RC +sim_module_resume (SIM_DESC sd) +{ + MODULE_RESUME_LIST *modp; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + for (modp = STATE_RESUME_LIST (sd); modp != NULL; modp = modp->next) + { + if ((*modp->fn) (sd) != SIM_RC_OK) + return SIM_RC_FAIL; + } + return SIM_RC_OK; +} + +/* Called when ever the simulator is suspended */ + +SIM_RC +sim_module_suspend (SIM_DESC sd) +{ + MODULE_SUSPEND_LIST *modp; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + for (modp = STATE_SUSPEND_LIST (sd); modp != NULL; modp = modp->next) + { + if ((*modp->fn) (sd) != SIM_RC_OK) + return SIM_RC_FAIL; + } + return SIM_RC_OK; +} + /* Uninstall installed modules, called by sim_close. */ void sim_module_uninstall (SIM_DESC sd) { MODULE_UNINSTALL_LIST *modp; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); /* Uninstall the modules. */ for (modp = STATE_UNINSTALL_LIST (sd); modp != NULL; modp = modp->next) (*modp->fn) (sd); } -/* Add FN to the init handler list. */ +/* Add FN to the init handler list. + init in the same order as the install. */ void sim_module_add_init_fn (SIM_DESC sd, MODULE_INIT_FN fn) { MODULE_INIT_LIST *l = (MODULE_INIT_LIST *) xmalloc (sizeof (MODULE_INIT_LIST)); + MODULE_INIT_LIST **last = &STATE_INIT_LIST (sd); + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + while (*last != NULL) + last = &((*last)->next); l->fn = fn; - l->next = STATE_INIT_LIST (sd); - STATE_INIT_LIST (sd) = l; + l->next = NULL; + *last = l; } -/* Add FN to the uninstall handler list. */ +/* Add FN to the resume handler list. + resume in the same order as the install. */ + +void +sim_module_add_resume_fn (SIM_DESC sd, MODULE_RESUME_FN fn) +{ + MODULE_RESUME_LIST *l = ZALLOC (MODULE_RESUME_LIST); + MODULE_RESUME_LIST **last; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + last = &STATE_RESUME_LIST (sd); + while (*last != NULL) + last = &((*last)->next); + + l->fn = fn; + l->next = NULL; + *last = l; +} + +/* Add FN to the init handler list. + suspend in the reverse order to install. */ + +void +sim_module_add_suspend_fn (SIM_DESC sd, MODULE_SUSPEND_FN fn) +{ + MODULE_SUSPEND_LIST *l = ZALLOC (MODULE_SUSPEND_LIST); + MODULE_SUSPEND_LIST **last; + SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); + + last = &STATE_SUSPEND_LIST (sd); + while (*last != NULL) + last = &((*last)->next); + + l->fn = fn; + l->next = STATE_SUSPEND_LIST (sd); + STATE_SUSPEND_LIST (sd) = l; +} + +/* Add FN to the uninstall handler list. + Uninstall in reverse order to install. */ void sim_module_add_uninstall_fn (SIM_DESC sd, MODULE_UNINSTALL_FN fn) diff --git a/sim/common/sim-utils.h b/sim/common/sim-utils.h index dfb991c0e8..cd7cc59c25 100644 --- a/sim/common/sim-utils.h +++ b/sim/common/sim-utils.h @@ -34,9 +34,11 @@ char *sim_add_commas (char *, int, unsigned long); /* Utilities for elapsed time reporting. */ -/* Opaque type, known only inside sim_elapsed_time_foo fns. */ +/* Opaque type, known only inside sim_elapsed_time_foo fns. Externally + it is known to never have the value zero. */ typedef unsigned long SIM_ELAPSED_TIME; + /* Get reference point for future call to sim_time_elapsed. */ SIM_ELAPSED_TIME sim_elapsed_time_get (void);