1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2018 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"
42 #include <signal.h> /* For SIGPROCMASK et al. */
47 /* core - target byte order */
52 /* core - big-endian */
57 /* core - little-endian */
63 /* sim - host byte order */
68 /* sim - big-endian */
73 /* sim - little-endian */
84 } sim_event_watchpoints
;
88 sim_event_watchpoints watching
;
90 sim_event_handler
*handler
;
92 signed64 time_of_event
;
93 /* watch wallclock event */
95 /* watch core address */
96 address_word core_addr
;
100 /* watch core/sim range */
101 int is_within
; /* 0/1 */
106 /* trace info (if any) */
113 /* The event queue maintains a single absolute time using two
116 TIME_OF_EVENT: this holds the time at which the next event is ment
117 to occur. If no next event it will hold the time of the last
120 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
121 <= 0 (except when poll-event is being processed) indicates that
122 event processing is due. This variable is decremented once for
123 each iteration of a clock cycle.
125 Initially, the clock is started at time one (0) with TIME_OF_EVENT
126 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
128 Clearly there is a bug in that this code assumes that the absolute
129 time counter will never become greater than 2^62.
131 To avoid the need to use 64bit arithmetic, the event queue always
132 contains at least one event scheduled every 16 000 ticks. This
133 limits the time from event counter to values less than
137 #if !defined (SIM_EVENTS_POLL_RATE)
138 #define SIM_EVENTS_POLL_RATE 0x1000
142 #define _ETRACE sd, NULL
145 #define ETRACE(ARGS) \
148 if (STRACE_EVENTS_P (sd)) \
150 if (STRACE_DEBUG_P (sd)) \
151 trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
158 /* event queue iterator - don't iterate over the held queue. */
160 #if EXTERN_SIM_EVENTS_P
162 next_event_queue (SIM_DESC sd
,
166 return &STATE_EVENTS (sd
)->queue
;
167 else if (queue
== &STATE_EVENTS (sd
)->queue
)
168 return &STATE_EVENTS (sd
)->watchpoints
;
169 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
170 return &STATE_EVENTS (sd
)->watchedpoints
;
171 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
174 sim_io_error (sd
, "next_event_queue - bad queue");
180 STATIC_INLINE_SIM_EVENTS\
182 sim_events_poll (SIM_DESC sd
,
185 /* just re-schedule in 1000 million ticks time */
186 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
187 sim_io_poll_quit (sd
);
191 /* "events" module install handler.
192 This is called via sim_module_install to install the "events" subsystem
193 into the simulator. */
195 #if EXTERN_SIM_EVENTS_P
196 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
197 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
198 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
199 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
202 #if EXTERN_SIM_EVENTS_P
204 sim_events_install (SIM_DESC sd
)
206 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
207 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
208 sim_module_add_init_fn (sd
, sim_events_init
);
209 sim_module_add_resume_fn (sd
, sim_events_resume
);
210 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
216 /* Suspend/resume the event queue manager when the simulator is not
219 #if EXTERN_SIM_EVENTS_P
221 sim_events_resume (SIM_DESC sd
)
223 sim_events
*events
= STATE_EVENTS (sd
);
224 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
225 SIM_ASSERT (events
->resume_wallclock
== 0);
226 events
->resume_wallclock
= sim_elapsed_time_get ();
231 #if EXTERN_SIM_EVENTS_P
233 sim_events_suspend (SIM_DESC sd
)
235 sim_events
*events
= STATE_EVENTS (sd
);
236 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
237 SIM_ASSERT (events
->resume_wallclock
!= 0);
238 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
239 events
->resume_wallclock
= 0;
245 /* Uninstall the "events" subsystem from the simulator. */
247 #if EXTERN_SIM_EVENTS_P
249 sim_events_uninstall (SIM_DESC sd
)
251 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
252 /* FIXME: free buffers, etc. */
259 #if EXTERN_SIM_EVENTS_P
261 sim_events_zalloc (SIM_DESC sd
)
263 sim_events
*events
= STATE_EVENTS (sd
);
264 sim_event
*new = events
->free_list
;
267 events
->free_list
= new->next
;
268 memset (new, 0, sizeof (*new));
272 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
276 sigfillset (&new_mask
);
277 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
279 new = ZALLOC (sim_event
);
280 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
282 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
289 STATIC_INLINE_SIM_EVENTS\
291 sim_events_free (SIM_DESC sd
,
294 sim_events
*events
= STATE_EVENTS (sd
);
295 dead
->next
= events
->free_list
;
296 events
->free_list
= dead
;
297 if (dead
->trace
!= NULL
)
299 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
305 /* Initialize the simulator event manager */
307 #if EXTERN_SIM_EVENTS_P
309 sim_events_init (SIM_DESC sd
)
311 sim_events
*events
= STATE_EVENTS (sd
);
313 /* drain the interrupt queue */
315 if (events
->held
== NULL
)
316 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
318 /* drain the normal queues */
320 sim_event
**queue
= NULL
;
321 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
323 if (queue
== NULL
) break;
324 while (*queue
!= NULL
)
326 sim_event
*dead
= *queue
;
328 sim_events_free (sd
, dead
);
334 /* wind time back to zero */
335 events
->nr_ticks_to_process
= 1; /* start by doing queue */
336 events
->time_of_event
= 0;
337 events
->time_from_event
= 0;
338 events
->elapsed_wallclock
= 0;
339 events
->resume_wallclock
= 0;
341 /* schedule our initial counter event */
342 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
344 /* from now on, except when the large-int event is being processed
345 the event queue is non empty */
346 SIM_ASSERT (events
->queue
!= NULL
);
355 sim_events_time (SIM_DESC sd
)
357 sim_events
*events
= STATE_EVENTS (sd
);
358 return (events
->time_of_event
- events
->time_from_event
);
364 sim_events_elapsed_time (SIM_DESC sd
)
366 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
368 /* Are we being called inside sim_resume?
369 (Is there a simulation in progress?) */
370 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
371 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
377 /* Returns the time that remains before the event is raised. */
380 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
385 return (event
->time_of_event
- sim_events_time (sd
));
390 STATIC_INLINE_SIM_EVENTS\
392 update_time_from_event (SIM_DESC sd
)
394 sim_events
*events
= STATE_EVENTS (sd
);
395 signed64 current_time
= sim_events_time (sd
);
396 if (events
->queue
!= NULL
)
398 events
->time_of_event
= events
->queue
->time_of_event
;
399 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
403 events
->time_of_event
= current_time
- 1;
404 events
->time_from_event
= -1;
406 if (STRACE_EVENTS_P (sd
))
410 for (event
= events
->queue
, i
= 0;
412 event
= event
->next
, i
++)
415 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
417 (long)events
->time_from_event
,
420 (long)event
->time_of_event
,
421 (long)event
->handler
,
423 (event
->trace
!= NULL
) ? ", " : "",
424 (event
->trace
!= NULL
) ? event
->trace
: ""));
427 SIM_ASSERT (current_time
== sim_events_time (sd
));
431 #if EXTERN_SIM_EVENTS_P
433 insert_sim_event (SIM_DESC sd
,
434 sim_event
*new_event
,
437 sim_events
*events
= STATE_EVENTS (sd
);
440 signed64 time_of_event
;
443 sim_io_error (sd
, "what is past is past!\n");
445 /* compute when the event should occur */
446 time_of_event
= sim_events_time (sd
) + delta
;
448 /* find the queue insertion point - things are time ordered */
449 prev
= &events
->queue
;
450 curr
= events
->queue
;
451 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
453 SIM_ASSERT (curr
->next
== NULL
454 || curr
->time_of_event
<= curr
->next
->time_of_event
);
458 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
461 new_event
->next
= curr
;
463 new_event
->time_of_event
= time_of_event
;
465 /* adjust the time until the first event */
466 update_time_from_event (sd
);
471 #if EXTERN_SIM_EVENTS_P
473 sim_events_schedule (SIM_DESC sd
,
475 sim_event_handler
*handler
,
479 memset (&dummy
, 0, sizeof dummy
);
480 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
486 #if EXTERN_SIM_EVENTS_P
488 sim_events_schedule_tracef (SIM_DESC sd
,
490 sim_event_handler
*handler
,
495 sim_event
*new_event
;
498 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
505 #if EXTERN_SIM_EVENTS_P
507 sim_events_schedule_vtracef (SIM_DESC sd
,
509 sim_event_handler
*handler
,
514 sim_event
*new_event
= sim_events_zalloc (sd
);
515 new_event
->data
= data
;
516 new_event
->handler
= handler
;
517 new_event
->watching
= watch_timer
;
518 if (fmt
== NULL
|| !STRACE_EVENTS_P (sd
) || vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
519 new_event
->trace
= NULL
;
520 insert_sim_event (sd
, new_event
, delta_time
);
522 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
523 (long)sim_events_time (sd
),
525 (long)new_event
->time_of_event
,
526 (long)new_event
->handler
,
527 (long)new_event
->data
,
528 (new_event
->trace
!= NULL
) ? ", " : "",
529 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
535 #if EXTERN_SIM_EVENTS_P
537 sim_events_schedule_after_signal (SIM_DESC sd
,
539 sim_event_handler
*handler
,
542 sim_events
*events
= STATE_EVENTS (sd
);
543 sim_event
*new_event
;
544 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
548 sigfillset (&new_mask
);
549 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
552 /* allocate an event entry from the signal buffer */
553 new_event
= &events
->held
[events
->nr_held
];
555 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
557 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
558 "sim_events_schedule_after_signal - buffer overflow");
561 new_event
->data
= data
;
562 new_event
->handler
= handler
;
563 new_event
->time_of_event
= delta_time
; /* work it out later */
564 new_event
->next
= NULL
;
566 events
->work_pending
= 1; /* notify main process */
568 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
570 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
574 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
575 (long)sim_events_time (sd
),
577 (long)new_event
->time_of_event
,
578 (long)new_event
->handler
,
579 (long)new_event
->data
));
584 #if EXTERN_SIM_EVENTS_P
586 sim_events_watch_clock (SIM_DESC sd
,
587 unsigned delta_ms_time
,
588 sim_event_handler
*handler
,
591 sim_events
*events
= STATE_EVENTS (sd
);
592 sim_event
*new_event
= sim_events_zalloc (sd
);
594 new_event
->watching
= watch_clock
;
596 new_event
->data
= data
;
597 new_event
->handler
= handler
;
599 if (events
->resume_wallclock
== 0)
600 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
602 new_event
->wallclock
= (events
->elapsed_wallclock
603 + sim_elapsed_time_since (events
->resume_wallclock
)
606 new_event
->next
= events
->watchpoints
;
607 events
->watchpoints
= new_event
;
608 events
->work_pending
= 1;
610 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
611 (long)sim_events_time (sd
),
613 (long)new_event
->wallclock
,
614 (long)new_event
->handler
,
615 (long)new_event
->data
));
621 #if EXTERN_SIM_EVENTS_P
623 sim_events_watch_sim (SIM_DESC sd
,
630 sim_event_handler
*handler
,
633 sim_events
*events
= STATE_EVENTS (sd
);
634 sim_event
*new_event
= sim_events_zalloc (sd
);
638 case BFD_ENDIAN_UNKNOWN
:
641 case 1: new_event
->watching
= watch_sim_host_1
; break;
642 case 2: new_event
->watching
= watch_sim_host_2
; break;
643 case 4: new_event
->watching
= watch_sim_host_4
; break;
644 case 8: new_event
->watching
= watch_sim_host_8
; break;
645 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
651 case 1: new_event
->watching
= watch_sim_be_1
; break;
652 case 2: new_event
->watching
= watch_sim_be_2
; break;
653 case 4: new_event
->watching
= watch_sim_be_4
; break;
654 case 8: new_event
->watching
= watch_sim_be_8
; break;
655 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
658 case BFD_ENDIAN_LITTLE
:
661 case 1: new_event
->watching
= watch_sim_le_1
; break;
662 case 2: new_event
->watching
= watch_sim_le_2
; break;
663 case 4: new_event
->watching
= watch_sim_le_4
; break;
664 case 8: new_event
->watching
= watch_sim_le_8
; break;
665 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
669 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
672 new_event
->data
= data
;
673 new_event
->handler
= handler
;
675 new_event
->host_addr
= host_addr
;
677 new_event
->lb64
= lb
;
679 new_event
->ub64
= ub
;
680 new_event
->is_within
= (is_within
!= 0);
682 new_event
->next
= events
->watchpoints
;
683 events
->watchpoints
= new_event
;
684 events
->work_pending
= 1;
686 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
687 (long)sim_events_time (sd
),
689 (long)new_event
->host_addr
,
692 (long)new_event
->handler
,
693 (long)new_event
->data
));
699 #if EXTERN_SIM_EVENTS_P
701 sim_events_watch_core (SIM_DESC sd
,
702 address_word core_addr
,
709 sim_event_handler
*handler
,
712 sim_events
*events
= STATE_EVENTS (sd
);
713 sim_event
*new_event
= sim_events_zalloc (sd
);
717 case BFD_ENDIAN_UNKNOWN
:
720 case 1: new_event
->watching
= watch_core_targ_1
; break;
721 case 2: new_event
->watching
= watch_core_targ_2
; break;
722 case 4: new_event
->watching
= watch_core_targ_4
; break;
723 case 8: new_event
->watching
= watch_core_targ_8
; break;
724 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
730 case 1: new_event
->watching
= watch_core_be_1
; break;
731 case 2: new_event
->watching
= watch_core_be_2
; break;
732 case 4: new_event
->watching
= watch_core_be_4
; break;
733 case 8: new_event
->watching
= watch_core_be_8
; break;
734 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
737 case BFD_ENDIAN_LITTLE
:
740 case 1: new_event
->watching
= watch_core_le_1
; break;
741 case 2: new_event
->watching
= watch_core_le_2
; break;
742 case 4: new_event
->watching
= watch_core_le_4
; break;
743 case 8: new_event
->watching
= watch_core_le_8
; break;
744 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
748 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
751 new_event
->data
= data
;
752 new_event
->handler
= handler
;
754 new_event
->core_addr
= core_addr
;
755 new_event
->core_map
= core_map
;
757 new_event
->lb64
= lb
;
759 new_event
->ub64
= ub
;
760 new_event
->is_within
= (is_within
!= 0);
762 new_event
->next
= events
->watchpoints
;
763 events
->watchpoints
= new_event
;
764 events
->work_pending
= 1;
766 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
767 (long)sim_events_time (sd
),
769 (long)new_event
->host_addr
,
772 (long)new_event
->handler
,
773 (long)new_event
->data
));
779 #if EXTERN_SIM_EVENTS_P
781 sim_events_deschedule (SIM_DESC sd
,
782 sim_event
*event_to_remove
)
784 sim_events
*events
= STATE_EVENTS (sd
);
785 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
786 if (event_to_remove
!= NULL
)
788 sim_event
**queue
= NULL
;
789 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
791 sim_event
**ptr_to_current
;
792 for (ptr_to_current
= queue
;
793 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
794 ptr_to_current
= &(*ptr_to_current
)->next
);
795 if (*ptr_to_current
== to_remove
)
797 sim_event
*dead
= *ptr_to_current
;
798 *ptr_to_current
= dead
->next
;
800 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
801 (long) sim_events_time (sd
),
802 (long) event_to_remove
,
803 (long) dead
->time_of_event
,
804 (long) dead
->handler
,
806 (dead
->trace
!= NULL
) ? ", " : "",
807 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
808 sim_events_free (sd
, dead
);
809 update_time_from_event (sd
);
810 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
816 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
817 (long) sim_events_time (sd
),
818 (long) event_to_remove
));
823 STATIC_INLINE_SIM_EVENTS\
825 sim_watch_valid (SIM_DESC sd
,
828 switch (to_do
->watching
)
831 #define WATCH_CORE(N,OP,EXT) \
833 unsigned_##N word = 0; \
834 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
835 to_do->core_addr, sizeof (word)); \
837 ok = (nr_read == sizeof (unsigned_##N) \
838 && (to_do->is_within \
839 == (word >= to_do->lb##EXT \
840 && word <= to_do->ub##EXT)));
842 case watch_core_targ_1
:
844 WATCH_CORE (1, T2H
,);
847 case watch_core_targ_2
:
849 WATCH_CORE (2, T2H
,);
852 case watch_core_targ_4
:
854 WATCH_CORE (4, T2H
,);
857 case watch_core_targ_8
:
859 WATCH_CORE (8, T2H
,64);
863 case watch_core_be_1
:
865 WATCH_CORE (1, BE2H
,);
868 case watch_core_be_2
:
870 WATCH_CORE (2, BE2H
,);
873 case watch_core_be_4
:
875 WATCH_CORE (4, BE2H
,);
878 case watch_core_be_8
:
880 WATCH_CORE (8, BE2H
,64);
884 case watch_core_le_1
:
886 WATCH_CORE (1, LE2H
,);
889 case watch_core_le_2
:
891 WATCH_CORE (2, LE2H
,);
894 case watch_core_le_4
:
896 WATCH_CORE (4, LE2H
,);
899 case watch_core_le_8
:
901 WATCH_CORE (8, LE2H
,64);
906 #define WATCH_SIM(N,OP,EXT) \
908 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
910 ok = (to_do->is_within \
911 == (word >= to_do->lb##EXT \
912 && word <= to_do->ub##EXT));
914 case watch_sim_host_1
:
916 WATCH_SIM (1, word
= ,);
919 case watch_sim_host_2
:
921 WATCH_SIM (2, word
= ,);
924 case watch_sim_host_4
:
926 WATCH_SIM (4, word
= ,);
929 case watch_sim_host_8
:
931 WATCH_SIM (8, word
= ,64);
937 WATCH_SIM (1, BE2H
,);
942 WATCH_SIM (2, BE2H
,);
947 WATCH_SIM (4, BE2H
,);
952 WATCH_SIM (8, BE2H
,64);
958 WATCH_SIM (1, LE2H
,);
963 WATCH_SIM (1, LE2H
,);
968 WATCH_SIM (1, LE2H
,);
973 WATCH_SIM (1, LE2H
,64);
978 case watch_clock
: /* wallclock */
980 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
981 return (elapsed_time
>= to_do
->wallclock
);
985 sim_io_error (sd
, "sim_watch_valid - bad switch");
995 sim_events_tick (SIM_DESC sd
)
997 sim_events
*events
= STATE_EVENTS (sd
);
999 /* this should only be called after the previous ticks have been
1002 /* Advance the time but *only* if there is nothing to process */
1003 if (events
->work_pending
1004 || events
->time_from_event
== 0)
1006 events
->nr_ticks_to_process
+= 1;
1011 events
->time_from_event
-= 1;
1019 sim_events_tickn (SIM_DESC sd
,
1022 sim_events
*events
= STATE_EVENTS (sd
);
1025 /* this should only be called after the previous ticks have been
1028 /* Advance the time but *only* if there is nothing to process */
1029 if (events
->work_pending
|| events
->time_from_event
< n
)
1031 events
->nr_ticks_to_process
+= n
;
1036 events
->time_from_event
-= n
;
1044 sim_events_slip (SIM_DESC sd
,
1047 sim_events
*events
= STATE_EVENTS (sd
);
1048 SIM_ASSERT (slip
> 0);
1050 /* Flag a ready event with work_pending instead of number of ticks
1051 to process so that the time continues to be correct */
1052 if (events
->time_from_event
< slip
)
1054 events
->work_pending
= 1;
1056 events
->time_from_event
-= slip
;
1062 sim_events_preprocess (SIM_DESC sd
,
1063 int events_were_last
,
1064 int events_were_next
)
1066 sim_events
*events
= STATE_EVENTS (sd
);
1067 if (events_were_last
)
1069 /* Halted part way through event processing */
1070 ASSERT (events
->nr_ticks_to_process
!= 0);
1071 /* The external world can't tell if the event that stopped the
1072 simulator was the last event to process. */
1073 ASSERT (events_were_next
);
1074 sim_events_process (sd
);
1076 else if (events_were_next
)
1078 /* Halted by the last processor */
1079 if (sim_events_tick (sd
))
1080 sim_events_process (sd
);
1087 sim_events_process (SIM_DESC sd
)
1089 sim_events
*events
= STATE_EVENTS (sd
);
1090 signed64 event_time
= sim_events_time (sd
);
1092 /* Clear work_pending before checking nr_held. Clearing
1093 work_pending after nr_held (with out a lock could loose an
1095 events
->work_pending
= 0;
1097 /* move any events that were asynchronously queued by any signal
1098 handlers onto the real event queue. */
1099 if (events
->nr_held
> 0)
1103 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1107 sigfillset (&new_mask
);
1108 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
1111 for (i
= 0; i
< events
->nr_held
; i
++)
1113 sim_event
*entry
= &events
->held
[i
];
1114 sim_events_schedule (sd
,
1115 entry
->time_of_event
,
1119 events
->nr_held
= 0;
1121 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1123 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
1128 /* Process any watchpoints. Be careful to allow a watchpoint to
1129 appear/disappear under our feet.
1130 To ensure that watchpoints are processed only once per cycle,
1131 they are moved onto a watched queue, this returned to the
1132 watchpoint queue when all queue processing has been
1134 while (events
->watchpoints
!= NULL
)
1136 sim_event
*to_do
= events
->watchpoints
;
1137 events
->watchpoints
= to_do
->next
;
1138 if (sim_watch_valid (sd
, to_do
))
1140 sim_event_handler
*handler
= to_do
->handler
;
1141 void *data
= to_do
->data
;
1143 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1148 (to_do
->trace
!= NULL
) ? ", " : "",
1149 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1150 sim_events_free (sd
, to_do
);
1155 to_do
->next
= events
->watchedpoints
;
1156 events
->watchedpoints
= to_do
;
1160 /* consume all events for this or earlier times. Be careful to
1161 allow an event to appear/disappear under our feet */
1162 while (events
->queue
->time_of_event
<
1163 (event_time
+ events
->nr_ticks_to_process
))
1165 sim_event
*to_do
= events
->queue
;
1166 sim_event_handler
*handler
= to_do
->handler
;
1167 void *data
= to_do
->data
;
1168 events
->queue
= to_do
->next
;
1169 update_time_from_event (sd
);
1171 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1176 (to_do
->trace
!= NULL
) ? ", " : "",
1177 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1178 sim_events_free (sd
, to_do
);
1182 /* put things back where they belong ready for the next iteration */
1183 events
->watchpoints
= events
->watchedpoints
;
1184 events
->watchedpoints
= NULL
;
1185 if (events
->watchpoints
!= NULL
)
1186 events
->work_pending
= 1;
1188 /* advance the time */
1189 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1190 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1191 events
->time_from_event
-= events
->nr_ticks_to_process
;
1193 /* this round of processing complete */
1194 events
->nr_ticks_to_process
= 0;