Add function sim_events_slip()

Clear work_pending flag as part of processing any pending work.
This commit is contained in:
Andrew Cagney 1997-10-24 05:53:01 +00:00
parent 1315b4cb60
commit 4a203fbae2
2 changed files with 56 additions and 16 deletions

View File

@ -1,3 +1,13 @@
Fri Oct 24 11:33:07 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-events.c (sim_events_process): Clear events->work_pending.
(sim_events_tickn, sim_events_tick): Accumulate, instead of
setting, nr_ticks_to_process.
(sim_events_preprocess): Allow nr_ticks_to_process to be non-zero
when the event queue isn't next.
* sim-events.h, sim-events.c (sim_events_slip): New function.
Wed Oct 22 14:18:38 1997 Andrew Cagney <cagney@b1.cygnus.com> Wed Oct 22 14:18:38 1997 Andrew Cagney <cagney@b1.cygnus.com>
* sim-hload.c (sim_load): Pass lma_p==0 and do_load=sim_load. * sim-hload.c (sim_load): Pass lma_p==0 and do_load=sim_load.

View File

@ -129,11 +129,11 @@ struct _sim_event {
#if !defined (SIM_EVENTS_POLL_RATE) #if !defined (SIM_EVENTS_POLL_RATE)
#define SIM_EVENTS_POLL_RATE 0x100000 #define SIM_EVENTS_POLL_RATE 0x1000
#endif #endif
#define _ETRACE sd #define _ETRACE sd, NULL
#undef ETRACE #undef ETRACE
#define ETRACE(ARGS) \ #define ETRACE(ARGS) \
@ -145,8 +145,8 @@ do \
{ \ { \
const char *file; \ const char *file; \
SIM_FILTER_PATH (file, __FILE__); \ SIM_FILTER_PATH (file, __FILE__); \
sim_io_printf (sd, "%s:%d: ", file, __LINE__); \ trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
sim_io_printf ARGS; \ trace_printf ARGS; \
} \ } \
} \ } \
} \ } \
@ -892,16 +892,16 @@ INLINE_SIM_EVENTS\
sim_events_tick (SIM_DESC sd) sim_events_tick (SIM_DESC sd)
{ {
sim_events *events = STATE_EVENTS (sd); sim_events *events = STATE_EVENTS (sd);
SIM_ASSERT (events->nr_ticks_to_process == 0);
/* this should only be called after the previous ticks have been /* this should only be called after the previous ticks have been
fully processed */ fully processed */
SIM_ASSERT (events->nr_ticks_to_process == 0);
/* Advance the time but *only* if there is nothing to process */ /* Advance the time but *only* if there is nothing to process */
if (events->work_pending if (events->work_pending
|| events->time_from_event == 0) || events->time_from_event == 0)
{ {
events->nr_ticks_to_process = 1; events->nr_ticks_to_process += 1;
return 1; return 1;
} }
else { else {
@ -917,17 +917,16 @@ sim_events_tickn (SIM_DESC sd,
int n) int n)
{ {
sim_events *events = STATE_EVENTS (sd); sim_events *events = STATE_EVENTS (sd);
SIM_ASSERT (n > 0);
/* this should only be called after the previous ticks have been /* this should only be called after the previous ticks have been
fully processed */ fully processed */
SIM_ASSERT (events->nr_ticks_to_process == 0);
SIM_ASSERT (n > 0);
/* Advance the time but *only* if there is nothing to process */ /* Advance the time but *only* if there is nothing to process */
if (events->work_pending if (events->work_pending
|| events->time_from_event < n) || events->time_from_event < n)
{ {
events->nr_ticks_to_process = n; events->nr_ticks_to_process += n;
return 1; return 1;
} }
else { else {
@ -937,6 +936,30 @@ sim_events_tickn (SIM_DESC sd,
} }
INLINE_SIM_EVENTS\
(void)
sim_events_slip (SIM_DESC sd,
int slip)
{
sim_events *events = STATE_EVENTS (sd);
SIM_ASSERT (slip > 0);
/* Advance either TIME_FROM_EVENT or NR_TICKS_TO_PROCESS dependant
on which is closer for this SLIP. While previous slips may have
advanced a different counter is sitll valid as the accumulative
effect is still the same. */
if (events->time_from_event < slip)
{
events->nr_ticks_to_process += slip;
events->work_pending = 1;
}
else
{
events->time_from_event -= slip;
}
}
INLINE_SIM_EVENTS\ INLINE_SIM_EVENTS\
(void) (void)
sim_events_preprocess (SIM_DESC sd, sim_events_preprocess (SIM_DESC sd,
@ -944,16 +967,18 @@ sim_events_preprocess (SIM_DESC sd,
int events_were_next) int events_were_next)
{ {
sim_events *events = STATE_EVENTS(sd); sim_events *events = STATE_EVENTS(sd);
if (events->nr_ticks_to_process != 0) if (events_were_last)
{ {
/* Halted midway through event processing */ /* Halted part way through event processing */
ASSERT (events_were_last && events_were_next); ASSERT (events->nr_ticks_to_process != 0);
/* The external world can't tell if the event that stopped the
simulator was the last event to process. */
ASSERT (events_were_next);
sim_events_process (sd); sim_events_process (sd);
} }
else if (events_were_next) else if (events_were_next)
{ {
/* Halted by the last processor */ /* Halted by the last processor */
ASSERT (events->nr_ticks_to_process == 0 && !events_were_last);
if (sim_events_tick (sd)) if (sim_events_tick (sd))
sim_events_process (sd); sim_events_process (sd);
} }
@ -969,8 +994,13 @@ sim_events_process (SIM_DESC sd)
ASSERT (events->nr_ticks_to_process != 0); ASSERT (events->nr_ticks_to_process != 0);
/* move any events that were queued by any signal handlers onto /* Clear work_pending before checking nr_held. Clearing
the real event queue. */ work_pending after nr_held (with out a lock could loose an
event). */
events->work_pending = 0;
/* move any events that were asynchronously queued by any signal
handlers onto the real event queue. */
if (events->nr_held > 0) if (events->nr_held > 0)
{ {
int i; int i;
@ -982,7 +1012,7 @@ sim_events_process (SIM_DESC sd)
sigfillset(&new_mask); sigfillset(&new_mask);
sigprocmask(SIG_SETMASK, &new_mask, &old_mask); sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
#endif #endif
for (i = 0; i < events->nr_held; i++) for (i = 0; i < events->nr_held; i++)
{ {
sim_event *entry = &events->held [i]; sim_event *entry = &events->held [i];