1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2014 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney and Red Hat.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
23 #ifndef _SIM_EVENTS_C_
24 #define _SIM_EVENTS_C_
27 #include "sim-assert.h"
41 #include <signal.h> /* For SIGPROCMASK et al. */
46 /* core - target byte order */
51 /* core - big-endian */
56 /* core - little-endian */
62 /* sim - host byte order */
67 /* sim - big-endian */
72 /* sim - little-endian */
83 } sim_event_watchpoints
;
87 sim_event_watchpoints watching
;
89 sim_event_handler
*handler
;
91 signed64 time_of_event
;
92 /* watch wallclock event */
94 /* watch core address */
95 address_word core_addr
;
99 /* watch core/sim range */
100 int is_within
; /* 0/1 */
105 /* trace info (if any) */
112 /* The event queue maintains a single absolute time using two
115 TIME_OF_EVENT: this holds the time at which the next event is ment
116 to occur. If no next event it will hold the time of the last
119 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
120 <= 0 (except when poll-event is being processed) indicates that
121 event processing is due. This variable is decremented once for
122 each iteration of a clock cycle.
124 Initially, the clock is started at time one (0) with TIME_OF_EVENT
125 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
127 Clearly there is a bug in that this code assumes that the absolute
128 time counter will never become greater than 2^62.
130 To avoid the need to use 64bit arithmetic, the event queue always
131 contains at least one event scheduled every 16 000 ticks. This
132 limits the time from event counter to values less than
136 #if !defined (SIM_EVENTS_POLL_RATE)
137 #define SIM_EVENTS_POLL_RATE 0x1000
141 #define _ETRACE sd, NULL
144 #define ETRACE_P (WITH_TRACE && STATE_EVENTS (sd)->trace)
147 #define ETRACE(ARGS) \
152 if (STRACE_DEBUG_P (sd)) \
155 SIM_FILTER_PATH (file, __FILE__); \
156 trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
164 /* event queue iterator - don't iterate over the held queue. */
166 #if EXTERN_SIM_EVENTS_P
168 next_event_queue (SIM_DESC sd
,
172 return &STATE_EVENTS (sd
)->queue
;
173 else if (queue
== &STATE_EVENTS (sd
)->queue
)
174 return &STATE_EVENTS (sd
)->watchpoints
;
175 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
176 return &STATE_EVENTS (sd
)->watchedpoints
;
177 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
180 sim_io_error (sd
, "next_event_queue - bad queue");
186 STATIC_INLINE_SIM_EVENTS\
188 sim_events_poll (SIM_DESC sd
,
191 /* just re-schedule in 1000 million ticks time */
192 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
193 sim_io_poll_quit (sd
);
197 /* "events" module install handler.
198 This is called via sim_module_install to install the "events" subsystem
199 into the simulator. */
201 #if EXTERN_SIM_EVENTS_P
202 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
203 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
204 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
205 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
208 #if EXTERN_SIM_EVENTS_P
210 sim_events_install (SIM_DESC sd
)
212 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
213 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
214 sim_module_add_init_fn (sd
, sim_events_init
);
215 sim_module_add_resume_fn (sd
, sim_events_resume
);
216 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
222 /* Suspend/resume the event queue manager when the simulator is not
225 #if EXTERN_SIM_EVENTS_P
227 sim_events_resume (SIM_DESC sd
)
229 sim_events
*events
= STATE_EVENTS (sd
);
230 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
231 SIM_ASSERT (events
->resume_wallclock
== 0);
232 events
->resume_wallclock
= sim_elapsed_time_get ();
237 #if EXTERN_SIM_EVENTS_P
239 sim_events_suspend (SIM_DESC sd
)
241 sim_events
*events
= STATE_EVENTS (sd
);
242 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
243 SIM_ASSERT (events
->resume_wallclock
!= 0);
244 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
245 events
->resume_wallclock
= 0;
251 /* Uninstall the "events" subsystem from the simulator. */
253 #if EXTERN_SIM_EVENTS_P
255 sim_events_uninstall (SIM_DESC sd
)
257 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
258 /* FIXME: free buffers, etc. */
265 #if EXTERN_SIM_EVENTS_P
267 sim_events_zalloc (SIM_DESC sd
)
269 sim_events
*events
= STATE_EVENTS (sd
);
270 sim_event
*new = events
->free_list
;
273 events
->free_list
= new->next
;
274 memset (new, 0, sizeof (*new));
278 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
282 sigfillset (&new_mask
);
283 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
285 new = ZALLOC (sim_event
);
286 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
288 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
295 STATIC_INLINE_SIM_EVENTS\
297 sim_events_free (SIM_DESC sd
,
300 sim_events
*events
= STATE_EVENTS (sd
);
301 dead
->next
= events
->free_list
;
302 events
->free_list
= dead
;
303 if (dead
->trace
!= NULL
)
305 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
311 /* Initialize the simulator event manager */
313 #if EXTERN_SIM_EVENTS_P
315 sim_events_init (SIM_DESC sd
)
317 sim_events
*events
= STATE_EVENTS (sd
);
319 /* drain the interrupt queue */
321 if (events
->held
== NULL
)
322 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
324 /* drain the normal queues */
326 sim_event
**queue
= NULL
;
327 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
329 if (queue
== NULL
) break;
330 while (*queue
!= NULL
)
332 sim_event
*dead
= *queue
;
334 sim_events_free (sd
, dead
);
340 /* wind time back to zero */
341 events
->nr_ticks_to_process
= 1; /* start by doing queue */
342 events
->time_of_event
= 0;
343 events
->time_from_event
= 0;
344 events
->elapsed_wallclock
= 0;
345 events
->resume_wallclock
= 0;
347 /* schedule our initial counter event */
348 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
350 /* from now on, except when the large-int event is being processed
351 the event queue is non empty */
352 SIM_ASSERT (events
->queue
!= NULL
);
361 sim_events_time (SIM_DESC sd
)
363 sim_events
*events
= STATE_EVENTS (sd
);
364 return (events
->time_of_event
- events
->time_from_event
);
370 sim_events_elapsed_time (SIM_DESC sd
)
372 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
374 /* Are we being called inside sim_resume?
375 (Is there a simulation in progress?) */
376 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
377 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
383 /* Returns the time that remains before the event is raised. */
386 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
391 return (event
->time_of_event
- sim_events_time (sd
));
396 STATIC_INLINE_SIM_EVENTS\
398 update_time_from_event (SIM_DESC sd
)
400 sim_events
*events
= STATE_EVENTS (sd
);
401 signed64 current_time
= sim_events_time (sd
);
402 if (events
->queue
!= NULL
)
404 events
->time_of_event
= events
->queue
->time_of_event
;
405 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
409 events
->time_of_event
= current_time
- 1;
410 events
->time_from_event
= -1;
416 for (event
= events
->queue
, i
= 0;
418 event
= event
->next
, i
++)
421 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
423 (long)events
->time_from_event
,
426 (long)event
->time_of_event
,
427 (long)event
->handler
,
429 (event
->trace
!= NULL
) ? ", " : "",
430 (event
->trace
!= NULL
) ? event
->trace
: ""));
433 SIM_ASSERT (current_time
== sim_events_time (sd
));
437 #if EXTERN_SIM_EVENTS_P
439 insert_sim_event (SIM_DESC sd
,
440 sim_event
*new_event
,
443 sim_events
*events
= STATE_EVENTS (sd
);
446 signed64 time_of_event
;
449 sim_io_error (sd
, "what is past is past!\n");
451 /* compute when the event should occur */
452 time_of_event
= sim_events_time (sd
) + delta
;
454 /* find the queue insertion point - things are time ordered */
455 prev
= &events
->queue
;
456 curr
= events
->queue
;
457 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
459 SIM_ASSERT (curr
->next
== NULL
460 || curr
->time_of_event
<= curr
->next
->time_of_event
);
464 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
467 new_event
->next
= curr
;
469 new_event
->time_of_event
= time_of_event
;
471 /* adjust the time until the first event */
472 update_time_from_event (sd
);
477 #if EXTERN_SIM_EVENTS_P
479 sim_events_schedule (SIM_DESC sd
,
481 sim_event_handler
*handler
,
485 memset (&dummy
, 0, sizeof dummy
);
486 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
492 #if EXTERN_SIM_EVENTS_P
494 sim_events_schedule_tracef (SIM_DESC sd
,
496 sim_event_handler
*handler
,
501 sim_event
*new_event
;
504 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
511 #if EXTERN_SIM_EVENTS_P
513 sim_events_schedule_vtracef (SIM_DESC sd
,
515 sim_event_handler
*handler
,
520 sim_event
*new_event
= sim_events_zalloc (sd
);
521 new_event
->data
= data
;
522 new_event
->handler
= handler
;
523 new_event
->watching
= watch_timer
;
524 if (fmt
== NULL
|| !ETRACE_P
|| vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
525 new_event
->trace
= NULL
;
526 insert_sim_event (sd
, new_event
, delta_time
);
528 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
529 (long)sim_events_time (sd
),
531 (long)new_event
->time_of_event
,
532 (long)new_event
->handler
,
533 (long)new_event
->data
,
534 (new_event
->trace
!= NULL
) ? ", " : "",
535 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
541 #if EXTERN_SIM_EVENTS_P
543 sim_events_schedule_after_signal (SIM_DESC sd
,
545 sim_event_handler
*handler
,
548 sim_events
*events
= STATE_EVENTS (sd
);
549 sim_event
*new_event
;
550 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
554 sigfillset (&new_mask
);
555 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
558 /* allocate an event entry from the signal buffer */
559 new_event
= &events
->held
[events
->nr_held
];
561 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
563 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
564 "sim_events_schedule_after_signal - buffer oveflow");
567 new_event
->data
= data
;
568 new_event
->handler
= handler
;
569 new_event
->time_of_event
= delta_time
; /* work it out later */
570 new_event
->next
= NULL
;
572 events
->work_pending
= 1; /* notify main process */
574 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
576 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
580 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
581 (long)sim_events_time (sd
),
583 (long)new_event
->time_of_event
,
584 (long)new_event
->handler
,
585 (long)new_event
->data
));
590 #if EXTERN_SIM_EVENTS_P
592 sim_events_watch_clock (SIM_DESC sd
,
593 unsigned delta_ms_time
,
594 sim_event_handler
*handler
,
597 sim_events
*events
= STATE_EVENTS (sd
);
598 sim_event
*new_event
= sim_events_zalloc (sd
);
600 new_event
->watching
= watch_clock
;
602 new_event
->data
= data
;
603 new_event
->handler
= handler
;
605 if (events
->resume_wallclock
== 0)
606 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
608 new_event
->wallclock
= (events
->elapsed_wallclock
609 + sim_elapsed_time_since (events
->resume_wallclock
)
612 new_event
->next
= events
->watchpoints
;
613 events
->watchpoints
= new_event
;
614 events
->work_pending
= 1;
616 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
617 (long)sim_events_time (sd
),
619 (long)new_event
->wallclock
,
620 (long)new_event
->handler
,
621 (long)new_event
->data
));
627 #if EXTERN_SIM_EVENTS_P
629 sim_events_watch_sim (SIM_DESC sd
,
636 sim_event_handler
*handler
,
639 sim_events
*events
= STATE_EVENTS (sd
);
640 sim_event
*new_event
= sim_events_zalloc (sd
);
647 case 1: new_event
->watching
= watch_sim_host_1
; break;
648 case 2: new_event
->watching
= watch_sim_host_2
; break;
649 case 4: new_event
->watching
= watch_sim_host_4
; break;
650 case 8: new_event
->watching
= watch_sim_host_8
; break;
651 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
657 case 1: new_event
->watching
= watch_sim_be_1
; break;
658 case 2: new_event
->watching
= watch_sim_be_2
; break;
659 case 4: new_event
->watching
= watch_sim_be_4
; break;
660 case 8: new_event
->watching
= watch_sim_be_8
; break;
661 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
667 case 1: new_event
->watching
= watch_sim_le_1
; break;
668 case 2: new_event
->watching
= watch_sim_le_2
; break;
669 case 4: new_event
->watching
= watch_sim_le_4
; break;
670 case 8: new_event
->watching
= watch_sim_le_8
; break;
671 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
675 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
678 new_event
->data
= data
;
679 new_event
->handler
= handler
;
681 new_event
->host_addr
= host_addr
;
683 new_event
->lb64
= lb
;
685 new_event
->ub64
= ub
;
686 new_event
->is_within
= (is_within
!= 0);
688 new_event
->next
= events
->watchpoints
;
689 events
->watchpoints
= new_event
;
690 events
->work_pending
= 1;
692 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
693 (long)sim_events_time (sd
),
695 (long)new_event
->host_addr
,
698 (long)new_event
->handler
,
699 (long)new_event
->data
));
705 #if EXTERN_SIM_EVENTS_P
707 sim_events_watch_core (SIM_DESC sd
,
708 address_word core_addr
,
715 sim_event_handler
*handler
,
718 sim_events
*events
= STATE_EVENTS (sd
);
719 sim_event
*new_event
= sim_events_zalloc (sd
);
726 case 1: new_event
->watching
= watch_core_targ_1
; break;
727 case 2: new_event
->watching
= watch_core_targ_2
; break;
728 case 4: new_event
->watching
= watch_core_targ_4
; break;
729 case 8: new_event
->watching
= watch_core_targ_8
; break;
730 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
736 case 1: new_event
->watching
= watch_core_be_1
; break;
737 case 2: new_event
->watching
= watch_core_be_2
; break;
738 case 4: new_event
->watching
= watch_core_be_4
; break;
739 case 8: new_event
->watching
= watch_core_be_8
; break;
740 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
746 case 1: new_event
->watching
= watch_core_le_1
; break;
747 case 2: new_event
->watching
= watch_core_le_2
; break;
748 case 4: new_event
->watching
= watch_core_le_4
; break;
749 case 8: new_event
->watching
= watch_core_le_8
; break;
750 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
754 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
757 new_event
->data
= data
;
758 new_event
->handler
= handler
;
760 new_event
->core_addr
= core_addr
;
761 new_event
->core_map
= core_map
;
763 new_event
->lb64
= lb
;
765 new_event
->ub64
= ub
;
766 new_event
->is_within
= (is_within
!= 0);
768 new_event
->next
= events
->watchpoints
;
769 events
->watchpoints
= new_event
;
770 events
->work_pending
= 1;
772 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
773 (long)sim_events_time (sd
),
775 (long)new_event
->host_addr
,
778 (long)new_event
->handler
,
779 (long)new_event
->data
));
785 #if EXTERN_SIM_EVENTS_P
787 sim_events_deschedule (SIM_DESC sd
,
788 sim_event
*event_to_remove
)
790 sim_events
*events
= STATE_EVENTS (sd
);
791 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
792 if (event_to_remove
!= NULL
)
794 sim_event
**queue
= NULL
;
795 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
797 sim_event
**ptr_to_current
;
798 for (ptr_to_current
= queue
;
799 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
800 ptr_to_current
= &(*ptr_to_current
)->next
);
801 if (*ptr_to_current
== to_remove
)
803 sim_event
*dead
= *ptr_to_current
;
804 *ptr_to_current
= dead
->next
;
806 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
807 (long) sim_events_time (sd
),
808 (long) event_to_remove
,
809 (long) dead
->time_of_event
,
810 (long) dead
->handler
,
812 (dead
->trace
!= NULL
) ? ", " : "",
813 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
814 sim_events_free (sd
, dead
);
815 update_time_from_event (sd
);
816 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
822 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
823 (long) sim_events_time (sd
),
824 (long) event_to_remove
));
829 STATIC_INLINE_SIM_EVENTS\
831 sim_watch_valid (SIM_DESC sd
,
834 switch (to_do
->watching
)
837 #define WATCH_CORE(N,OP,EXT) \
839 unsigned_##N word = 0; \
840 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
841 to_do->core_addr, sizeof (word)); \
843 ok = (nr_read == sizeof (unsigned_##N) \
844 && (to_do->is_within \
845 == (word >= to_do->lb##EXT \
846 && word <= to_do->ub##EXT)));
848 case watch_core_targ_1
:
850 WATCH_CORE (1, T2H
,);
853 case watch_core_targ_2
:
855 WATCH_CORE (2, T2H
,);
858 case watch_core_targ_4
:
860 WATCH_CORE (4, T2H
,);
863 case watch_core_targ_8
:
865 WATCH_CORE (8, T2H
,64);
869 case watch_core_be_1
:
871 WATCH_CORE (1, BE2H
,);
874 case watch_core_be_2
:
876 WATCH_CORE (2, BE2H
,);
879 case watch_core_be_4
:
881 WATCH_CORE (4, BE2H
,);
884 case watch_core_be_8
:
886 WATCH_CORE (8, BE2H
,64);
890 case watch_core_le_1
:
892 WATCH_CORE (1, LE2H
,);
895 case watch_core_le_2
:
897 WATCH_CORE (2, LE2H
,);
900 case watch_core_le_4
:
902 WATCH_CORE (4, LE2H
,);
905 case watch_core_le_8
:
907 WATCH_CORE (8, LE2H
,64);
912 #define WATCH_SIM(N,OP,EXT) \
914 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
916 ok = (to_do->is_within \
917 == (word >= to_do->lb##EXT \
918 && word <= to_do->ub##EXT));
920 case watch_sim_host_1
:
922 WATCH_SIM (1, word
= ,);
925 case watch_sim_host_2
:
927 WATCH_SIM (2, word
= ,);
930 case watch_sim_host_4
:
932 WATCH_SIM (4, word
= ,);
935 case watch_sim_host_8
:
937 WATCH_SIM (8, word
= ,64);
943 WATCH_SIM (1, BE2H
,);
948 WATCH_SIM (2, BE2H
,);
953 WATCH_SIM (4, BE2H
,);
958 WATCH_SIM (8, BE2H
,64);
964 WATCH_SIM (1, LE2H
,);
969 WATCH_SIM (1, LE2H
,);
974 WATCH_SIM (1, LE2H
,);
979 WATCH_SIM (1, LE2H
,64);
984 case watch_clock
: /* wallclock */
986 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
987 return (elapsed_time
>= to_do
->wallclock
);
991 sim_io_error (sd
, "sim_watch_valid - bad switch");
1001 sim_events_tick (SIM_DESC sd
)
1003 sim_events
*events
= STATE_EVENTS (sd
);
1005 /* this should only be called after the previous ticks have been
1008 /* Advance the time but *only* if there is nothing to process */
1009 if (events
->work_pending
1010 || events
->time_from_event
== 0)
1012 events
->nr_ticks_to_process
+= 1;
1017 events
->time_from_event
-= 1;
1025 sim_events_tickn (SIM_DESC sd
,
1028 sim_events
*events
= STATE_EVENTS (sd
);
1031 /* this should only be called after the previous ticks have been
1034 /* Advance the time but *only* if there is nothing to process */
1035 if (events
->work_pending
|| events
->time_from_event
< n
)
1037 events
->nr_ticks_to_process
+= n
;
1042 events
->time_from_event
-= n
;
1050 sim_events_slip (SIM_DESC sd
,
1053 sim_events
*events
= STATE_EVENTS (sd
);
1054 SIM_ASSERT (slip
> 0);
1056 /* Flag a ready event with work_pending instead of number of ticks
1057 to process so that the time continues to be correct */
1058 if (events
->time_from_event
< slip
)
1060 events
->work_pending
= 1;
1062 events
->time_from_event
-= slip
;
1068 sim_events_preprocess (SIM_DESC sd
,
1069 int events_were_last
,
1070 int events_were_next
)
1072 sim_events
*events
= STATE_EVENTS (sd
);
1073 if (events_were_last
)
1075 /* Halted part way through event processing */
1076 ASSERT (events
->nr_ticks_to_process
!= 0);
1077 /* The external world can't tell if the event that stopped the
1078 simulator was the last event to process. */
1079 ASSERT (events_were_next
);
1080 sim_events_process (sd
);
1082 else if (events_were_next
)
1084 /* Halted by the last processor */
1085 if (sim_events_tick (sd
))
1086 sim_events_process (sd
);
1093 sim_events_process (SIM_DESC sd
)
1095 sim_events
*events
= STATE_EVENTS (sd
);
1096 signed64 event_time
= sim_events_time (sd
);
1098 /* Clear work_pending before checking nr_held. Clearing
1099 work_pending after nr_held (with out a lock could loose an
1101 events
->work_pending
= 0;
1103 /* move any events that were asynchronously queued by any signal
1104 handlers onto the real event queue. */
1105 if (events
->nr_held
> 0)
1109 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1113 sigfillset (&new_mask
);
1114 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1117 for (i
= 0; i
< events
->nr_held
; i
++)
1119 sim_event
*entry
= &events
->held
[i
];
1120 sim_events_schedule (sd
,
1121 entry
->time_of_event
,
1125 events
->nr_held
= 0;
1127 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1129 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1134 /* Process any watchpoints. Be careful to allow a watchpoint to
1135 appear/disappear under our feet.
1136 To ensure that watchpoints are processed only once per cycle,
1137 they are moved onto a watched queue, this returned to the
1138 watchpoint queue when all queue processing has been
1140 while (events
->watchpoints
!= NULL
)
1142 sim_event
*to_do
= events
->watchpoints
;
1143 events
->watchpoints
= to_do
->next
;
1144 if (sim_watch_valid (sd
, to_do
))
1146 sim_event_handler
*handler
= to_do
->handler
;
1147 void *data
= to_do
->data
;
1149 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1154 (to_do
->trace
!= NULL
) ? ", " : "",
1155 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1156 sim_events_free (sd
, to_do
);
1161 to_do
->next
= events
->watchedpoints
;
1162 events
->watchedpoints
= to_do
;
1166 /* consume all events for this or earlier times. Be careful to
1167 allow an event to appear/disappear under our feet */
1168 while (events
->queue
->time_of_event
<
1169 (event_time
+ events
->nr_ticks_to_process
))
1171 sim_event
*to_do
= events
->queue
;
1172 sim_event_handler
*handler
= to_do
->handler
;
1173 void *data
= to_do
->data
;
1174 events
->queue
= to_do
->next
;
1175 update_time_from_event (sd
);
1177 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1182 (to_do
->trace
!= NULL
) ? ", " : "",
1183 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1184 sim_events_free (sd
, to_do
);
1188 /* put things back where they belong ready for the next iteration */
1189 events
->watchpoints
= events
->watchedpoints
;
1190 events
->watchedpoints
= NULL
;
1191 if (events
->watchpoints
!= NULL
)
1192 events
->work_pending
= 1;
1194 /* advance the time */
1195 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1196 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1197 events
->time_from_event
-= events
->nr_ticks_to_process
;
1199 /* this round of processing complete */
1200 events
->nr_ticks_to_process
= 0;