Add support for suspending/resumeing the simulator in sim-modules.
authorAndrew Cagney <cagney@redhat.com>
Wed, 3 Sep 1997 07:26:11 +0000 (07:26 +0000)
committerAndrew Cagney <cagney@redhat.com>
Wed, 3 Sep 1997 07:26:11 +0000 (07:26 +0000)
Use in sim-events.

sim/common/ChangeLog
sim/common/sim-base.h
sim/common/sim-events.c
sim/common/sim-events.h
sim/common/sim-module.c
sim/common/sim-utils.h

index 0e566f4..7017536 100644 (file)
@@ -1,5 +1,27 @@
 Wed Sep  3 10:08:21 1997  Andrew Cagney  <cagney@b1.cygnus.com>
 
+       * 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  <cagney@b1.cygnus.com>
+
        * sim-core.c (sim_core_map_attach): Clarify memory overlap error
        message.
 
index 12e1a25..ef5f1ce 100644 (file)
@@ -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.  */
index 653cd61..7139662 100644 (file)
@@ -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);
       }
 
index dd69f0a..6dd1a2f 100644 (file)
@@ -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\
index b68a4f3..9292c37 100644 (file)
@@ -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);
 }
 \f
-/* 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 = NULL;
+  *last = l;
+}
+
+/* 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_INIT_LIST (sd);
-  STATE_INIT_LIST (sd) = l;
+  l->next = STATE_SUSPEND_LIST (sd);
+  STATE_SUSPEND_LIST (sd) = l;
 }
 
-/* Add FN to the uninstall handler list.  */
+/* 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)
index dfb991c..cd7cc59 100644 (file)
@@ -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);