1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002 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 2 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, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330,
22 Boston, MA 02111-1307, USA. */
25 #ifndef _SIM_EVENTS_C_
26 #define _SIM_EVENTS_C_
29 #include "sim-assert.h"
43 #include <signal.h> /* For SIGPROCMASK et al. */
48 /* core - target byte order */
53 /* core - big-endian */
58 /* core - little-endian */
64 /* sim - host byte order */
69 /* sim - big-endian */
74 /* sim - little-endian */
85 } sim_event_watchpoints
;
89 sim_event_watchpoints watching
;
91 sim_event_handler
*handler
;
93 signed64 time_of_event
;
94 /* watch wallclock event */
96 /* watch core address */
97 address_word core_addr
;
101 /* watch core/sim range */
102 int is_within
; /* 0/1 */
107 /* trace info (if any) */
114 /* The event queue maintains a single absolute time using two
117 TIME_OF_EVENT: this holds the time at which the next event is ment
118 to occur. If no next event it will hold the time of the last
121 TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
122 <= 0 (except when poll-event is being processed) indicates that
123 event processing is due. This variable is decremented once for
124 each iteration of a clock cycle.
126 Initially, the clock is started at time one (0) with TIME_OF_EVENT
127 == 0 and TIME_FROM_EVENT == 0 and with NR_TICKS_TO_PROCESS == 1.
129 Clearly there is a bug in that this code assumes that the absolute
130 time counter will never become greater than 2^62.
132 To avoid the need to use 64bit arithmetic, the event queue always
133 contains at least one event scheduled every 16 000 ticks. This
134 limits the time from event counter to values less than
138 #if !defined (SIM_EVENTS_POLL_RATE)
139 #define SIM_EVENTS_POLL_RATE 0x1000
143 #define _ETRACE sd, NULL
146 #define ETRACE_P (WITH_TRACE && STATE_EVENTS (sd)->trace)
149 #define ETRACE(ARGS) \
154 if (STRACE_DEBUG_P (sd)) \
157 SIM_FILTER_PATH (file, __FILE__); \
158 trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
166 /* event queue iterator - don't iterate over the held queue. */
168 #if EXTERN_SIM_EVENTS_P
170 next_event_queue (SIM_DESC sd
,
174 return &STATE_EVENTS (sd
)->queue
;
175 else if (queue
== &STATE_EVENTS (sd
)->queue
)
176 return &STATE_EVENTS (sd
)->watchpoints
;
177 else if (queue
== &STATE_EVENTS (sd
)->watchpoints
)
178 return &STATE_EVENTS (sd
)->watchedpoints
;
179 else if (queue
== &STATE_EVENTS (sd
)->watchedpoints
)
182 sim_io_error (sd
, "next_event_queue - bad queue");
188 STATIC_INLINE_SIM_EVENTS\
190 sim_events_poll (SIM_DESC sd
,
193 /* just re-schedule in 1000 million ticks time */
194 sim_events_schedule (sd
, SIM_EVENTS_POLL_RATE
, sim_events_poll
, sd
);
195 sim_io_poll_quit (sd
);
199 /* "events" module install handler.
200 This is called via sim_module_install to install the "events" subsystem
201 into the simulator. */
203 #if EXTERN_SIM_EVENTS_P
204 STATIC_SIM_EVENTS (MODULE_UNINSTALL_FN
) sim_events_uninstall
;
205 STATIC_SIM_EVENTS (MODULE_INIT_FN
) sim_events_init
;
206 STATIC_SIM_EVENTS (MODULE_RESUME_FN
) sim_events_resume
;
207 STATIC_SIM_EVENTS (MODULE_SUSPEND_FN
) sim_events_suspend
;
210 #if EXTERN_SIM_EVENTS_P
212 sim_events_install (SIM_DESC sd
)
214 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
215 sim_module_add_uninstall_fn (sd
, sim_events_uninstall
);
216 sim_module_add_init_fn (sd
, sim_events_init
);
217 sim_module_add_resume_fn (sd
, sim_events_resume
);
218 sim_module_add_suspend_fn (sd
, sim_events_suspend
);
224 /* Suspend/resume the event queue manager when the simulator is not
227 #if EXTERN_SIM_EVENTS_P
229 sim_events_resume (SIM_DESC sd
)
231 sim_events
*events
= STATE_EVENTS (sd
);
232 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
233 SIM_ASSERT (events
->resume_wallclock
== 0);
234 events
->resume_wallclock
= sim_elapsed_time_get ();
239 #if EXTERN_SIM_EVENTS_P
241 sim_events_suspend (SIM_DESC sd
)
243 sim_events
*events
= STATE_EVENTS (sd
);
244 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
245 SIM_ASSERT (events
->resume_wallclock
!= 0);
246 events
->elapsed_wallclock
+= sim_elapsed_time_since (events
->resume_wallclock
);
247 events
->resume_wallclock
= 0;
253 /* Uninstall the "events" subsystem from the simulator. */
255 #if EXTERN_SIM_EVENTS_P
257 sim_events_uninstall (SIM_DESC sd
)
259 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
260 /* FIXME: free buffers, etc. */
267 #if EXTERN_SIM_EVENTS_P
269 sim_events_zalloc (SIM_DESC sd
)
271 sim_events
*events
= STATE_EVENTS (sd
);
272 sim_event
*new = events
->free_list
;
275 events
->free_list
= new->next
;
276 memset (new, 0, sizeof (*new));
280 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
284 sigfillset(&new_mask
);
285 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
287 new = ZALLOC (sim_event
);
288 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
290 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
297 STATIC_INLINE_SIM_EVENTS\
299 sim_events_free (SIM_DESC sd
,
302 sim_events
*events
= STATE_EVENTS (sd
);
303 dead
->next
= events
->free_list
;
304 events
->free_list
= dead
;
305 if (dead
->trace
!= NULL
)
307 free (dead
->trace
); /* NB: asprintf returns a `free' buf */
313 /* Initialize the simulator event manager */
315 #if EXTERN_SIM_EVENTS_P
317 sim_events_init (SIM_DESC sd
)
319 sim_events
*events
= STATE_EVENTS (sd
);
321 /* drain the interrupt queue */
323 if (events
->held
== NULL
)
324 events
->held
= NZALLOC (sim_event
, MAX_NR_SIGNAL_SIM_EVENTS
);
326 /* drain the normal queues */
328 sim_event
**queue
= NULL
;
329 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
331 if (queue
== NULL
) break;
332 while (*queue
!= NULL
)
334 sim_event
*dead
= *queue
;
336 sim_events_free (sd
, dead
);
342 /* wind time back to zero */
343 events
->nr_ticks_to_process
= 1; /* start by doing queue */
344 events
->time_of_event
= 0;
345 events
->time_from_event
= 0;
346 events
->elapsed_wallclock
= 0;
347 events
->resume_wallclock
= 0;
349 /* schedule our initial counter event */
350 sim_events_schedule (sd
, 0, sim_events_poll
, sd
);
352 /* from now on, except when the large-int event is being processed
353 the event queue is non empty */
354 SIM_ASSERT (events
->queue
!= NULL
);
363 sim_events_time (SIM_DESC sd
)
365 sim_events
*events
= STATE_EVENTS (sd
);
366 return (events
->time_of_event
- events
->time_from_event
);
372 sim_events_elapsed_time (SIM_DESC sd
)
374 unsigned long elapsed
= STATE_EVENTS (sd
)->elapsed_wallclock
;
376 /* Are we being called inside sim_resume?
377 (Is there a simulation in progress?) */
378 if (STATE_EVENTS (sd
)->resume_wallclock
!= 0)
379 elapsed
+= sim_elapsed_time_since (STATE_EVENTS (sd
)->resume_wallclock
);
385 /* Returns the time that remains before the event is raised. */
388 sim_events_remain_time (SIM_DESC sd
, sim_event
*event
)
393 return (event
->time_of_event
- sim_events_time (sd
));
398 STATIC_INLINE_SIM_EVENTS\
400 update_time_from_event (SIM_DESC sd
)
402 sim_events
*events
= STATE_EVENTS (sd
);
403 signed64 current_time
= sim_events_time (sd
);
404 if (events
->queue
!= NULL
)
406 events
->time_of_event
= events
->queue
->time_of_event
;
407 events
->time_from_event
= (events
->queue
->time_of_event
- current_time
);
411 events
->time_of_event
= current_time
- 1;
412 events
->time_from_event
= -1;
418 for (event
= events
->queue
, i
= 0;
420 event
= event
->next
, i
++)
423 "event time-from-event - time %ld, delta %ld - event %d, tag 0x%lx, time %ld, handler 0x%lx, data 0x%lx%s%s\n",
425 (long)events
->time_from_event
,
428 (long)event
->time_of_event
,
429 (long)event
->handler
,
431 (event
->trace
!= NULL
) ? ", " : "",
432 (event
->trace
!= NULL
) ? event
->trace
: ""));
435 SIM_ASSERT (current_time
== sim_events_time (sd
));
439 #if EXTERN_SIM_EVENTS_P
441 insert_sim_event (SIM_DESC sd
,
442 sim_event
*new_event
,
445 sim_events
*events
= STATE_EVENTS (sd
);
448 signed64 time_of_event
;
451 sim_io_error (sd
, "what is past is past!\n");
453 /* compute when the event should occur */
454 time_of_event
= sim_events_time (sd
) + delta
;
456 /* find the queue insertion point - things are time ordered */
457 prev
= &events
->queue
;
458 curr
= events
->queue
;
459 while (curr
!= NULL
&& time_of_event
>= curr
->time_of_event
)
461 SIM_ASSERT (curr
->next
== NULL
462 || curr
->time_of_event
<= curr
->next
->time_of_event
);
466 SIM_ASSERT (curr
== NULL
|| time_of_event
< curr
->time_of_event
);
469 new_event
->next
= curr
;
471 new_event
->time_of_event
= time_of_event
;
473 /* adjust the time until the first event */
474 update_time_from_event (sd
);
479 #if EXTERN_SIM_EVENTS_P
481 sim_events_schedule (SIM_DESC sd
,
483 sim_event_handler
*handler
,
487 memset (&dummy
, 0, sizeof dummy
);
488 return sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
,
494 #if EXTERN_SIM_EVENTS_P
496 sim_events_schedule_tracef (SIM_DESC sd
,
498 sim_event_handler
*handler
,
503 sim_event
*new_event
;
506 new_event
= sim_events_schedule_vtracef (sd
, delta_time
, handler
, data
, fmt
, ap
);
513 #if EXTERN_SIM_EVENTS_P
515 sim_events_schedule_vtracef (SIM_DESC sd
,
517 sim_event_handler
*handler
,
522 sim_event
*new_event
= sim_events_zalloc (sd
);
523 new_event
->data
= data
;
524 new_event
->handler
= handler
;
525 new_event
->watching
= watch_timer
;
526 if (fmt
== NULL
|| !ETRACE_P
|| vasprintf (&new_event
->trace
, fmt
, ap
) < 0)
527 new_event
->trace
= NULL
;
528 insert_sim_event(sd
, new_event
, delta_time
);
530 "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
531 (long)sim_events_time(sd
),
533 (long)new_event
->time_of_event
,
534 (long)new_event
->handler
,
535 (long)new_event
->data
,
536 (new_event
->trace
!= NULL
) ? ", " : "",
537 (new_event
->trace
!= NULL
) ? new_event
->trace
: ""));
543 #if EXTERN_SIM_EVENTS_P
545 sim_events_schedule_after_signal (SIM_DESC sd
,
547 sim_event_handler
*handler
,
550 sim_events
*events
= STATE_EVENTS (sd
);
551 sim_event
*new_event
;
552 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
556 sigfillset(&new_mask
);
557 sigprocmask (SIG_SETMASK
, &new_mask
, &old_mask
);
560 /* allocate an event entry from the signal buffer */
561 new_event
= &events
->held
[events
->nr_held
];
563 if (events
->nr_held
> MAX_NR_SIGNAL_SIM_EVENTS
)
565 sim_engine_abort (NULL
, NULL
, NULL_CIA
,
566 "sim_events_schedule_after_signal - buffer oveflow");
569 new_event
->data
= data
;
570 new_event
->handler
= handler
;
571 new_event
->time_of_event
= delta_time
; /* work it out later */
572 new_event
->next
= NULL
;
574 events
->work_pending
= 1; /* notify main process */
576 #if defined (HAVE_SIGPROCMASK) && defined (SIG_SETMASK)
578 sigprocmask (SIG_SETMASK
, &old_mask
, NULL
);
582 "signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
583 (long)sim_events_time(sd
),
585 (long)new_event
->time_of_event
,
586 (long)new_event
->handler
,
587 (long)new_event
->data
));
592 #if EXTERN_SIM_EVENTS_P
594 sim_events_watch_clock (SIM_DESC sd
,
595 unsigned delta_ms_time
,
596 sim_event_handler
*handler
,
599 sim_events
*events
= STATE_EVENTS (sd
);
600 sim_event
*new_event
= sim_events_zalloc (sd
);
602 new_event
->watching
= watch_clock
;
604 new_event
->data
= data
;
605 new_event
->handler
= handler
;
607 if (events
->resume_wallclock
== 0)
608 new_event
->wallclock
= (events
->elapsed_wallclock
+ delta_ms_time
);
610 new_event
->wallclock
= (events
->elapsed_wallclock
611 + sim_elapsed_time_since (events
->resume_wallclock
)
614 new_event
->next
= events
->watchpoints
;
615 events
->watchpoints
= new_event
;
616 events
->work_pending
= 1;
618 "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",
619 (long)sim_events_time (sd
),
621 (long)new_event
->wallclock
,
622 (long)new_event
->handler
,
623 (long)new_event
->data
));
629 #if EXTERN_SIM_EVENTS_P
631 sim_events_watch_sim (SIM_DESC sd
,
638 sim_event_handler
*handler
,
641 sim_events
*events
= STATE_EVENTS (sd
);
642 sim_event
*new_event
= sim_events_zalloc (sd
);
649 case 1: new_event
->watching
= watch_sim_host_1
; break;
650 case 2: new_event
->watching
= watch_sim_host_2
; break;
651 case 4: new_event
->watching
= watch_sim_host_4
; break;
652 case 8: new_event
->watching
= watch_sim_host_8
; break;
653 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
659 case 1: new_event
->watching
= watch_sim_be_1
; break;
660 case 2: new_event
->watching
= watch_sim_be_2
; break;
661 case 4: new_event
->watching
= watch_sim_be_4
; break;
662 case 8: new_event
->watching
= watch_sim_be_8
; break;
663 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
669 case 1: new_event
->watching
= watch_sim_le_1
; break;
670 case 2: new_event
->watching
= watch_sim_le_2
; break;
671 case 4: new_event
->watching
= watch_sim_le_4
; break;
672 case 8: new_event
->watching
= watch_sim_le_8
; break;
673 default: sim_io_error (sd
, "sim_events_watch_sim - invalid nr bytes");
677 sim_io_error (sd
, "sim_events_watch_sim - invalid byte order");
680 new_event
->data
= data
;
681 new_event
->handler
= handler
;
683 new_event
->host_addr
= host_addr
;
685 new_event
->lb64
= lb
;
687 new_event
->ub64
= ub
;
688 new_event
->is_within
= (is_within
!= 0);
690 new_event
->next
= events
->watchpoints
;
691 events
->watchpoints
= new_event
;
692 events
->work_pending
= 1;
694 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
695 (long)sim_events_time (sd
),
697 (long)new_event
->host_addr
,
700 (long)new_event
->handler
,
701 (long)new_event
->data
));
707 #if EXTERN_SIM_EVENTS_P
709 sim_events_watch_core (SIM_DESC sd
,
710 address_word core_addr
,
717 sim_event_handler
*handler
,
720 sim_events
*events
= STATE_EVENTS (sd
);
721 sim_event
*new_event
= sim_events_zalloc (sd
);
728 case 1: new_event
->watching
= watch_core_targ_1
; break;
729 case 2: new_event
->watching
= watch_core_targ_2
; break;
730 case 4: new_event
->watching
= watch_core_targ_4
; break;
731 case 8: new_event
->watching
= watch_core_targ_8
; break;
732 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
738 case 1: new_event
->watching
= watch_core_be_1
; break;
739 case 2: new_event
->watching
= watch_core_be_2
; break;
740 case 4: new_event
->watching
= watch_core_be_4
; break;
741 case 8: new_event
->watching
= watch_core_be_8
; break;
742 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
748 case 1: new_event
->watching
= watch_core_le_1
; break;
749 case 2: new_event
->watching
= watch_core_le_2
; break;
750 case 4: new_event
->watching
= watch_core_le_4
; break;
751 case 8: new_event
->watching
= watch_core_le_8
; break;
752 default: sim_io_error (sd
, "sim_events_watch_core - invalid nr bytes");
756 sim_io_error (sd
, "sim_events_watch_core - invalid byte order");
759 new_event
->data
= data
;
760 new_event
->handler
= handler
;
762 new_event
->core_addr
= core_addr
;
763 new_event
->core_map
= core_map
;
765 new_event
->lb64
= lb
;
767 new_event
->ub64
= ub
;
768 new_event
->is_within
= (is_within
!= 0);
770 new_event
->next
= events
->watchpoints
;
771 events
->watchpoints
= new_event
;
772 events
->work_pending
= 1;
774 "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",
775 (long)sim_events_time (sd
),
777 (long)new_event
->host_addr
,
780 (long)new_event
->handler
,
781 (long)new_event
->data
));
787 #if EXTERN_SIM_EVENTS_P
789 sim_events_deschedule (SIM_DESC sd
,
790 sim_event
*event_to_remove
)
792 sim_events
*events
= STATE_EVENTS (sd
);
793 sim_event
*to_remove
= (sim_event
*)event_to_remove
;
794 if (event_to_remove
!= NULL
)
796 sim_event
**queue
= NULL
;
797 while ((queue
= next_event_queue (sd
, queue
)) != NULL
)
799 sim_event
**ptr_to_current
;
800 for (ptr_to_current
= queue
;
801 *ptr_to_current
!= NULL
&& *ptr_to_current
!= to_remove
;
802 ptr_to_current
= &(*ptr_to_current
)->next
);
803 if (*ptr_to_current
== to_remove
)
805 sim_event
*dead
= *ptr_to_current
;
806 *ptr_to_current
= dead
->next
;
808 "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
809 (long) sim_events_time (sd
),
810 (long) event_to_remove
,
811 (long) dead
->time_of_event
,
812 (long) dead
->handler
,
814 (dead
->trace
!= NULL
) ? ", " : "",
815 (dead
->trace
!= NULL
) ? dead
->trace
: ""));
816 sim_events_free (sd
, dead
);
817 update_time_from_event (sd
);
818 SIM_ASSERT ((events
->time_from_event
>= 0) == (events
->queue
!= NULL
));
824 "event/watch descheduled at %ld - tag 0x%lx - not found\n",
825 (long) sim_events_time (sd
),
826 (long) event_to_remove
));
831 STATIC_INLINE_SIM_EVENTS\
833 sim_watch_valid (SIM_DESC sd
,
836 switch (to_do
->watching
)
839 #define WATCH_CORE(N,OP,EXT) \
841 unsigned_##N word = 0; \
842 int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \
843 to_do->core_addr, sizeof (word)); \
845 ok = (nr_read == sizeof (unsigned_##N) \
846 && (to_do->is_within \
847 == (word >= to_do->lb##EXT \
848 && word <= to_do->ub##EXT)));
850 case watch_core_targ_1
:
852 WATCH_CORE (1, T2H
,);
855 case watch_core_targ_2
:
857 WATCH_CORE (2, T2H
,);
860 case watch_core_targ_4
:
862 WATCH_CORE (4, T2H
,);
865 case watch_core_targ_8
:
867 WATCH_CORE (8, T2H
,64);
871 case watch_core_be_1
:
873 WATCH_CORE (1, BE2H
,);
876 case watch_core_be_2
:
878 WATCH_CORE (2, BE2H
,);
881 case watch_core_be_4
:
883 WATCH_CORE (4, BE2H
,);
886 case watch_core_be_8
:
888 WATCH_CORE (8, BE2H
,64);
892 case watch_core_le_1
:
894 WATCH_CORE (1, LE2H
,);
897 case watch_core_le_2
:
899 WATCH_CORE (2, LE2H
,);
902 case watch_core_le_4
:
904 WATCH_CORE (4, LE2H
,);
907 case watch_core_le_8
:
909 WATCH_CORE (8, LE2H
,64);
914 #define WATCH_SIM(N,OP,EXT) \
916 unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \
918 ok = (to_do->is_within \
919 == (word >= to_do->lb##EXT \
920 && word <= to_do->ub##EXT));
922 case watch_sim_host_1
:
924 WATCH_SIM (1, word
= ,);
927 case watch_sim_host_2
:
929 WATCH_SIM (2, word
= ,);
932 case watch_sim_host_4
:
934 WATCH_SIM (4, word
= ,);
937 case watch_sim_host_8
:
939 WATCH_SIM (8, word
= ,64);
945 WATCH_SIM (1, BE2H
,);
950 WATCH_SIM (2, BE2H
,);
955 WATCH_SIM (4, BE2H
,);
960 WATCH_SIM (8, BE2H
,64);
966 WATCH_SIM (1, LE2H
,);
971 WATCH_SIM (1, LE2H
,);
976 WATCH_SIM (1, LE2H
,);
981 WATCH_SIM (1, LE2H
,64);
986 case watch_clock
: /* wallclock */
988 unsigned long elapsed_time
= sim_events_elapsed_time (sd
);
989 return (elapsed_time
>= to_do
->wallclock
);
993 sim_io_error (sd
, "sim_watch_valid - bad switch");
1003 sim_events_tick (SIM_DESC sd
)
1005 sim_events
*events
= STATE_EVENTS (sd
);
1007 /* this should only be called after the previous ticks have been
1010 /* Advance the time but *only* if there is nothing to process */
1011 if (events
->work_pending
1012 || events
->time_from_event
== 0)
1014 events
->nr_ticks_to_process
+= 1;
1019 events
->time_from_event
-= 1;
1027 sim_events_tickn (SIM_DESC sd
,
1030 sim_events
*events
= STATE_EVENTS (sd
);
1033 /* this should only be called after the previous ticks have been
1036 /* Advance the time but *only* if there is nothing to process */
1037 if (events
->work_pending
|| events
->time_from_event
< n
)
1039 events
->nr_ticks_to_process
+= n
;
1044 events
->time_from_event
-= n
;
1052 sim_events_slip (SIM_DESC sd
,
1055 sim_events
*events
= STATE_EVENTS (sd
);
1056 SIM_ASSERT (slip
> 0);
1058 /* Flag a ready event with work_pending instead of number of ticks
1059 to process so that the time continues to be correct */
1060 if (events
->time_from_event
< slip
)
1062 events
->work_pending
= 1;
1064 events
->time_from_event
-= slip
;
1070 sim_events_preprocess (SIM_DESC sd
,
1071 int events_were_last
,
1072 int events_were_next
)
1074 sim_events
*events
= STATE_EVENTS(sd
);
1075 if (events_were_last
)
1077 /* Halted part way through event processing */
1078 ASSERT (events
->nr_ticks_to_process
!= 0);
1079 /* The external world can't tell if the event that stopped the
1080 simulator was the last event to process. */
1081 ASSERT (events_were_next
);
1082 sim_events_process (sd
);
1084 else if (events_were_next
)
1086 /* Halted by the last processor */
1087 if (sim_events_tick (sd
))
1088 sim_events_process (sd
);
1095 sim_events_process (SIM_DESC sd
)
1097 sim_events
*events
= STATE_EVENTS(sd
);
1098 signed64 event_time
= sim_events_time(sd
);
1100 /* Clear work_pending before checking nr_held. Clearing
1101 work_pending after nr_held (with out a lock could loose an
1103 events
->work_pending
= 0;
1105 /* move any events that were asynchronously queued by any signal
1106 handlers onto the real event queue. */
1107 if (events
->nr_held
> 0)
1111 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1115 sigfillset(&new_mask
);
1116 sigprocmask(SIG_SETMASK
, &new_mask
, &old_mask
);
1119 for (i
= 0; i
< events
->nr_held
; i
++)
1121 sim_event
*entry
= &events
->held
[i
];
1122 sim_events_schedule (sd
,
1123 entry
->time_of_event
,
1127 events
->nr_held
= 0;
1129 #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
1131 sigprocmask(SIG_SETMASK
, &old_mask
, NULL
);
1136 /* Process any watchpoints. Be careful to allow a watchpoint to
1137 appear/disappear under our feet.
1138 To ensure that watchpoints are processed only once per cycle,
1139 they are moved onto a watched queue, this returned to the
1140 watchpoint queue when all queue processing has been
1142 while (events
->watchpoints
!= NULL
)
1144 sim_event
*to_do
= events
->watchpoints
;
1145 events
->watchpoints
= to_do
->next
;
1146 if (sim_watch_valid (sd
, to_do
))
1148 sim_event_handler
*handler
= to_do
->handler
;
1149 void *data
= to_do
->data
;
1151 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1156 (to_do
->trace
!= NULL
) ? ", " : "",
1157 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1158 sim_events_free (sd
, to_do
);
1163 to_do
->next
= events
->watchedpoints
;
1164 events
->watchedpoints
= to_do
;
1168 /* consume all events for this or earlier times. Be careful to
1169 allow an event to appear/disappear under our feet */
1170 while (events
->queue
->time_of_event
<
1171 (event_time
+ events
->nr_ticks_to_process
))
1173 sim_event
*to_do
= events
->queue
;
1174 sim_event_handler
*handler
= to_do
->handler
;
1175 void *data
= to_do
->data
;
1176 events
->queue
= to_do
->next
;
1177 update_time_from_event (sd
);
1179 "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
1184 (to_do
->trace
!= NULL
) ? ", " : "",
1185 (to_do
->trace
!= NULL
) ? to_do
->trace
: ""));
1186 sim_events_free (sd
, to_do
);
1190 /* put things back where they belong ready for the next iteration */
1191 events
->watchpoints
= events
->watchedpoints
;
1192 events
->watchedpoints
= NULL
;
1193 if (events
->watchpoints
!= NULL
)
1194 events
->work_pending
= 1;
1196 /* advance the time */
1197 SIM_ASSERT (events
->time_from_event
>= events
->nr_ticks_to_process
);
1198 SIM_ASSERT (events
->queue
!= NULL
); /* always poll event */
1199 events
->time_from_event
-= events
->nr_ticks_to_process
;
1201 /* this round of processing complete */
1202 events
->nr_ticks_to_process
= 0;