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 occur. 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 /* Returns the time that remains before the event is raised. */
385 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
390 return (event
->time_of_event
- sim_events_time (sd
));
395 STATIC_INLINE_SIM_EVENTS\
397 update_time_from_event (SIM_DESC sd
)
399 sim_events
*events
= STATE_EVENTS (sd
);
400 signed64 current_time
= sim_events_time (sd
);
401 if (events
->queue
!= NULL
)
403 events
->time_of_event
= events
->queue
->time_of_event
;
404 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
408 events
->time_of_event
= current_time
- 1;
409 events
->time_from_event
= -1;
415 for (event
= events
->queue
, i
= 0;
417 event
= event
->next
, i
++)
420 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
422 (long)events
->time_from_event
,
425 (long)event
->time_of_event
,
426 (long)event
->handler
,
428 (event
->trace
!= NULL
) ? ", " : "",
429 (event
->trace
!= NULL
) ? event
->trace
: ""));
432 SIM_ASSERT (current_time
== sim_events_time (sd
));
436 #if EXTERN_SIM_EVENTS_P
438 insert_sim_event (SIM_DESC sd
,
439 sim_event
*new_event
,
442 sim_events
*events
= STATE_EVENTS (sd
);
445 signed64 time_of_event
;
448 sim_io_error (sd
, "what is past is past!\n");
450 /* compute when the event should occur */
451 time_of_event
= sim_events_time (sd
) + delta
;
453 /* find the queue insertion point - things are time ordered */
454 prev
= &events
->queue
;
455 curr
= events
->queue
;
456 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
458 SIM_ASSERT (curr
->next
== NULL
459 || curr
->time_of_event
<= curr
->next
->time_of_event
);
463 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
466 new_event
->next
= curr
;
468 new_event
->time_of_event
= time_of_event
;
470 /* adjust the time until the first event */
471 update_time_from_event (sd
);
476 #if EXTERN_SIM_EVENTS_P
478 sim_events_schedule (SIM_DESC sd
,
480 sim_event_handler
*handler
,
484 memset (&dummy
, 0, sizeof dummy
);
485 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
491 #if EXTERN_SIM_EVENTS_P
493 sim_events_schedule_tracef (SIM_DESC sd
,
495 sim_event_handler
*handler
,
500 sim_event
*new_event
;
503 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
510 #if EXTERN_SIM_EVENTS_P
512 sim_events_schedule_vtracef (SIM_DESC sd
,
514 sim_event_handler
*handler
,
519 sim_event
*new_event
= sim_events_zalloc (sd
);
520 new_event
->data
= data
;
521 new_event
->handler
= handler
;
522 new_event
->watching
= watch_timer
;
523 if (fmt
== NULL
|| !ETRACE_P
|| vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
524 new_event
->trace
= NULL
;
525 insert_sim_event(sd
, new_event
, delta_time
);
527 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
528 (long)sim_events_time(sd
),
530 (long)new_event
->time_of_event
,
531 (long)new_event
->handler
,
532 (long)new_event
->data
,
533 (new_event
->trace
!= NULL
) ? ", " : "",
534 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
540 #if EXTERN_SIM_EVENTS_P
542 sim_events_schedule_after_signal (SIM_DESC sd
,
544 sim_event_handler
*handler
,
547 sim_events
*events
= STATE_EVENTS (sd
);
548 sim_event
*new_event
;
549 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
553 sigfillset(&new_mask
);
554 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
557 /* allocate an event entry from the signal buffer */
558 new_event
= &events
->held
[events
->nr_held
];
560 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
562 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
563 "sim_events_schedule_after_signal - buffer oveflow");
566 new_event
->data
= data
;
567 new_event
->handler
= handler
;
568 new_event
->time_of_event
= delta_time
; /* work it out later */
569 new_event
->next
= NULL
;
571 events
->work_pending
= 1; /* notify main process */
573 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
575 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
579 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
580 (long)sim_events_time(sd
),
582 (long)new_event
->time_of_event
,
583 (long)new_event
->handler
,
584 (long)new_event
->data
));
589 #if EXTERN_SIM_EVENTS_P
591 sim_events_watch_clock (SIM_DESC sd
,
592 unsigned delta_ms_time
,
593 sim_event_handler
*handler
,
596 sim_events
*events
= STATE_EVENTS (sd
);
597 sim_event
*new_event
= sim_events_zalloc (sd
);
599 new_event
->watching
= watch_clock
;
601 new_event
->data
= data
;
602 new_event
->handler
= handler
;
604 if (events
->resume_wallclock
== 0)
605 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
607 new_event
->wallclock
= (events
->elapsed_wallclock
608 + sim_elapsed_time_since (events
->resume_wallclock
)
611 new_event
->next
= events
->watchpoints
;
612 events
->watchpoints
= new_event
;
613 events
->work_pending
= 1;
615 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
616 (long)sim_events_time (sd
),
618 (long)new_event
->wallclock
,
619 (long)new_event
->handler
,
620 (long)new_event
->data
));
626 #if EXTERN_SIM_EVENTS_P
628 sim_events_watch_sim (SIM_DESC sd
,
635 sim_event_handler
*handler
,
638 sim_events
*events
= STATE_EVENTS (sd
);
639 sim_event
*new_event
= sim_events_zalloc (sd
);
646 case 1: new_event
->watching
= watch_sim_host_1
; break;
647 case 2: new_event
->watching
= watch_sim_host_2
; break;
648 case 4: new_event
->watching
= watch_sim_host_4
; break;
649 case 8: new_event
->watching
= watch_sim_host_8
; break;
650 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
656 case 1: new_event
->watching
= watch_sim_be_1
; break;
657 case 2: new_event
->watching
= watch_sim_be_2
; break;
658 case 4: new_event
->watching
= watch_sim_be_4
; break;
659 case 8: new_event
->watching
= watch_sim_be_8
; break;
660 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
666 case 1: new_event
->watching
= watch_sim_le_1
; break;
667 case 2: new_event
->watching
= watch_sim_le_2
; break;
668 case 4: new_event
->watching
= watch_sim_le_4
; break;
669 case 8: new_event
->watching
= watch_sim_le_8
; break;
670 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
674 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
677 new_event
->data
= data
;
678 new_event
->handler
= handler
;
680 new_event
->host_addr
= host_addr
;
682 new_event
->lb64
= lb
;
684 new_event
->ub64
= ub
;
685 new_event
->is_within
= (is_within
!= 0);
687 new_event
->next
= events
->watchpoints
;
688 events
->watchpoints
= new_event
;
689 events
->work_pending
= 1;
691 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
692 (long)sim_events_time (sd
),
694 (long)new_event
->host_addr
,
697 (long)new_event
->handler
,
698 (long)new_event
->data
));
704 #if EXTERN_SIM_EVENTS_P
706 sim_events_watch_core (SIM_DESC sd
,
707 address_word core_addr
,
714 sim_event_handler
*handler
,
717 sim_events
*events
= STATE_EVENTS (sd
);
718 sim_event
*new_event
= sim_events_zalloc (sd
);
725 case 1: new_event
->watching
= watch_core_targ_1
; break;
726 case 2: new_event
->watching
= watch_core_targ_2
; break;
727 case 4: new_event
->watching
= watch_core_targ_4
; break;
728 case 8: new_event
->watching
= watch_core_targ_8
; break;
729 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
735 case 1: new_event
->watching
= watch_core_be_1
; break;
736 case 2: new_event
->watching
= watch_core_be_2
; break;
737 case 4: new_event
->watching
= watch_core_be_4
; break;
738 case 8: new_event
->watching
= watch_core_be_8
; break;
739 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
745 case 1: new_event
->watching
= watch_core_le_1
; break;
746 case 2: new_event
->watching
= watch_core_le_2
; break;
747 case 4: new_event
->watching
= watch_core_le_4
; break;
748 case 8: new_event
->watching
= watch_core_le_8
; break;
749 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
753 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
756 new_event
->data
= data
;
757 new_event
->handler
= handler
;
759 new_event
->core_addr
= core_addr
;
760 new_event
->core_map
= core_map
;
762 new_event
->lb64
= lb
;
764 new_event
->ub64
= ub
;
765 new_event
->is_within
= (is_within
!= 0);
767 new_event
->next
= events
->watchpoints
;
768 events
->watchpoints
= new_event
;
769 events
->work_pending
= 1;
771 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
772 (long)sim_events_time (sd
),
774 (long)new_event
->host_addr
,
777 (long)new_event
->handler
,
778 (long)new_event
->data
));
784 #if EXTERN_SIM_EVENTS_P
786 sim_events_deschedule (SIM_DESC sd
,
787 sim_event
*event_to_remove
)
789 sim_events
*events
= STATE_EVENTS (sd
);
790 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
791 if (event_to_remove
!= NULL
)
793 sim_event
**queue
= NULL
;
794 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
796 sim_event
**ptr_to_current
;
797 for (ptr_to_current
= queue
;
798 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
799 ptr_to_current
= &(*ptr_to_current
)->next
);
800 if (*ptr_to_current
== to_remove
)
802 sim_event
*dead
= *ptr_to_current
;
803 *ptr_to_current
= dead
->next
;
805 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
806 (long) sim_events_time (sd
),
807 (long) event_to_remove
,
808 (long) dead
->time_of_event
,
809 (long) dead
->handler
,
811 (dead
->trace
!= NULL
) ? ", " : "",
812 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
813 sim_events_free (sd
, dead
);
814 update_time_from_event (sd
);
815 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
821 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
822 (long) sim_events_time (sd
),
823 (long) event_to_remove
));
828 STATIC_INLINE_SIM_EVENTS\
830 sim_watch_valid (SIM_DESC sd
,
833 switch (to_do
->watching
)
836 #define WATCH_CORE(N,OP,EXT) \
838 unsigned_##N word = 0; \
839 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
840 to_do->core_addr, sizeof (word)); \
842 ok = (nr_read == sizeof (unsigned_##N) \
843 && (to_do->is_within \
844 == (word >= to_do->lb##EXT \
845 && word <= to_do->ub##EXT)));
847 case watch_core_targ_1
:
849 WATCH_CORE (1, T2H
,);
852 case watch_core_targ_2
:
854 WATCH_CORE (2, T2H
,);
857 case watch_core_targ_4
:
859 WATCH_CORE (4, T2H
,);
862 case watch_core_targ_8
:
864 WATCH_CORE (8, T2H
,64);
868 case watch_core_be_1
:
870 WATCH_CORE (1, BE2H
,);
873 case watch_core_be_2
:
875 WATCH_CORE (2, BE2H
,);
878 case watch_core_be_4
:
880 WATCH_CORE (4, BE2H
,);
883 case watch_core_be_8
:
885 WATCH_CORE (8, BE2H
,64);
889 case watch_core_le_1
:
891 WATCH_CORE (1, LE2H
,);
894 case watch_core_le_2
:
896 WATCH_CORE (2, LE2H
,);
899 case watch_core_le_4
:
901 WATCH_CORE (4, LE2H
,);
904 case watch_core_le_8
:
906 WATCH_CORE (8, LE2H
,64);
911 #define WATCH_SIM(N,OP,EXT) \
913 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
915 ok = (to_do->is_within \
916 == (word >= to_do->lb##EXT \
917 && word <= to_do->ub##EXT));
919 case watch_sim_host_1
:
921 WATCH_SIM (1, word
= ,);
924 case watch_sim_host_2
:
926 WATCH_SIM (2, word
= ,);
929 case watch_sim_host_4
:
931 WATCH_SIM (4, word
= ,);
934 case watch_sim_host_8
:
936 WATCH_SIM (8, word
= ,64);
942 WATCH_SIM (1, BE2H
,);
947 WATCH_SIM (2, BE2H
,);
952 WATCH_SIM (4, BE2H
,);
957 WATCH_SIM (8, BE2H
,64);
963 WATCH_SIM (1, LE2H
,);
968 WATCH_SIM (1, LE2H
,);
973 WATCH_SIM (1, LE2H
,);
978 WATCH_SIM (1, LE2H
,64);
983 case watch_clock
: /* wallclock */
985 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
986 return (elapsed_time
>= to_do
->wallclock
);
990 sim_io_error (sd
, "sim_watch_valid - bad switch");
1000 sim_events_tick (SIM_DESC sd
)
1002 sim_events
*events
= STATE_EVENTS (sd
);
1004 /* this should only be called after the previous ticks have been
1007 /* Advance the time but *only* if there is nothing to process */
1008 if (events
->work_pending
1009 || events
->time_from_event
== 0)
1011 events
->nr_ticks_to_process
+= 1;
1016 events
->time_from_event
-= 1;
1024 sim_events_tickn (SIM_DESC sd
,
1027 sim_events
*events
= STATE_EVENTS (sd
);
1030 /* this should only be called after the previous ticks have been
1033 /* Advance the time but *only* if there is nothing to process */
1034 if (events
->work_pending
|| events
->time_from_event
< n
)
1036 events
->nr_ticks_to_process
+= n
;
1041 events
->time_from_event
-= n
;
1049 sim_events_slip (SIM_DESC sd
,
1052 sim_events
*events
= STATE_EVENTS (sd
);
1053 SIM_ASSERT (slip
> 0);
1055 /* Flag a ready event with work_pending instead of number of ticks
1056 to process so that the time continues to be correct */
1057 if (events
->time_from_event
< slip
)
1059 events
->work_pending
= 1;
1061 events
->time_from_event
-= slip
;
1067 sim_events_preprocess (SIM_DESC sd
,
1068 int events_were_last
,
1069 int events_were_next
)
1071 sim_events
*events
= STATE_EVENTS(sd
);
1072 if (events_were_last
)
1074 /* Halted part way through event processing */
1075 ASSERT (events
->nr_ticks_to_process
!= 0);
1076 /* The external world can't tell if the event that stopped the
1077 simulator was the last event to process. */
1078 ASSERT (events_were_next
);
1079 sim_events_process (sd
);
1081 else if (events_were_next
)
1083 /* Halted by the last processor */
1084 if (sim_events_tick (sd
))
1085 sim_events_process (sd
);
1092 sim_events_process (SIM_DESC sd
)
1094 sim_events
*events
= STATE_EVENTS(sd
);
1095 signed64 event_time
= sim_events_time(sd
);
1097 /* Clear work_pending before checking nr_held. Clearing
1098 work_pending after nr_held (with out a lock could loose an
1100 events
->work_pending
= 0;
1102 /* move any events that were asynchronously queued by any signal
1103 handlers onto the real event queue. */
1104 if (events
->nr_held
> 0)
1108 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1112 sigfillset(&new_mask
);
1113 sigprocmask(SIG_SETMASK
, &new_mask
, &old_mask
);
1116 for (i
= 0; i
< events
->nr_held
; i
++)
1118 sim_event
*entry
= &events
->held
[i
];
1119 sim_events_schedule (sd
,
1120 entry
->time_of_event
,
1124 events
->nr_held
= 0;
1126 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1128 sigprocmask(SIG_SETMASK
, &old_mask
, NULL
);
1133 /* Process any watchpoints. Be careful to allow a watchpoint to
1134 appear/disappear under our feet.
1135 To ensure that watchpoints are processed only once per cycle,
1136 they are moved onto a watched queue, this returned to the
1137 watchpoint queue when all queue processing has been
1139 while (events
->watchpoints
!= NULL
)
1141 sim_event
*to_do
= events
->watchpoints
;
1142 events
->watchpoints
= to_do
->next
;
1143 if (sim_watch_valid (sd
, to_do
))
1145 sim_event_handler
*handler
= to_do
->handler
;
1146 void *data
= to_do
->data
;
1148 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1153 (to_do
->trace
!= NULL
) ? ", " : "",
1154 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1155 sim_events_free (sd
, to_do
);
1160 to_do
->next
= events
->watchedpoints
;
1161 events
->watchedpoints
= to_do
;
1165 /* consume all events for this or earlier times. Be careful to
1166 allow an event to appear/disappear under our feet */
1167 while (events
->queue
->time_of_event
<
1168 (event_time
+ events
->nr_ticks_to_process
))
1170 sim_event
*to_do
= events
->queue
;
1171 sim_event_handler
*handler
= to_do
->handler
;
1172 void *data
= to_do
->data
;
1173 events
->queue
= to_do
->next
;
1174 update_time_from_event (sd
);
1176 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1181 (to_do
->trace
!= NULL
) ? ", " : "",
1182 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1183 sim_events_free (sd
, to_do
);
1187 /* put things back where they belong ready for the next iteration */
1188 events
->watchpoints
= events
->watchedpoints
;
1189 events
->watchedpoints
= NULL
;
1190 if (events
->watchpoints
!= NULL
)
1191 events
->work_pending
= 1;
1193 /* advance the time */
1194 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1195 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1196 events
->time_from_event
-= events
->nr_ticks_to_process
;
1198 /* this round of processing complete */
1199 events
->nr_ticks_to_process
= 0;