1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2021 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"
28 #include "libiberty.h"
32 #include <signal.h> /* For SIGPROCMASK et al. */
37 /* core - target byte order */
42 /* core - big-endian */
47 /* core - little-endian */
53 /* sim - host byte order */
58 /* sim - big-endian */
63 /* sim - little-endian */
74 } sim_event_watchpoints
;
78 sim_event_watchpoints watching
;
80 sim_event_handler
*handler
;
82 signed64 time_of_event
;
83 /* watch wallclock event */
85 /* watch core address */
86 address_word core_addr
;
90 /* watch core/sim range */
91 int is_within
; /* 0/1 */
96 /* trace info (if any) */
103 /* The event queue maintains a single absolute time using two
106 TIME_OF_EVENT: this holds the time at which the next event is ment
107 to occur. If no next event it will hold the time of the last
110 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
111 <= 0 (except when poll-event is being processed) indicates that
112 event processing is due. This variable is decremented once for
113 each iteration of a clock cycle.
115 Initially, the clock is started at time one (0) with TIME_OF_EVENT
116 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
118 Clearly there is a bug in that this code assumes that the absolute
119 time counter will never become greater than 2^62.
121 To avoid the need to use 64bit arithmetic, the event queue always
122 contains at least one event scheduled every 16 000 ticks. This
123 limits the time from event counter to values less than
127 #if !defined (SIM_EVENTS_POLL_RATE)
128 #define SIM_EVENTS_POLL_RATE 0x1000
132 #define _ETRACE sd, NULL
135 #define ETRACE(ARGS) \
138 if (STRACE_EVENTS_P (sd)) \
140 if (STRACE_DEBUG_P (sd)) \
141 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
148 /* event queue iterator - don't iterate over the held queue. */
150 #if EXTERN_SIM_EVENTS_P
152 next_event_queue (SIM_DESC sd
,
156 return &STATE_EVENTS (sd
)->queue
;
157 else if (queue
== &STATE_EVENTS (sd
)->queue
)
158 return &STATE_EVENTS (sd
)->watchpoints
;
159 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
160 return &STATE_EVENTS (sd
)->watchedpoints
;
161 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
164 sim_io_error (sd
, "next_event_queue - bad queue");
170 STATIC_INLINE_SIM_EVENTS\
172 sim_events_poll (SIM_DESC sd
,
175 /* just re-schedule in 1000 million ticks time */
176 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
177 sim_io_poll_quit (sd
);
181 /* "events" module install handler.
182 This is called via sim_module_install to install the "events" subsystem
183 into the simulator. */
185 #if EXTERN_SIM_EVENTS_P
186 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
187 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
188 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
189 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
192 #if EXTERN_SIM_EVENTS_P
194 sim_events_install (SIM_DESC sd
)
196 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
197 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
198 sim_module_add_init_fn (sd
, sim_events_init
);
199 sim_module_add_resume_fn (sd
, sim_events_resume
);
200 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
206 /* Suspend/resume the event queue manager when the simulator is not
209 #if EXTERN_SIM_EVENTS_P
211 sim_events_resume (SIM_DESC sd
)
213 sim_events
*events
= STATE_EVENTS (sd
);
214 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
215 SIM_ASSERT (events
->resume_wallclock
== 0);
216 events
->resume_wallclock
= sim_elapsed_time_get ();
221 #if EXTERN_SIM_EVENTS_P
223 sim_events_suspend (SIM_DESC sd
)
225 sim_events
*events
= STATE_EVENTS (sd
);
226 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
227 SIM_ASSERT (events
->resume_wallclock
!= 0);
228 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
229 events
->resume_wallclock
= 0;
235 /* Uninstall the "events" subsystem from the simulator. */
237 #if EXTERN_SIM_EVENTS_P
239 sim_events_uninstall (SIM_DESC sd
)
241 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
242 /* FIXME: free buffers, etc. */
249 #if EXTERN_SIM_EVENTS_P
251 sim_events_zalloc (SIM_DESC sd
)
253 sim_events
*events
= STATE_EVENTS (sd
);
254 sim_event
*new = events
->free_list
;
257 events
->free_list
= new->next
;
258 memset (new, 0, sizeof (*new));
262 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
266 sigfillset (&new_mask
);
267 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
269 new = ZALLOC (sim_event
);
270 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
272 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
279 STATIC_INLINE_SIM_EVENTS\
281 sim_events_free (SIM_DESC sd
,
284 sim_events
*events
= STATE_EVENTS (sd
);
285 dead
->next
= events
->free_list
;
286 events
->free_list
= dead
;
287 if (dead
->trace
!= NULL
)
289 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
295 /* Initialize the simulator event manager */
297 #if EXTERN_SIM_EVENTS_P
299 sim_events_init (SIM_DESC sd
)
301 sim_events
*events
= STATE_EVENTS (sd
);
303 /* drain the interrupt queue */
305 if (events
->held
== NULL
)
306 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
308 /* drain the normal queues */
310 sim_event
**queue
= NULL
;
311 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
313 if (queue
== NULL
) break;
314 while (*queue
!= NULL
)
316 sim_event
*dead
= *queue
;
318 sim_events_free (sd
, dead
);
324 /* wind time back to zero */
325 events
->nr_ticks_to_process
= 1; /* start by doing queue */
326 events
->time_of_event
= 0;
327 events
->time_from_event
= 0;
328 events
->elapsed_wallclock
= 0;
329 events
->resume_wallclock
= 0;
331 /* schedule our initial counter event */
332 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
334 /* from now on, except when the large-int event is being processed
335 the event queue is non empty */
336 SIM_ASSERT (events
->queue
!= NULL
);
345 sim_events_time (SIM_DESC sd
)
347 sim_events
*events
= STATE_EVENTS (sd
);
348 return (events
->time_of_event
- events
->time_from_event
);
354 sim_events_elapsed_time (SIM_DESC sd
)
356 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
358 /* Are we being called inside sim_resume?
359 (Is there a simulation in progress?) */
360 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
361 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
367 /* Returns the time that remains before the event is raised. */
370 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
375 return (event
->time_of_event
- sim_events_time (sd
));
380 STATIC_INLINE_SIM_EVENTS\
382 update_time_from_event (SIM_DESC sd
)
384 sim_events
*events
= STATE_EVENTS (sd
);
385 signed64 current_time
= sim_events_time (sd
);
386 if (events
->queue
!= NULL
)
388 events
->time_of_event
= events
->queue
->time_of_event
;
389 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
393 events
->time_of_event
= current_time
- 1;
394 events
->time_from_event
= -1;
396 if (STRACE_EVENTS_P (sd
))
400 for (event
= events
->queue
, i
= 0;
402 event
= event
->next
, i
++)
405 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
407 (long)events
->time_from_event
,
410 (long)event
->time_of_event
,
411 (long)event
->handler
,
413 (event
->trace
!= NULL
) ? ", " : "",
414 (event
->trace
!= NULL
) ? event
->trace
: ""));
417 SIM_ASSERT (current_time
== sim_events_time (sd
));
421 #if EXTERN_SIM_EVENTS_P
423 insert_sim_event (SIM_DESC sd
,
424 sim_event
*new_event
,
427 sim_events
*events
= STATE_EVENTS (sd
);
430 signed64 time_of_event
;
433 sim_io_error (sd
, "what is past is past!\n");
435 /* compute when the event should occur */
436 time_of_event
= sim_events_time (sd
) + delta
;
438 /* find the queue insertion point - things are time ordered */
439 prev
= &events
->queue
;
440 curr
= events
->queue
;
441 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
443 SIM_ASSERT (curr
->next
== NULL
444 || curr
->time_of_event
<= curr
->next
->time_of_event
);
448 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
451 new_event
->next
= curr
;
453 new_event
->time_of_event
= time_of_event
;
455 /* adjust the time until the first event */
456 update_time_from_event (sd
);
461 #if EXTERN_SIM_EVENTS_P
463 sim_events_schedule (SIM_DESC sd
,
465 sim_event_handler
*handler
,
469 memset (&dummy
, 0, sizeof dummy
);
470 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
476 #if EXTERN_SIM_EVENTS_P
478 sim_events_schedule_tracef (SIM_DESC sd
,
480 sim_event_handler
*handler
,
485 sim_event
*new_event
;
488 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
495 #if EXTERN_SIM_EVENTS_P
497 sim_events_schedule_vtracef (SIM_DESC sd
,
499 sim_event_handler
*handler
,
504 sim_event
*new_event
= sim_events_zalloc (sd
);
505 new_event
->data
= data
;
506 new_event
->handler
= handler
;
507 new_event
->watching
= watch_timer
;
508 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
509 new_event
->trace
= NULL
;
510 insert_sim_event (sd
, new_event
, delta_time
);
512 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
513 (long)sim_events_time (sd
),
515 (long)new_event
->time_of_event
,
516 (long)new_event
->handler
,
517 (long)new_event
->data
,
518 (new_event
->trace
!= NULL
) ? ", " : "",
519 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
525 #if EXTERN_SIM_EVENTS_P
527 sim_events_schedule_after_signal (SIM_DESC sd
,
529 sim_event_handler
*handler
,
532 sim_events
*events
= STATE_EVENTS (sd
);
533 sim_event
*new_event
;
534 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
538 sigfillset (&new_mask
);
539 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
542 /* allocate an event entry from the signal buffer */
543 new_event
= &events
->held
[events
->nr_held
];
545 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
547 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
548 "sim_events_schedule_after_signal - buffer overflow");
551 new_event
->data
= data
;
552 new_event
->handler
= handler
;
553 new_event
->time_of_event
= delta_time
; /* work it out later */
554 new_event
->next
= NULL
;
556 events
->work_pending
= 1; /* notify main process */
558 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
560 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
564 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
565 (long)sim_events_time (sd
),
567 (long)new_event
->time_of_event
,
568 (long)new_event
->handler
,
569 (long)new_event
->data
));
574 #if EXTERN_SIM_EVENTS_P
576 sim_events_watch_clock (SIM_DESC sd
,
577 unsigned delta_ms_time
,
578 sim_event_handler
*handler
,
581 sim_events
*events
= STATE_EVENTS (sd
);
582 sim_event
*new_event
= sim_events_zalloc (sd
);
584 new_event
->watching
= watch_clock
;
586 new_event
->data
= data
;
587 new_event
->handler
= handler
;
589 if (events
->resume_wallclock
== 0)
590 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
592 new_event
->wallclock
= (events
->elapsed_wallclock
593 + sim_elapsed_time_since (events
->resume_wallclock
)
596 new_event
->next
= events
->watchpoints
;
597 events
->watchpoints
= new_event
;
598 events
->work_pending
= 1;
600 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
601 (long)sim_events_time (sd
),
603 (long)new_event
->wallclock
,
604 (long)new_event
->handler
,
605 (long)new_event
->data
));
611 #if EXTERN_SIM_EVENTS_P
613 sim_events_watch_sim (SIM_DESC sd
,
616 enum bfd_endian byte_order
,
620 sim_event_handler
*handler
,
623 sim_events
*events
= STATE_EVENTS (sd
);
624 sim_event
*new_event
= sim_events_zalloc (sd
);
628 case BFD_ENDIAN_UNKNOWN
:
631 case 1: new_event
->watching
= watch_sim_host_1
; break;
632 case 2: new_event
->watching
= watch_sim_host_2
; break;
633 case 4: new_event
->watching
= watch_sim_host_4
; break;
634 case 8: new_event
->watching
= watch_sim_host_8
; break;
635 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
641 case 1: new_event
->watching
= watch_sim_be_1
; break;
642 case 2: new_event
->watching
= watch_sim_be_2
; break;
643 case 4: new_event
->watching
= watch_sim_be_4
; break;
644 case 8: new_event
->watching
= watch_sim_be_8
; break;
645 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
648 case BFD_ENDIAN_LITTLE
:
651 case 1: new_event
->watching
= watch_sim_le_1
; break;
652 case 2: new_event
->watching
= watch_sim_le_2
; break;
653 case 4: new_event
->watching
= watch_sim_le_4
; break;
654 case 8: new_event
->watching
= watch_sim_le_8
; break;
655 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
659 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
662 new_event
->data
= data
;
663 new_event
->handler
= handler
;
665 new_event
->host_addr
= host_addr
;
667 new_event
->lb64
= lb
;
669 new_event
->ub64
= ub
;
670 new_event
->is_within
= (is_within
!= 0);
672 new_event
->next
= events
->watchpoints
;
673 events
->watchpoints
= new_event
;
674 events
->work_pending
= 1;
676 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
677 (long)sim_events_time (sd
),
679 (long)new_event
->host_addr
,
682 (long)new_event
->handler
,
683 (long)new_event
->data
));
689 #if EXTERN_SIM_EVENTS_P
691 sim_events_watch_core (SIM_DESC sd
,
692 address_word core_addr
,
695 enum bfd_endian byte_order
,
699 sim_event_handler
*handler
,
702 sim_events
*events
= STATE_EVENTS (sd
);
703 sim_event
*new_event
= sim_events_zalloc (sd
);
707 case BFD_ENDIAN_UNKNOWN
:
710 case 1: new_event
->watching
= watch_core_targ_1
; break;
711 case 2: new_event
->watching
= watch_core_targ_2
; break;
712 case 4: new_event
->watching
= watch_core_targ_4
; break;
713 case 8: new_event
->watching
= watch_core_targ_8
; break;
714 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
720 case 1: new_event
->watching
= watch_core_be_1
; break;
721 case 2: new_event
->watching
= watch_core_be_2
; break;
722 case 4: new_event
->watching
= watch_core_be_4
; break;
723 case 8: new_event
->watching
= watch_core_be_8
; break;
724 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
727 case BFD_ENDIAN_LITTLE
:
730 case 1: new_event
->watching
= watch_core_le_1
; break;
731 case 2: new_event
->watching
= watch_core_le_2
; break;
732 case 4: new_event
->watching
= watch_core_le_4
; break;
733 case 8: new_event
->watching
= watch_core_le_8
; break;
734 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
738 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
741 new_event
->data
= data
;
742 new_event
->handler
= handler
;
744 new_event
->core_addr
= core_addr
;
745 new_event
->core_map
= core_map
;
747 new_event
->lb64
= lb
;
749 new_event
->ub64
= ub
;
750 new_event
->is_within
= (is_within
!= 0);
752 new_event
->next
= events
->watchpoints
;
753 events
->watchpoints
= new_event
;
754 events
->work_pending
= 1;
756 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
757 (long)sim_events_time (sd
),
759 (long)new_event
->host_addr
,
762 (long)new_event
->handler
,
763 (long)new_event
->data
));
769 #if EXTERN_SIM_EVENTS_P
771 sim_events_deschedule (SIM_DESC sd
,
772 sim_event
*event_to_remove
)
774 sim_events
*events
= STATE_EVENTS (sd
);
775 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
776 if (event_to_remove
!= NULL
)
778 sim_event
**queue
= NULL
;
779 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
781 sim_event
**ptr_to_current
;
782 for (ptr_to_current
= queue
;
783 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
784 ptr_to_current
= &(*ptr_to_current
)->next
);
785 if (*ptr_to_current
== to_remove
)
787 sim_event
*dead
= *ptr_to_current
;
788 *ptr_to_current
= dead
->next
;
790 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
791 (long) sim_events_time (sd
),
792 (long) event_to_remove
,
793 (long) dead
->time_of_event
,
794 (long) dead
->handler
,
796 (dead
->trace
!= NULL
) ? ", " : "",
797 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
798 sim_events_free (sd
, dead
);
799 update_time_from_event (sd
);
800 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
806 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
807 (long) sim_events_time (sd
),
808 (long) event_to_remove
));
813 STATIC_INLINE_SIM_EVENTS\
815 sim_watch_valid (SIM_DESC sd
,
818 switch (to_do
->watching
)
821 #define WATCH_CORE(N,OP,EXT) \
823 unsigned_##N word = 0; \
824 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
825 to_do->core_addr, sizeof (word)); \
827 ok = (nr_read == sizeof (unsigned_##N) \
828 && (to_do->is_within \
829 == (word >= to_do->lb##EXT \
830 && word <= to_do->ub##EXT)));
832 case watch_core_targ_1
:
834 WATCH_CORE (1, T2H
,);
837 case watch_core_targ_2
:
839 WATCH_CORE (2, T2H
,);
842 case watch_core_targ_4
:
844 WATCH_CORE (4, T2H
,);
847 case watch_core_targ_8
:
849 WATCH_CORE (8, T2H
,64);
853 case watch_core_be_1
:
855 WATCH_CORE (1, BE2H
,);
858 case watch_core_be_2
:
860 WATCH_CORE (2, BE2H
,);
863 case watch_core_be_4
:
865 WATCH_CORE (4, BE2H
,);
868 case watch_core_be_8
:
870 WATCH_CORE (8, BE2H
,64);
874 case watch_core_le_1
:
876 WATCH_CORE (1, LE2H
,);
879 case watch_core_le_2
:
881 WATCH_CORE (2, LE2H
,);
884 case watch_core_le_4
:
886 WATCH_CORE (4, LE2H
,);
889 case watch_core_le_8
:
891 WATCH_CORE (8, LE2H
,64);
896 #define WATCH_SIM(N,OP,EXT) \
898 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
900 ok = (to_do->is_within \
901 == (word >= to_do->lb##EXT \
902 && word <= to_do->ub##EXT));
904 case watch_sim_host_1
:
906 WATCH_SIM (1, word
= ,);
909 case watch_sim_host_2
:
911 WATCH_SIM (2, word
= ,);
914 case watch_sim_host_4
:
916 WATCH_SIM (4, word
= ,);
919 case watch_sim_host_8
:
921 WATCH_SIM (8, word
= ,64);
927 WATCH_SIM (1, BE2H
,);
932 WATCH_SIM (2, BE2H
,);
937 WATCH_SIM (4, BE2H
,);
942 WATCH_SIM (8, BE2H
,64);
948 WATCH_SIM (1, LE2H
,);
953 WATCH_SIM (1, LE2H
,);
958 WATCH_SIM (1, LE2H
,);
963 WATCH_SIM (1, LE2H
,64);
968 case watch_clock
: /* wallclock */
970 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
971 return (elapsed_time
>= to_do
->wallclock
);
975 sim_io_error (sd
, "sim_watch_valid - bad switch");
985 sim_events_tick (SIM_DESC sd
)
987 sim_events
*events
= STATE_EVENTS (sd
);
989 /* this should only be called after the previous ticks have been
992 /* Advance the time but *only* if there is nothing to process */
993 if (events
->work_pending
994 || events
->time_from_event
== 0)
996 events
->nr_ticks_to_process
+= 1;
1001 events
->time_from_event
-= 1;
1009 sim_events_tickn (SIM_DESC sd
,
1012 sim_events
*events
= STATE_EVENTS (sd
);
1015 /* this should only be called after the previous ticks have been
1018 /* Advance the time but *only* if there is nothing to process */
1019 if (events
->work_pending
|| events
->time_from_event
< n
)
1021 events
->nr_ticks_to_process
+= n
;
1026 events
->time_from_event
-= n
;
1034 sim_events_slip (SIM_DESC sd
,
1037 sim_events
*events
= STATE_EVENTS (sd
);
1038 SIM_ASSERT (slip
> 0);
1040 /* Flag a ready event with work_pending instead of number of ticks
1041 to process so that the time continues to be correct */
1042 if (events
->time_from_event
< slip
)
1044 events
->work_pending
= 1;
1046 events
->time_from_event
-= slip
;
1052 sim_events_preprocess (SIM_DESC sd
,
1053 int events_were_last
,
1054 int events_were_next
)
1056 sim_events
*events
= STATE_EVENTS (sd
);
1057 if (events_were_last
)
1059 /* Halted part way through event processing */
1060 ASSERT (events
->nr_ticks_to_process
!= 0);
1061 /* The external world can't tell if the event that stopped the
1062 simulator was the last event to process. */
1063 ASSERT (events_were_next
);
1064 sim_events_process (sd
);
1066 else if (events_were_next
)
1068 /* Halted by the last processor */
1069 if (sim_events_tick (sd
))
1070 sim_events_process (sd
);
1077 sim_events_process (SIM_DESC sd
)
1079 sim_events
*events
= STATE_EVENTS (sd
);
1080 signed64 event_time
= sim_events_time (sd
);
1082 /* Clear work_pending before checking nr_held. Clearing
1083 work_pending after nr_held (with out a lock could loose an
1085 events
->work_pending
= 0;
1087 /* move any events that were asynchronously queued by any signal
1088 handlers onto the real event queue. */
1089 if (events
->nr_held
> 0)
1093 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1097 sigfillset (&new_mask
);
1098 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1101 for (i
= 0; i
< events
->nr_held
; i
++)
1103 sim_event
*entry
= &events
->held
[i
];
1104 sim_events_schedule (sd
,
1105 entry
->time_of_event
,
1109 events
->nr_held
= 0;
1111 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1113 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1118 /* Process any watchpoints. Be careful to allow a watchpoint to
1119 appear/disappear under our feet.
1120 To ensure that watchpoints are processed only once per cycle,
1121 they are moved onto a watched queue, this returned to the
1122 watchpoint queue when all queue processing has been
1124 while (events
->watchpoints
!= NULL
)
1126 sim_event
*to_do
= events
->watchpoints
;
1127 events
->watchpoints
= to_do
->next
;
1128 if (sim_watch_valid (sd
, to_do
))
1130 sim_event_handler
*handler
= to_do
->handler
;
1131 void *data
= to_do
->data
;
1133 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1138 (to_do
->trace
!= NULL
) ? ", " : "",
1139 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1140 sim_events_free (sd
, to_do
);
1145 to_do
->next
= events
->watchedpoints
;
1146 events
->watchedpoints
= to_do
;
1150 /* consume all events for this or earlier times. Be careful to
1151 allow an event to appear/disappear under our feet */
1152 while (events
->queue
->time_of_event
<
1153 (event_time
+ events
->nr_ticks_to_process
))
1155 sim_event
*to_do
= events
->queue
;
1156 sim_event_handler
*handler
= to_do
->handler
;
1157 void *data
= to_do
->data
;
1158 events
->queue
= to_do
->next
;
1159 update_time_from_event (sd
);
1161 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1166 (to_do
->trace
!= NULL
) ? ", " : "",
1167 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1168 sim_events_free (sd
, to_do
);
1172 /* put things back where they belong ready for the next iteration */
1173 events
->watchpoints
= events
->watchedpoints
;
1174 events
->watchedpoints
= NULL
;
1175 if (events
->watchpoints
!= NULL
)
1176 events
->work_pending
= 1;
1178 /* advance the time */
1179 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1180 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1181 events
->time_from_event
-= events
->nr_ticks_to_process
;
1183 /* this round of processing complete */
1184 events
->nr_ticks_to_process
= 0;