diff options
author | Andrew Cagney <cagney@redhat.com> | 1997-05-21 06:54:13 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1997-05-21 06:54:13 +0000 |
commit | 50a2a691824992f474b19bf40bbff016b2f67150 (patch) | |
tree | 00df34e93ad0cb95e742316790b57f1ced5d7bb8 /sim/common/sim-events.c | |
parent | 003c91bec4849e4a5b54d6e81383a4ff4376e996 (diff) | |
download | gdb-50a2a691824992f474b19bf40bbff016b2f67150.zip gdb-50a2a691824992f474b19bf40bbff016b2f67150.tar.gz gdb-50a2a691824992f474b19bf40bbff016b2f67150.tar.bz2 |
Watchpoint interface.
Diffstat (limited to 'sim/common/sim-events.c')
-rw-r--r-- | sim/common/sim-events.c | 322 |
1 files changed, 190 insertions, 132 deletions
diff --git a/sim/common/sim-events.c b/sim/common/sim-events.c index 00fac12..0053fbb 100644 --- a/sim/common/sim-events.c +++ b/sim/common/sim-events.c @@ -25,8 +25,17 @@ #include "sim-main.h" #include "sim-assert.h" +#ifdef HAVE_STRING_H +#include <string.h> +#else +#ifdef HAVE_STRINGS_H +#include <strings.h> +#endif +#endif + #include <signal.h> + typedef enum { watch_invalid, @@ -67,11 +76,11 @@ typedef enum { /* timer */ watch_timer, -} sim_watchpoints; +} sim_event_watchpoints; struct _sim_event { - sim_watchpoints watching; + sim_event_watchpoints watching; void *data; sim_event_handler *handler; /* timer event */ @@ -102,8 +111,9 @@ struct _sim_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. + pending (eg when poll-event is being processed) 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. @@ -118,7 +128,7 @@ struct _sim_event { #if !defined (SIM_EVENTS_POLL_RATE) -#define SIM_EVENTS_POLL_RATE 0x4000 +#define SIM_EVENTS_POLL_RATE 0x100000 #endif @@ -142,7 +152,8 @@ do \ while (0) -/* event queue iterator */ +/* event queue iterator - don't iterate over the held queue. */ + STATIC_INLINE_SIM_EVENTS\ (sim_event **) next_event_queue (SIM_DESC sd, @@ -181,6 +192,7 @@ EXTERN_SIM_EVENTS\ (SIM_RC) 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); return SIM_RC_OK; @@ -197,6 +209,48 @@ sim_events_uninstall (SIM_DESC sd) } +/* malloc/free */ + +STATIC_INLINE_SIM_EVENTS\ +(sim_event *) +sim_events_zalloc (SIM_DESC sd) +{ + sim_events *events = STATE_EVENTS (sd); + sim_event *new = events->free_list; + if (new != NULL) + { + events->free_list = new->next; + memset (new, 0, sizeof (*new)); + } + else + { +#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 + new = ZALLOC (sim_event); +#if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK) + /*-UNLOCK-*/ + sigprocmask (SIG_SETMASK, &old_mask, NULL); +#endif + } + return new; +} + +STATIC_INLINE_SIM_EVENTS\ +(void) +sim_events_free (SIM_DESC sd, + sim_event *dead) +{ + sim_events *events = STATE_EVENTS (sd); + dead->next = events->free_list; + events->free_list = dead; +} + + /* Initialize the simulator event manager */ EXTERN_SIM_EVENTS\ @@ -206,27 +260,9 @@ sim_events_init (SIM_DESC sd) sim_events *events = STATE_EVENTS (sd); /* drain the interrupt queue */ - { - sim_event *event; -#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; - events->work_pending = 0; -#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK) - /*-UNLOCK-*/ sigprocmask(SIG_SETMASK, &old_mask, NULL); -#endif - } + events->nr_held = 0; + if (events->held == NULL) + events->held = zalloc (sizeof (sim_event) * MAX_NR_SIGNAL_SIM_EVENTS); /* drain the normal queues */ { @@ -238,14 +274,14 @@ sim_events_init (SIM_DESC sd) { sim_event *dead = *queue; *queue = dead->next; - zfree (dead); + sim_events_free (sd, dead); } *queue = NULL; } } /* wind time back to zero */ - events->processing = 1; /* start by doing queue */ + 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 (); @@ -337,7 +373,7 @@ sim_events_schedule (SIM_DESC sd, sim_event_handler *handler, void *data) { - sim_event *new_event = ZALLOC(sim_event); + sim_event *new_event = sim_events_zalloc (sd); new_event->data = data; new_event->handler = handler; new_event->watching = watch_timer; @@ -354,70 +390,69 @@ sim_events_schedule (SIM_DESC sd, EXTERN_SIM_EVENTS\ -(sim_event *) -sim_events_schedule_after_signal(SIM_DESC sd, - signed64 delta_time, - sim_event_handler *handler, - void *data) +(void) +sim_events_schedule_after_signal (SIM_DESC sd, + signed64 delta_time, + sim_event_handler *handler, + void *data) { sim_events *events = STATE_EVENTS (sd); - sim_event *new_event = ZALLOC (sim_event); + sim_event *new_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 + + /* allocate an event entry from the signal buffer */ + new_event = &events->held [events->nr_held]; + events->nr_held ++; + if (events->nr_held >= MAX_NR_SIGNAL_SIM_EVENTS) + { + sim_engine_abort (NULL, NULL, NULL_CIA, + "sim_events_schedule_after_signal - buffer oveflow"); + } 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) - /*-LOCK-*/ - sigset_t old_mask; - sigset_t new_mask; - sigfillset(&new_mask); - 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; - events->work_pending = 1; /* notify main process */ + + events->work_pending = 1; /* notify main process */ + #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK) - /*-UNLOCK-*/ - sigprocmask (SIG_SETMASK, &old_mask, NULL); + /*-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", + "signal 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; } EXTERN_SIM_EVENTS\ (sim_event *) sim_events_watch_clock (SIM_DESC sd, - unsigned wallclock_ms_time, + unsigned delta_ms_time, sim_event_handler *handler, void *data) { sim_events *events = STATE_EVENTS (sd); - sim_event *new_event = ZALLOC (sim_event); + sim_event *new_event = sim_events_zalloc (sd); /* type */ new_event->watching = watch_clock; /* handler */ new_event->data = data; new_event->handler = handler; /* data */ - new_event->wallclock = wallclock_ms_time; + new_event->wallclock = (sim_elapsed_time_since (events->initial_wallclock) + delta_ms_time); /* insert */ new_event->next = events->watchpoints; events->watchpoints = new_event; @@ -445,7 +480,7 @@ sim_events_watch_sim (SIM_DESC sd, void *data) { sim_events *events = STATE_EVENTS (sd); - sim_event *new_event = ZALLOC (sim_event); + sim_event *new_event = sim_events_zalloc (sd); /* type */ switch (byte_order) { @@ -521,7 +556,7 @@ sim_events_watch_core (SIM_DESC sd, void *data) { sim_events *events = STATE_EVENTS (sd); - sim_event *new_event = ZALLOC (sim_event); + sim_event *new_event = sim_events_zalloc (sd); /* type */ switch (byte_order) { @@ -613,7 +648,7 @@ sim_events_deschedule (SIM_DESC sd, (long) dead->time_of_event, (long) dead->handler, (long) dead->data)); - zfree (dead); + sim_events_free (sd, dead); update_time_from_event (sd); SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL)); return; @@ -635,60 +670,59 @@ sim_watch_valid (SIM_DESC sd, switch (to_do->watching) { -#define WATCH_CORE(N,OP) \ +#define WATCH_CORE(N,OP,EXT) \ { \ unsigned_##N word; \ sim_core_read_buffer (sd, to_do->core_map, &word, to_do->core_addr, sizeof (word)); \ OP (word); \ - return (word >= to_do->lb && word <= to_do->ub); \ + return (word >= to_do->lb##EXT && word <= to_do->ub##EXT); \ } - - case watch_core_targ_1: WATCH_CORE (1, T2H); - case watch_core_targ_2: WATCH_CORE (2, T2H); - case watch_core_targ_4: WATCH_CORE (4, T2H); - case watch_core_targ_8: WATCH_CORE (8, T2H); - - case watch_core_be_1: WATCH_CORE (1, BE2H); - case watch_core_be_2: WATCH_CORE (2, BE2H); - case watch_core_be_4: WATCH_CORE (4, BE2H); - case watch_core_be_8: WATCH_CORE (8, BE2H); - - case watch_core_le_1: WATCH_CORE (1, LE2H); - case watch_core_le_2: WATCH_CORE (2, LE2H); - case watch_core_le_4: WATCH_CORE (4, LE2H); - case watch_core_le_8: WATCH_CORE (8, LE2H); - + case watch_core_targ_1: WATCH_CORE (1, T2H,); + case watch_core_targ_2: WATCH_CORE (2, T2H,); + case watch_core_targ_4: WATCH_CORE (4, T2H,); + case watch_core_targ_8: WATCH_CORE (8, T2H,64); + + case watch_core_be_1: WATCH_CORE (1, BE2H,); + case watch_core_be_2: WATCH_CORE (2, BE2H,); + case watch_core_be_4: WATCH_CORE (4, BE2H,); + case watch_core_be_8: WATCH_CORE (8, BE2H,64); + + case watch_core_le_1: WATCH_CORE (1, LE2H,); + case watch_core_le_2: WATCH_CORE (2, LE2H,); + case watch_core_le_4: WATCH_CORE (4, LE2H,); + case watch_core_le_8: WATCH_CORE (8, LE2H,64); #undef WATCH_CORE -#define WATCH_SIM(N,OP) \ +#define WATCH_SIM(N,OP,EXT) \ { \ unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \ OP (word); \ - return (word >= to_do->lb && word <= to_do->ub); \ + return (word >= to_do->lb##EXT && word <= to_do->ub##EXT); \ } - case watch_sim_host_1: WATCH_SIM (1, word = ); - case watch_sim_host_2: WATCH_SIM (2, word = ); - case watch_sim_host_4: WATCH_SIM (4, word = ); - case watch_sim_host_8: WATCH_SIM (8, word = ); + case watch_sim_host_1: WATCH_SIM (1, word = ,); + case watch_sim_host_2: WATCH_SIM (2, word = ,); + case watch_sim_host_4: WATCH_SIM (4, word = ,); + case watch_sim_host_8: WATCH_SIM (8, word = ,64); - case watch_sim_be_1: WATCH_SIM (1, BE2H); - case watch_sim_be_2: WATCH_SIM (2, BE2H); - case watch_sim_be_4: WATCH_SIM (4, BE2H); - case watch_sim_be_8: WATCH_SIM (8, BE2H); + case watch_sim_be_1: WATCH_SIM (1, BE2H,); + case watch_sim_be_2: WATCH_SIM (2, BE2H,); + case watch_sim_be_4: WATCH_SIM (4, BE2H,); + case watch_sim_be_8: WATCH_SIM (8, BE2H,64); - case watch_sim_le_1: WATCH_SIM (1, LE2H); - case watch_sim_le_2: WATCH_SIM (1, LE2H); - case watch_sim_le_4: WATCH_SIM (1, LE2H); - case watch_sim_le_8: WATCH_SIM (1, LE2H); + case watch_sim_le_1: WATCH_SIM (1, LE2H,); + case watch_sim_le_2: WATCH_SIM (1, LE2H,); + case watch_sim_le_4: WATCH_SIM (1, LE2H,); + case watch_sim_le_8: WATCH_SIM (1, LE2H,64); #undef WATCH_SIM case watch_clock: /* wallclock */ - return (sim_elapsed_time_since (STATE_EVENTS (sd)->initial_wallclock) - < to_do->wallclock); + { + unsigned long elapsed_time = sim_elapsed_time_since (STATE_EVENTS (sd)->initial_wallclock); + return (elapsed_time >= to_do->wallclock); + } - case watch_timer: - case watch_invalid: + default: sim_io_error (sd, "sim_watch_valid - bad switch"); break; @@ -703,15 +737,15 @@ sim_events_tick (SIM_DESC sd) { sim_events *events = STATE_EVENTS (sd); - /* this should only be called after the previous tick has been fully - processed */ - SIM_ASSERT (!events->processing); + /* this should only be called after the previous ticks have been + fully processed */ + SIM_ASSERT (events->nr_ticks_to_process == 0); /* Advance the time but *only* if there is nothing to process */ if (events->work_pending || events->time_from_event == 0) { - events->processing = 1; + events->nr_ticks_to_process = 1; return 1; } else { @@ -722,13 +756,39 @@ sim_events_tick (SIM_DESC sd) INLINE_SIM_EVENTS\ +(int) +sim_events_tickn (SIM_DESC sd, + unsigned n) +{ + sim_events *events = STATE_EVENTS (sd); + + /* this should only be called after the previous ticks have been + 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 */ + if (events->work_pending + || events->time_from_event < n) + { + events->nr_ticks_to_process = n; + return 1; + } + else { + events->time_from_event -= n; + return 0; + } +} + + +INLINE_SIM_EVENTS\ (void) sim_events_preprocess (SIM_DESC sd, int events_were_last, int events_were_next) { sim_events *events = STATE_EVENTS(sd); - if (events->processing) + if (events->nr_ticks_to_process != 0) { /* Halted midway through event processing */ ASSERT (events_were_last && events_were_next); @@ -737,7 +797,7 @@ sim_events_preprocess (SIM_DESC sd, else if (events_were_next) { /* Halted by the last processor */ - ASSERT (!events->processing && !events_were_last); + ASSERT (events->nr_ticks_to_process == 0 && !events_were_last); if (sim_events_tick (sd)) sim_events_process (sd); } @@ -751,14 +811,13 @@ sim_events_process (SIM_DESC sd) sim_events *events = STATE_EVENTS(sd); signed64 event_time = sim_events_time(sd); - ASSERT (events->processing); + ASSERT (events->nr_ticks_to_process != 0); /* move any events that were queued by any signal handlers onto the real event queue. */ - if (events->held != NULL) + if (events->nr_held > 0) { - sim_event *held_events; - sim_event *curr_event; + int i; #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK) /*-LOCK-*/ @@ -768,24 +827,21 @@ sim_events_process (SIM_DESC sd) sigprocmask(SIG_SETMASK, &new_mask, &old_mask); #endif - held_events = events->held; - events->held = NULL; - events->held_end = &events->held; - events->work_pending = 0; + for (i = 0; i < events->nr_held; i++) + { + sim_event *entry = &events->held [i]; + sim_events_schedule (sd, + entry->time_of_event, + entry->handler, + entry->data); + } + events->nr_held = 0; #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); } /* Process any watchpoints. Be careful to allow a watchpoint to @@ -809,7 +865,7 @@ sim_events_process (SIM_DESC sd) (long) to_do, (long) handler, (long) data)); - zfree (to_do); + sim_events_free (sd, to_do); handler (sd, data); } else @@ -821,7 +877,8 @@ sim_events_process (SIM_DESC sd) /* consume all events for this or earlier times. Be careful to allow an event to appear/disappear under our feet */ - while (events->queue->time_of_event <= event_time) + while (events->queue->time_of_event < + (event_time + events->nr_ticks_to_process)) { sim_event *to_do = events->queue; sim_event_handler *handler = to_do->handler; @@ -833,7 +890,7 @@ sim_events_process (SIM_DESC sd) (long) to_do, (long) handler, (long) data)); - zfree (to_do); + sim_events_free (sd, to_do); handler (sd, data); } @@ -843,13 +900,14 @@ sim_events_process (SIM_DESC sd) if (events->watchpoints != NULL) events->work_pending = 1; - /* this round of processing complete */ - events->processing = 0; - - /* re-caculate time for new events - advance the time */ + /* re-caculate time for new events then advance the time */ update_time_from_event(sd); - SIM_ASSERT(events->time_from_event > 0 && events->queue != NULL); - events->time_from_event -= 1; + SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process); + SIM_ASSERT (events->queue != NULL); /* always poll event */ + events->time_from_event -= events->nr_ticks_to_process; + + /* this round of processing complete */ + events->nr_ticks_to_process = 0; } #endif |