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;
398 SIM_ASSERT (current_time
== sim_events_time (sd
));
402 #if EXTERN_SIM_EVENTS_P
404 insert_sim_event (SIM_DESC sd
,
405 sim_event
*new_event
,
408 sim_events
*events
= STATE_EVENTS (sd
);
411 signed64 time_of_event
;
414 sim_io_error (sd
, "what is past is past!\n");
416 /* compute when the event should occure */
417 time_of_event
= sim_events_time (sd
) + delta
;
419 /* find the queue insertion point - things are time ordered */
420 prev
= &events
->queue
;
421 curr
= events
->queue
;
422 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
424 SIM_ASSERT (curr
->next
== NULL
425 || curr
->time_of_event
<= curr
->next
->time_of_event
);
429 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
432 new_event
->next
= curr
;
434 new_event
->time_of_event
= time_of_event
;
436 /* adjust the time until the first event */
437 update_time_from_event (sd
);
442 #if EXTERN_SIM_EVENTS_P
444 sim_events_schedule (SIM_DESC sd
,
446 sim_event_handler
*handler
,
450 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
456 #if EXTERN_SIM_EVENTS_P
458 sim_events_schedule_tracef (SIM_DESC sd
,
460 sim_event_handler
*handler
,
465 sim_event
*new_event
;
468 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
475 #if EXTERN_SIM_EVENTS_P
477 sim_events_schedule_vtracef (SIM_DESC sd
,
479 sim_event_handler
*handler
,
484 sim_event
*new_event
= sim_events_zalloc (sd
);
485 new_event
->data
= data
;
486 new_event
->handler
= handler
;
487 new_event
->watching
= watch_timer
;
488 if (fmt
== NULL
|| !ETRACE_P
|| vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
489 new_event
->trace
= NULL
;
490 insert_sim_event(sd
, new_event
, delta_time
);
492 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
493 (long)sim_events_time(sd
),
495 (long)new_event
->time_of_event
,
496 (long)new_event
->handler
,
497 (long)new_event
->data
,
498 (new_event
->trace
!= NULL
) ? ", " : "",
499 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
505 #if EXTERN_SIM_EVENTS_P
507 sim_events_schedule_after_signal (SIM_DESC sd
,
509 sim_event_handler
*handler
,
512 sim_events
*events
= STATE_EVENTS (sd
);
513 sim_event
*new_event
;
514 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
518 sigfillset(&new_mask
);
519 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
522 /* allocate an event entry from the signal buffer */
523 new_event
= &events
->held
[events
->nr_held
];
525 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
527 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
528 "sim_events_schedule_after_signal - buffer oveflow");
531 new_event
->data
= data
;
532 new_event
->handler
= handler
;
533 new_event
->time_of_event
= delta_time
; /* work it out later */
534 new_event
->next
= NULL
;
536 events
->work_pending
= 1; /* notify main process */
538 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
540 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
544 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
545 (long)sim_events_time(sd
),
547 (long)new_event
->time_of_event
,
548 (long)new_event
->handler
,
549 (long)new_event
->data
));
554 #if EXTERN_SIM_EVENTS_P
556 sim_events_watch_clock (SIM_DESC sd
,
557 unsigned delta_ms_time
,
558 sim_event_handler
*handler
,
561 sim_events
*events
= STATE_EVENTS (sd
);
562 sim_event
*new_event
= sim_events_zalloc (sd
);
564 new_event
->watching
= watch_clock
;
566 new_event
->data
= data
;
567 new_event
->handler
= handler
;
569 if (events
->resume_wallclock
== 0)
570 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
572 new_event
->wallclock
= (events
->elapsed_wallclock
573 + sim_elapsed_time_since (events
->resume_wallclock
)
576 new_event
->next
= events
->watchpoints
;
577 events
->watchpoints
= new_event
;
578 events
->work_pending
= 1;
580 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
581 (long)sim_events_time (sd
),
583 (long)new_event
->wallclock
,
584 (long)new_event
->handler
,
585 (long)new_event
->data
));
591 #if EXTERN_SIM_EVENTS_P
593 sim_events_watch_sim (SIM_DESC sd
,
600 sim_event_handler
*handler
,
603 sim_events
*events
= STATE_EVENTS (sd
);
604 sim_event
*new_event
= sim_events_zalloc (sd
);
611 case 1: new_event
->watching
= watch_sim_host_1
; break;
612 case 2: new_event
->watching
= watch_sim_host_2
; break;
613 case 4: new_event
->watching
= watch_sim_host_4
; break;
614 case 8: new_event
->watching
= watch_sim_host_8
; break;
615 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
621 case 1: new_event
->watching
= watch_sim_be_1
; break;
622 case 2: new_event
->watching
= watch_sim_be_2
; break;
623 case 4: new_event
->watching
= watch_sim_be_4
; break;
624 case 8: new_event
->watching
= watch_sim_be_8
; break;
625 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
631 case 1: new_event
->watching
= watch_sim_le_1
; break;
632 case 2: new_event
->watching
= watch_sim_le_2
; break;
633 case 4: new_event
->watching
= watch_sim_le_4
; break;
634 case 8: new_event
->watching
= watch_sim_le_8
; break;
635 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
639 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
642 new_event
->data
= data
;
643 new_event
->handler
= handler
;
645 new_event
->host_addr
= host_addr
;
647 new_event
->lb64
= lb
;
649 new_event
->ub64
= ub
;
650 new_event
->is_within
= (is_within
!= 0);
652 new_event
->next
= events
->watchpoints
;
653 events
->watchpoints
= new_event
;
654 events
->work_pending
= 1;
656 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
657 (long)sim_events_time (sd
),
659 (long)new_event
->host_addr
,
662 (long)new_event
->handler
,
663 (long)new_event
->data
));
669 #if EXTERN_SIM_EVENTS_P
671 sim_events_watch_core (SIM_DESC sd
,
672 address_word core_addr
,
679 sim_event_handler
*handler
,
682 sim_events
*events
= STATE_EVENTS (sd
);
683 sim_event
*new_event
= sim_events_zalloc (sd
);
690 case 1: new_event
->watching
= watch_core_targ_1
; break;
691 case 2: new_event
->watching
= watch_core_targ_2
; break;
692 case 4: new_event
->watching
= watch_core_targ_4
; break;
693 case 8: new_event
->watching
= watch_core_targ_8
; break;
694 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
700 case 1: new_event
->watching
= watch_core_be_1
; break;
701 case 2: new_event
->watching
= watch_core_be_2
; break;
702 case 4: new_event
->watching
= watch_core_be_4
; break;
703 case 8: new_event
->watching
= watch_core_be_8
; break;
704 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
710 case 1: new_event
->watching
= watch_core_le_1
; break;
711 case 2: new_event
->watching
= watch_core_le_2
; break;
712 case 4: new_event
->watching
= watch_core_le_4
; break;
713 case 8: new_event
->watching
= watch_core_le_8
; break;
714 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
718 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
721 new_event
->data
= data
;
722 new_event
->handler
= handler
;
724 new_event
->core_addr
= core_addr
;
725 new_event
->core_map
= core_map
;
727 new_event
->lb64
= lb
;
729 new_event
->ub64
= ub
;
730 new_event
->is_within
= (is_within
!= 0);
732 new_event
->next
= events
->watchpoints
;
733 events
->watchpoints
= new_event
;
734 events
->work_pending
= 1;
736 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
737 (long)sim_events_time (sd
),
739 (long)new_event
->host_addr
,
742 (long)new_event
->handler
,
743 (long)new_event
->data
));
749 #if EXTERN_SIM_EVENTS_P
751 sim_events_deschedule (SIM_DESC sd
,
752 sim_event
*event_to_remove
)
754 sim_events
*events
= STATE_EVENTS (sd
);
755 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
756 if (event_to_remove
!= NULL
)
758 sim_event
**queue
= NULL
;
759 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
761 sim_event
**ptr_to_current
;
762 for (ptr_to_current
= queue
;
763 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
764 ptr_to_current
= &(*ptr_to_current
)->next
);
765 if (*ptr_to_current
== to_remove
)
767 sim_event
*dead
= *ptr_to_current
;
768 *ptr_to_current
= dead
->next
;
770 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
771 (long) sim_events_time (sd
),
772 (long) event_to_remove
,
773 (long) dead
->time_of_event
,
774 (long) dead
->handler
,
776 (dead
->trace
!= NULL
) ? ", " : "",
777 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
778 sim_events_free (sd
, dead
);
779 update_time_from_event (sd
);
780 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
786 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
787 (long) sim_events_time (sd
),
788 (long) event_to_remove
));
793 STATIC_INLINE_SIM_EVENTS\
795 sim_watch_valid (SIM_DESC sd
,
798 switch (to_do
->watching
)
801 #define WATCH_CORE(N,OP,EXT) \
803 unsigned_##N word = 0; \
804 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
805 to_do->core_addr, sizeof (word)); \
807 ok = (nr_read == sizeof (unsigned_##N) \
808 && (to_do->is_within \
809 == (word >= to_do->lb##EXT \
810 && word <= to_do->ub##EXT)));
812 case watch_core_targ_1
:
814 WATCH_CORE (1, T2H
,);
817 case watch_core_targ_2
:
819 WATCH_CORE (2, T2H
,);
822 case watch_core_targ_4
:
824 WATCH_CORE (4, T2H
,);
827 case watch_core_targ_8
:
829 WATCH_CORE (8, T2H
,64);
833 case watch_core_be_1
:
835 WATCH_CORE (1, BE2H
,);
838 case watch_core_be_2
:
840 WATCH_CORE (2, BE2H
,);
843 case watch_core_be_4
:
845 WATCH_CORE (4, BE2H
,);
848 case watch_core_be_8
:
850 WATCH_CORE (8, BE2H
,64);
854 case watch_core_le_1
:
856 WATCH_CORE (1, LE2H
,);
859 case watch_core_le_2
:
861 WATCH_CORE (2, LE2H
,);
864 case watch_core_le_4
:
866 WATCH_CORE (4, LE2H
,);
869 case watch_core_le_8
:
871 WATCH_CORE (8, LE2H
,64);
876 #define WATCH_SIM(N,OP,EXT) \
878 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
880 ok = (to_do->is_within \
881 == (word >= to_do->lb##EXT \
882 && word <= to_do->ub##EXT));
884 case watch_sim_host_1
:
886 WATCH_SIM (1, word
= ,);
889 case watch_sim_host_2
:
891 WATCH_SIM (2, word
= ,);
894 case watch_sim_host_4
:
896 WATCH_SIM (4, word
= ,);
899 case watch_sim_host_8
:
901 WATCH_SIM (8, word
= ,64);
907 WATCH_SIM (1, BE2H
,);
912 WATCH_SIM (2, BE2H
,);
917 WATCH_SIM (4, BE2H
,);
922 WATCH_SIM (8, BE2H
,64);
928 WATCH_SIM (1, LE2H
,);
933 WATCH_SIM (1, LE2H
,);
938 WATCH_SIM (1, LE2H
,);
943 WATCH_SIM (1, LE2H
,64);
948 case watch_clock
: /* wallclock */
950 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
951 return (elapsed_time
>= to_do
->wallclock
);
955 sim_io_error (sd
, "sim_watch_valid - bad switch");
965 sim_events_tick (SIM_DESC sd
)
967 sim_events
*events
= STATE_EVENTS (sd
);
969 /* this should only be called after the previous ticks have been
972 /* Advance the time but *only* if there is nothing to process */
973 if (events
->work_pending
974 || events
->time_from_event
== 0)
976 events
->nr_ticks_to_process
+= 1;
981 events
->time_from_event
-= 1;
989 sim_events_tickn (SIM_DESC sd
,
992 sim_events
*events
= STATE_EVENTS (sd
);
995 /* this should only be called after the previous ticks have been
998 /* Advance the time but *only* if there is nothing to process */
999 if (events
->work_pending
|| events
->time_from_event
< n
)
1001 events
->nr_ticks_to_process
+= n
;
1006 events
->time_from_event
-= n
;
1014 sim_events_slip (SIM_DESC sd
,
1017 sim_events
*events
= STATE_EVENTS (sd
);
1018 SIM_ASSERT (slip
> 0);
1020 /* Flag a ready event with work_pending instead of number of ticks
1021 to process so that the time continues to be correct */
1022 if (events
->time_from_event
< slip
)
1024 events
->work_pending
= 1;
1026 events
->time_from_event
-= slip
;
1032 sim_events_preprocess (SIM_DESC sd
,
1033 int events_were_last
,
1034 int events_were_next
)
1036 sim_events
*events
= STATE_EVENTS(sd
);
1037 if (events_were_last
)
1039 /* Halted part way through event processing */
1040 ASSERT (events
->nr_ticks_to_process
!= 0);
1041 /* The external world can't tell if the event that stopped the
1042 simulator was the last event to process. */
1043 ASSERT (events_were_next
);
1044 sim_events_process (sd
);
1046 else if (events_were_next
)
1048 /* Halted by the last processor */
1049 if (sim_events_tick (sd
))
1050 sim_events_process (sd
);
1057 sim_events_process (SIM_DESC sd
)
1059 sim_events
*events
= STATE_EVENTS(sd
);
1060 signed64 event_time
= sim_events_time(sd
);
1062 /* Clear work_pending before checking nr_held. Clearing
1063 work_pending after nr_held (with out a lock could loose an
1065 events
->work_pending
= 0;
1067 /* move any events that were asynchronously queued by any signal
1068 handlers onto the real event queue. */
1069 if (events
->nr_held
> 0)
1073 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1077 sigfillset(&new_mask
);
1078 sigprocmask(SIG_SETMASK
, &new_mask
, &old_mask
);
1081 for (i
= 0; i
< events
->nr_held
; i
++)
1083 sim_event
*entry
= &events
->held
[i
];
1084 sim_events_schedule (sd
,
1085 entry
->time_of_event
,
1089 events
->nr_held
= 0;
1091 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1093 sigprocmask(SIG_SETMASK
, &old_mask
, NULL
);
1098 /* Process any watchpoints. Be careful to allow a watchpoint to
1099 appear/disappear under our feet.
1100 To ensure that watchpoints are processed only once per cycle,
1101 they are moved onto a watched queue, this returned to the
1102 watchpoint queue when all queue processing has been
1104 while (events
->watchpoints
!= NULL
)
1106 sim_event
*to_do
= events
->watchpoints
;
1107 events
->watchpoints
= to_do
->next
;
1108 if (sim_watch_valid (sd
, to_do
))
1110 sim_event_handler
*handler
= to_do
->handler
;
1111 void *data
= to_do
->data
;
1113 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1118 (to_do
->trace
!= NULL
) ? ", " : "",
1119 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1120 sim_events_free (sd
, to_do
);
1125 to_do
->next
= events
->watchedpoints
;
1126 events
->watchedpoints
= to_do
;
1130 /* consume all events for this or earlier times. Be careful to
1131 allow an event to appear/disappear under our feet */
1132 while (events
->queue
->time_of_event
<
1133 (event_time
+ events
->nr_ticks_to_process
))
1135 sim_event
*to_do
= events
->queue
;
1136 sim_event_handler
*handler
= to_do
->handler
;
1137 void *data
= to_do
->data
;
1138 events
->queue
= to_do
->next
;
1139 update_time_from_event (sd
);
1141 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1146 (to_do
->trace
!= NULL
) ? ", " : "",
1147 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1148 sim_events_free (sd
, to_do
);
1152 /* put things back where they belong ready for the next iteration */
1153 events
->watchpoints
= events
->watchedpoints
;
1154 events
->watchedpoints
= NULL
;
1155 if (events
->watchpoints
!= NULL
)
1156 events
->work_pending
= 1;
1158 /* advance the time */
1159 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1160 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1161 events
->time_from_event
-= events
->nr_ticks_to_process
;
1163 /* this round of processing complete */
1164 events
->nr_ticks_to_process
= 0;