1 /* This file is part of the program psim.
3 Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #ifndef _SIM_EVENTS_C_
23 #define _SIM_EVENTS_C_
26 #include "sim-assert.h"
40 #include <signal.h> /* For SIGPROCMASK et.al. */
45 /* core - target byte order */
50 /* core - big-endian */
55 /* core - little-endian */
61 /* sim - host byte order */
66 /* sim - big-endian */
71 /* sim - little-endian */
82 } sim_event_watchpoints
;
86 sim_event_watchpoints watching
;
88 sim_event_handler
*handler
;
90 signed64 time_of_event
;
91 /* watch wallclock event */
93 /* watch core address */
94 address_word core_addr
;
98 /* watch core/sim range */
99 int is_within
; /* 0/1 */
104 /* trace info (if any) */
111 /* The event queue maintains a single absolute time using two
114 TIME_OF_EVENT: this holds the time at which the next event is ment
115 to occure. If no next event it will hold the time of the last
118 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
119 <= 0 (except when poll-event is being processed) indicates that
120 event processing is due. This variable is decremented once for
121 each iteration of a clock cycle.
123 Initially, the clock is started at time one (0) with TIME_OF_EVENT
124 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
126 Clearly there is a bug in that this code assumes that the absolute
127 time counter will never become greater than 2^62.
129 To avoid the need to use 64bit arithmetic, the event queue always
130 contains at least one event scheduled every 16 000 ticks. This
131 limits the time from event counter to values less than
135 #if !defined (SIM_EVENTS_POLL_RATE)
136 #define SIM_EVENTS_POLL_RATE 0x1000
140 #define _ETRACE sd, NULL
143 #define ETRACE_P (WITH_TRACE && STATE_EVENTS (sd)->trace)
146 #define ETRACE(ARGS) \
151 if (STRACE_DEBUG_P (sd)) \
154 SIM_FILTER_PATH (file, __FILE__); \
155 trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
163 /* event queue iterator - don't iterate over the held queue. */
165 #if EXTERN_SIM_EVENTS_P
167 next_event_queue (SIM_DESC sd
,
171 return &STATE_EVENTS (sd
)->queue
;
172 else if (queue
== &STATE_EVENTS (sd
)->queue
)
173 return &STATE_EVENTS (sd
)->watchpoints
;
174 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
175 return &STATE_EVENTS (sd
)->watchedpoints
;
176 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
179 sim_io_error (sd
, "next_event_queue - bad queue");
185 STATIC_INLINE_SIM_EVENTS\
187 sim_events_poll (SIM_DESC sd
,
190 /* just re-schedule in 1000 million ticks time */
191 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
192 sim_io_poll_quit (sd
);
196 /* "events" module install handler.
197 This is called via sim_module_install to install the "events" subsystem
198 into the simulator. */
200 #if EXTERN_SIM_EVENTS_P
201 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
202 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
203 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
204 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
207 #if EXTERN_SIM_EVENTS_P
209 sim_events_install (SIM_DESC sd
)
211 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
212 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
213 sim_module_add_init_fn (sd
, sim_events_init
);
214 sim_module_add_resume_fn (sd
, sim_events_resume
);
215 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
221 /* Suspend/resume the event queue manager when the simulator is not
224 #if EXTERN_SIM_EVENTS_P
226 sim_events_resume (SIM_DESC sd
)
228 sim_events
*events
= STATE_EVENTS (sd
);
229 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
230 SIM_ASSERT (events
->resume_wallclock
== 0);
231 events
->resume_wallclock
= sim_elapsed_time_get ();
236 #if EXTERN_SIM_EVENTS_P
238 sim_events_suspend (SIM_DESC sd
)
240 sim_events
*events
= STATE_EVENTS (sd
);
241 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
242 SIM_ASSERT (events
->resume_wallclock
!= 0);
243 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
244 events
->resume_wallclock
= 0;
250 /* Uninstall the "events" subsystem from the simulator. */
252 #if EXTERN_SIM_EVENTS_P
254 sim_events_uninstall (SIM_DESC sd
)
256 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
257 /* FIXME: free buffers, etc. */
264 #if EXTERN_SIM_EVENTS_P
266 sim_events_zalloc (SIM_DESC sd
)
268 sim_events
*events
= STATE_EVENTS (sd
);
269 sim_event
*new = events
->free_list
;
272 events
->free_list
= new->next
;
273 memset (new, 0, sizeof (*new));
277 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
281 sigfillset(&new_mask
);
282 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
284 new = ZALLOC (sim_event
);
285 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
287 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
294 STATIC_INLINE_SIM_EVENTS\
296 sim_events_free (SIM_DESC sd
,
299 sim_events
*events
= STATE_EVENTS (sd
);
300 dead
->next
= events
->free_list
;
301 events
->free_list
= dead
;
302 if (dead
->trace
!= NULL
)
304 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
310 /* Initialize the simulator event manager */
312 #if EXTERN_SIM_EVENTS_P
314 sim_events_init (SIM_DESC sd
)
316 sim_events
*events
= STATE_EVENTS (sd
);
318 /* drain the interrupt queue */
320 if (events
->held
== NULL
)
321 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
323 /* drain the normal queues */
325 sim_event
**queue
= NULL
;
326 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
328 if (queue
== NULL
) break;
329 while (*queue
!= NULL
)
331 sim_event
*dead
= *queue
;
333 sim_events_free (sd
, dead
);
339 /* wind time back to zero */
340 events
->nr_ticks_to_process
= 1; /* start by doing queue */
341 events
->time_of_event
= 0;
342 events
->time_from_event
= 0;
343 events
->elapsed_wallclock
= 0;
344 events
->resume_wallclock
= 0;
346 /* schedule our initial counter event */
347 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
349 /* from now on, except when the large-int event is being processed
350 the event queue is non empty */
351 SIM_ASSERT (events
->queue
!= NULL
);
360 sim_events_time (SIM_DESC sd
)
362 sim_events
*events
= STATE_EVENTS (sd
);
363 return (events
->time_of_event
- events
->time_from_event
);
369 sim_events_elapsed_time (SIM_DESC sd
)
371 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
373 /* Are we being called inside sim_resume?
374 (Is there a simulation in progress?) */
375 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
376 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
382 STATIC_INLINE_SIM_EVENTS\
384 update_time_from_event (SIM_DESC sd
)
386 sim_events
*events
= STATE_EVENTS (sd
);
387 signed64 current_time
= sim_events_time (sd
);
388 if (events
->queue
!= NULL
)
390 events
->time_of_event
= events
->queue
->time_of_event
;
391 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
395 events
->time_of_event
= current_time
- 1;
396 events
->time_from_event
= -1;
402 for (event
= events
->queue
, i
= 0;
404 event
= event
->next
, i
++)
407 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
409 (long)events
->time_from_event
,
412 (long)event
->time_of_event
,
413 (long)event
->handler
,
415 (event
->trace
!= NULL
) ? ", " : "",
416 (event
->trace
!= NULL
) ? event
->trace
: ""));
419 SIM_ASSERT (current_time
== sim_events_time (sd
));
423 #if EXTERN_SIM_EVENTS_P
425 insert_sim_event (SIM_DESC sd
,
426 sim_event
*new_event
,
429 sim_events
*events
= STATE_EVENTS (sd
);
432 signed64 time_of_event
;
435 sim_io_error (sd
, "what is past is past!\n");
437 /* compute when the event should occure */
438 time_of_event
= sim_events_time (sd
) + delta
;
440 /* find the queue insertion point - things are time ordered */
441 prev
= &events
->queue
;
442 curr
= events
->queue
;
443 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
445 SIM_ASSERT (curr
->next
== NULL
446 || curr
->time_of_event
<= curr
->next
->time_of_event
);
450 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
453 new_event
->next
= curr
;
455 new_event
->time_of_event
= time_of_event
;
457 /* adjust the time until the first event */
458 update_time_from_event (sd
);
463 #if EXTERN_SIM_EVENTS_P
465 sim_events_schedule (SIM_DESC sd
,
467 sim_event_handler
*handler
,
471 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
477 #if EXTERN_SIM_EVENTS_P
479 sim_events_schedule_tracef (SIM_DESC sd
,
481 sim_event_handler
*handler
,
486 sim_event
*new_event
;
489 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
496 #if EXTERN_SIM_EVENTS_P
498 sim_events_schedule_vtracef (SIM_DESC sd
,
500 sim_event_handler
*handler
,
505 sim_event
*new_event
= sim_events_zalloc (sd
);
506 new_event
->data
= data
;
507 new_event
->handler
= handler
;
508 new_event
->watching
= watch_timer
;
509 if (fmt
== NULL
|| !ETRACE_P
|| vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
510 new_event
->trace
= NULL
;
511 insert_sim_event(sd
, new_event
, delta_time
);
513 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
514 (long)sim_events_time(sd
),
516 (long)new_event
->time_of_event
,
517 (long)new_event
->handler
,
518 (long)new_event
->data
,
519 (new_event
->trace
!= NULL
) ? ", " : "",
520 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
526 #if EXTERN_SIM_EVENTS_P
528 sim_events_schedule_after_signal (SIM_DESC sd
,
530 sim_event_handler
*handler
,
533 sim_events
*events
= STATE_EVENTS (sd
);
534 sim_event
*new_event
;
535 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
539 sigfillset(&new_mask
);
540 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
543 /* allocate an event entry from the signal buffer */
544 new_event
= &events
->held
[events
->nr_held
];
546 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
548 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
549 "sim_events_schedule_after_signal - buffer oveflow");
552 new_event
->data
= data
;
553 new_event
->handler
= handler
;
554 new_event
->time_of_event
= delta_time
; /* work it out later */
555 new_event
->next
= NULL
;
557 events
->work_pending
= 1; /* notify main process */
559 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
561 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
565 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
566 (long)sim_events_time(sd
),
568 (long)new_event
->time_of_event
,
569 (long)new_event
->handler
,
570 (long)new_event
->data
));
575 #if EXTERN_SIM_EVENTS_P
577 sim_events_watch_clock (SIM_DESC sd
,
578 unsigned delta_ms_time
,
579 sim_event_handler
*handler
,
582 sim_events
*events
= STATE_EVENTS (sd
);
583 sim_event
*new_event
= sim_events_zalloc (sd
);
585 new_event
->watching
= watch_clock
;
587 new_event
->data
= data
;
588 new_event
->handler
= handler
;
590 if (events
->resume_wallclock
== 0)
591 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
593 new_event
->wallclock
= (events
->elapsed_wallclock
594 + sim_elapsed_time_since (events
->resume_wallclock
)
597 new_event
->next
= events
->watchpoints
;
598 events
->watchpoints
= new_event
;
599 events
->work_pending
= 1;
601 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
602 (long)sim_events_time (sd
),
604 (long)new_event
->wallclock
,
605 (long)new_event
->handler
,
606 (long)new_event
->data
));
612 #if EXTERN_SIM_EVENTS_P
614 sim_events_watch_sim (SIM_DESC sd
,
621 sim_event_handler
*handler
,
624 sim_events
*events
= STATE_EVENTS (sd
);
625 sim_event
*new_event
= sim_events_zalloc (sd
);
632 case 1: new_event
->watching
= watch_sim_host_1
; break;
633 case 2: new_event
->watching
= watch_sim_host_2
; break;
634 case 4: new_event
->watching
= watch_sim_host_4
; break;
635 case 8: new_event
->watching
= watch_sim_host_8
; break;
636 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
642 case 1: new_event
->watching
= watch_sim_be_1
; break;
643 case 2: new_event
->watching
= watch_sim_be_2
; break;
644 case 4: new_event
->watching
= watch_sim_be_4
; break;
645 case 8: new_event
->watching
= watch_sim_be_8
; break;
646 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
652 case 1: new_event
->watching
= watch_sim_le_1
; break;
653 case 2: new_event
->watching
= watch_sim_le_2
; break;
654 case 4: new_event
->watching
= watch_sim_le_4
; break;
655 case 8: new_event
->watching
= watch_sim_le_8
; break;
656 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
660 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
663 new_event
->data
= data
;
664 new_event
->handler
= handler
;
666 new_event
->host_addr
= host_addr
;
668 new_event
->lb64
= lb
;
670 new_event
->ub64
= ub
;
671 new_event
->is_within
= (is_within
!= 0);
673 new_event
->next
= events
->watchpoints
;
674 events
->watchpoints
= new_event
;
675 events
->work_pending
= 1;
677 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
678 (long)sim_events_time (sd
),
680 (long)new_event
->host_addr
,
683 (long)new_event
->handler
,
684 (long)new_event
->data
));
690 #if EXTERN_SIM_EVENTS_P
692 sim_events_watch_core (SIM_DESC sd
,
693 address_word core_addr
,
700 sim_event_handler
*handler
,
703 sim_events
*events
= STATE_EVENTS (sd
);
704 sim_event
*new_event
= sim_events_zalloc (sd
);
711 case 1: new_event
->watching
= watch_core_targ_1
; break;
712 case 2: new_event
->watching
= watch_core_targ_2
; break;
713 case 4: new_event
->watching
= watch_core_targ_4
; break;
714 case 8: new_event
->watching
= watch_core_targ_8
; break;
715 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
721 case 1: new_event
->watching
= watch_core_be_1
; break;
722 case 2: new_event
->watching
= watch_core_be_2
; break;
723 case 4: new_event
->watching
= watch_core_be_4
; break;
724 case 8: new_event
->watching
= watch_core_be_8
; break;
725 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
731 case 1: new_event
->watching
= watch_core_le_1
; break;
732 case 2: new_event
->watching
= watch_core_le_2
; break;
733 case 4: new_event
->watching
= watch_core_le_4
; break;
734 case 8: new_event
->watching
= watch_core_le_8
; break;
735 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
739 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
742 new_event
->data
= data
;
743 new_event
->handler
= handler
;
745 new_event
->core_addr
= core_addr
;
746 new_event
->core_map
= core_map
;
748 new_event
->lb64
= lb
;
750 new_event
->ub64
= ub
;
751 new_event
->is_within
= (is_within
!= 0);
753 new_event
->next
= events
->watchpoints
;
754 events
->watchpoints
= new_event
;
755 events
->work_pending
= 1;
757 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
758 (long)sim_events_time (sd
),
760 (long)new_event
->host_addr
,
763 (long)new_event
->handler
,
764 (long)new_event
->data
));
770 #if EXTERN_SIM_EVENTS_P
772 sim_events_deschedule (SIM_DESC sd
,
773 sim_event
*event_to_remove
)
775 sim_events
*events
= STATE_EVENTS (sd
);
776 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
777 if (event_to_remove
!= NULL
)
779 sim_event
**queue
= NULL
;
780 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
782 sim_event
**ptr_to_current
;
783 for (ptr_to_current
= queue
;
784 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
785 ptr_to_current
= &(*ptr_to_current
)->next
);
786 if (*ptr_to_current
== to_remove
)
788 sim_event
*dead
= *ptr_to_current
;
789 *ptr_to_current
= dead
->next
;
791 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
792 (long) sim_events_time (sd
),
793 (long) event_to_remove
,
794 (long) dead
->time_of_event
,
795 (long) dead
->handler
,
797 (dead
->trace
!= NULL
) ? ", " : "",
798 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
799 sim_events_free (sd
, dead
);
800 update_time_from_event (sd
);
801 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
807 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
808 (long) sim_events_time (sd
),
809 (long) event_to_remove
));
814 STATIC_INLINE_SIM_EVENTS\
816 sim_watch_valid (SIM_DESC sd
,
819 switch (to_do
->watching
)
822 #define WATCH_CORE(N,OP,EXT) \
824 unsigned_##N word = 0; \
825 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
826 to_do->core_addr, sizeof (word)); \
828 ok = (nr_read == sizeof (unsigned_##N) \
829 && (to_do->is_within \
830 == (word >= to_do->lb##EXT \
831 && word <= to_do->ub##EXT)));
833 case watch_core_targ_1
:
835 WATCH_CORE (1, T2H
,);
838 case watch_core_targ_2
:
840 WATCH_CORE (2, T2H
,);
843 case watch_core_targ_4
:
845 WATCH_CORE (4, T2H
,);
848 case watch_core_targ_8
:
850 WATCH_CORE (8, T2H
,64);
854 case watch_core_be_1
:
856 WATCH_CORE (1, BE2H
,);
859 case watch_core_be_2
:
861 WATCH_CORE (2, BE2H
,);
864 case watch_core_be_4
:
866 WATCH_CORE (4, BE2H
,);
869 case watch_core_be_8
:
871 WATCH_CORE (8, BE2H
,64);
875 case watch_core_le_1
:
877 WATCH_CORE (1, LE2H
,);
880 case watch_core_le_2
:
882 WATCH_CORE (2, LE2H
,);
885 case watch_core_le_4
:
887 WATCH_CORE (4, LE2H
,);
890 case watch_core_le_8
:
892 WATCH_CORE (8, LE2H
,64);
897 #define WATCH_SIM(N,OP,EXT) \
899 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
901 ok = (to_do->is_within \
902 == (word >= to_do->lb##EXT \
903 && word <= to_do->ub##EXT));
905 case watch_sim_host_1
:
907 WATCH_SIM (1, word
= ,);
910 case watch_sim_host_2
:
912 WATCH_SIM (2, word
= ,);
915 case watch_sim_host_4
:
917 WATCH_SIM (4, word
= ,);
920 case watch_sim_host_8
:
922 WATCH_SIM (8, word
= ,64);
928 WATCH_SIM (1, BE2H
,);
933 WATCH_SIM (2, BE2H
,);
938 WATCH_SIM (4, BE2H
,);
943 WATCH_SIM (8, BE2H
,64);
949 WATCH_SIM (1, LE2H
,);
954 WATCH_SIM (1, LE2H
,);
959 WATCH_SIM (1, LE2H
,);
964 WATCH_SIM (1, LE2H
,64);
969 case watch_clock
: /* wallclock */
971 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
972 return (elapsed_time
>= to_do
->wallclock
);
976 sim_io_error (sd
, "sim_watch_valid - bad switch");
986 sim_events_tick (SIM_DESC sd
)
988 sim_events
*events
= STATE_EVENTS (sd
);
990 /* this should only be called after the previous ticks have been
993 /* Advance the time but *only* if there is nothing to process */
994 if (events
->work_pending
995 || events
->time_from_event
== 0)
997 events
->nr_ticks_to_process
+= 1;
1002 events
->time_from_event
-= 1;
1010 sim_events_tickn (SIM_DESC sd
,
1013 sim_events
*events
= STATE_EVENTS (sd
);
1016 /* this should only be called after the previous ticks have been
1019 /* Advance the time but *only* if there is nothing to process */
1020 if (events
->work_pending
|| events
->time_from_event
< n
)
1022 events
->nr_ticks_to_process
+= n
;
1027 events
->time_from_event
-= n
;
1035 sim_events_slip (SIM_DESC sd
,
1038 sim_events
*events
= STATE_EVENTS (sd
);
1039 SIM_ASSERT (slip
> 0);
1041 /* Flag a ready event with work_pending instead of number of ticks
1042 to process so that the time continues to be correct */
1043 if (events
->time_from_event
< slip
)
1045 events
->work_pending
= 1;
1047 events
->time_from_event
-= slip
;
1053 sim_events_preprocess (SIM_DESC sd
,
1054 int events_were_last
,
1055 int events_were_next
)
1057 sim_events
*events
= STATE_EVENTS(sd
);
1058 if (events_were_last
)
1060 /* Halted part way through event processing */
1061 ASSERT (events
->nr_ticks_to_process
!= 0);
1062 /* The external world can't tell if the event that stopped the
1063 simulator was the last event to process. */
1064 ASSERT (events_were_next
);
1065 sim_events_process (sd
);
1067 else if (events_were_next
)
1069 /* Halted by the last processor */
1070 if (sim_events_tick (sd
))
1071 sim_events_process (sd
);
1078 sim_events_process (SIM_DESC sd
)
1080 sim_events
*events
= STATE_EVENTS(sd
);
1081 signed64 event_time
= sim_events_time(sd
);
1083 /* Clear work_pending before checking nr_held. Clearing
1084 work_pending after nr_held (with out a lock could loose an
1086 events
->work_pending
= 0;
1088 /* move any events that were asynchronously queued by any signal
1089 handlers onto the real event queue. */
1090 if (events
->nr_held
> 0)
1094 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1098 sigfillset(&new_mask
);
1099 sigprocmask(SIG_SETMASK
, &new_mask
, &old_mask
);
1102 for (i
= 0; i
< events
->nr_held
; i
++)
1104 sim_event
*entry
= &events
->held
[i
];
1105 sim_events_schedule (sd
,
1106 entry
->time_of_event
,
1110 events
->nr_held
= 0;
1112 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1114 sigprocmask(SIG_SETMASK
, &old_mask
, NULL
);
1119 /* Process any watchpoints. Be careful to allow a watchpoint to
1120 appear/disappear under our feet.
1121 To ensure that watchpoints are processed only once per cycle,
1122 they are moved onto a watched queue, this returned to the
1123 watchpoint queue when all queue processing has been
1125 while (events
->watchpoints
!= NULL
)
1127 sim_event
*to_do
= events
->watchpoints
;
1128 events
->watchpoints
= to_do
->next
;
1129 if (sim_watch_valid (sd
, to_do
))
1131 sim_event_handler
*handler
= to_do
->handler
;
1132 void *data
= to_do
->data
;
1134 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1139 (to_do
->trace
!= NULL
) ? ", " : "",
1140 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1141 sim_events_free (sd
, to_do
);
1146 to_do
->next
= events
->watchedpoints
;
1147 events
->watchedpoints
= to_do
;
1151 /* consume all events for this or earlier times. Be careful to
1152 allow an event to appear/disappear under our feet */
1153 while (events
->queue
->time_of_event
<
1154 (event_time
+ events
->nr_ticks_to_process
))
1156 sim_event
*to_do
= events
->queue
;
1157 sim_event_handler
*handler
= to_do
->handler
;
1158 void *data
= to_do
->data
;
1159 events
->queue
= to_do
->next
;
1160 update_time_from_event (sd
);
1162 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1167 (to_do
->trace
!= NULL
) ? ", " : "",
1168 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1169 sim_events_free (sd
, to_do
);
1173 /* put things back where they belong ready for the next iteration */
1174 events
->watchpoints
= events
->watchedpoints
;
1175 events
->watchedpoints
= NULL
;
1176 if (events
->watchpoints
!= NULL
)
1177 events
->work_pending
= 1;
1179 /* advance the time */
1180 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1181 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1182 events
->time_from_event
-= events
->nr_ticks_to_process
;
1184 /* this round of processing complete */
1185 events
->nr_ticks_to_process
= 0;