-/* This file is part of the program psim.
+/* The common simulator framework for GDB, the GNU Debugger.
- Copyright (C) 1994-1997, Andrew Cagney <cagney@highland.com.au>
+ Copyright 2002-2019 Free Software Foundation, Inc.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ Contributed by Andrew Cagney and Red Hat.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- */
+ This file is part of GDB.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _SIM_EVENTS_C_
#include "sim-main.h"
#include "sim-assert.h"
+#include "libiberty.h"
#ifdef HAVE_STRING_H
#include <string.h>
#include <stdlib.h>
#endif
-#include <signal.h> /* For SIGPROCMASK et.al. */
+#include <signal.h> /* For SIGPROCMASK et al. */
typedef enum {
watch_invalid,
watch_sim_le_2,
watch_sim_le_4,
watch_sim_le_8,
-
+
/* wallclock */
watch_clock,
/* The event queue maintains a single absolute time using two
variables.
-
+
TIME_OF_EVENT: this holds the time at which the next event is ment
- to occure. If no next event it will hold the time of the last
+ to occur. If no next event it will hold the time of the last
event.
TIME_FROM_EVENT: The current distance from TIME_OF_EVENT. A value
#define _ETRACE sd, NULL
-#undef ETRACE_P
-#define ETRACE_P (WITH_TRACE && STATE_EVENTS (sd)->trace)
-
#undef ETRACE
#define ETRACE(ARGS) \
do \
{ \
- if (ETRACE_P) \
+ if (STRACE_EVENTS_P (sd)) \
{ \
if (STRACE_DEBUG_P (sd)) \
- { \
- const char *file; \
- SIM_FILTER_PATH (file, __FILE__); \
- trace_printf (sd, NULL, "%s:%d: ", file, __LINE__); \
- } \
+ trace_printf (sd, NULL, "%s:%d: ", lbasename (__FILE__), __LINE__); \
trace_printf ARGS; \
} \
} \
/*-LOCK-*/
sigset_t old_mask;
sigset_t new_mask;
- sigfillset(&new_mask);
+ sigfillset (&new_mask);
sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
#endif
new = ZALLOC (sim_event);
}
+/* Returns the time that remains before the event is raised. */
+INLINE_SIM_EVENTS\
+(signed64)
+sim_events_remain_time (SIM_DESC sd, sim_event *event)
+{
+ if (event == 0)
+ return 0;
+
+ return (event->time_of_event - sim_events_time (sd));
+}
+
+
+
STATIC_INLINE_SIM_EVENTS\
(void)
update_time_from_event (SIM_DESC sd)
events->time_of_event = current_time - 1;
events->time_from_event = -1;
}
- if (ETRACE_P)
+ if (STRACE_EVENTS_P (sd))
{
sim_event *event;
int i;
if (delta < 0)
sim_io_error (sd, "what is past is past!\n");
-
- /* compute when the event should occure */
+
+ /* compute when the event should occur */
time_of_event = sim_events_time (sd) + delta;
-
+
/* find the queue insertion point - things are time ordered */
prev = &events->queue;
curr = events->queue;
curr = curr->next;
}
SIM_ASSERT (curr == NULL || time_of_event < curr->time_of_event);
-
+
/* insert it */
new_event->next = curr;
*prev = new_event;
new_event->time_of_event = time_of_event;
-
+
/* adjust the time until the first event */
update_time_from_event (sd);
}
void *data)
{
va_list dummy;
+ memset (&dummy, 0, sizeof dummy);
return sim_events_schedule_vtracef (sd, delta_time, handler, data,
NULL, dummy);
}
new_event->data = data;
new_event->handler = handler;
new_event->watching = watch_timer;
- if (fmt == NULL || !ETRACE_P || vasprintf (&new_event->trace, fmt, ap) < 0)
+ if (fmt == NULL || !STRACE_EVENTS_P (sd) || vasprintf (&new_event->trace, fmt, ap) < 0)
new_event->trace = NULL;
- insert_sim_event(sd, new_event, delta_time);
- ETRACE((_ETRACE,
- "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
- (long)sim_events_time(sd),
- (long)new_event,
- (long)new_event->time_of_event,
- (long)new_event->handler,
- (long)new_event->data,
- (new_event->trace != NULL) ? ", " : "",
- (new_event->trace != NULL) ? new_event->trace : ""));
+ insert_sim_event (sd, new_event, delta_time);
+ ETRACE ((_ETRACE,
+ "event scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",
+ (long)sim_events_time (sd),
+ (long)new_event,
+ (long)new_event->time_of_event,
+ (long)new_event->handler,
+ (long)new_event->data,
+ (new_event->trace != NULL) ? ", " : "",
+ (new_event->trace != NULL) ? new_event->trace : ""));
return new_event;
}
#endif
/*-LOCK-*/
sigset_t old_mask;
sigset_t new_mask;
- sigfillset(&new_mask);
+ sigfillset (&new_mask);
sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
#endif
-
+
/* allocate an event entry from the signal buffer */
new_event = &events->held [events->nr_held];
events->nr_held ++;
if (events->nr_held > MAX_NR_SIGNAL_SIM_EVENTS)
{
sim_engine_abort (NULL, NULL, NULL_CIA,
- "sim_events_schedule_after_signal - buffer oveflow");
+ "sim_events_schedule_after_signal - buffer overflow");
}
-
+
new_event->data = data;
new_event->handler = handler;
new_event->time_of_event = delta_time; /* work it out later */
/*-UNLOCK-*/
sigprocmask (SIG_SETMASK, &old_mask, NULL);
#endif
-
+
ETRACE ((_ETRACE,
"signal scheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx\n",
- (long)sim_events_time(sd),
+ (long)sim_events_time (sd),
(long)new_event,
(long)new_event->time_of_event,
(long)new_event->handler,
/* type */
switch (byte_order)
{
- case 0:
+ case BFD_ENDIAN_UNKNOWN:
switch (nr_bytes)
{
case 1: new_event->watching = watch_sim_host_1; break;
default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
}
break;
- case BIG_ENDIAN:
+ case BFD_ENDIAN_BIG:
switch (nr_bytes)
{
case 1: new_event->watching = watch_sim_be_1; break;
default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");
}
break;
- case LITTLE_ENDIAN:
+ case BFD_ENDIAN_LITTLE:
switch (nr_bytes)
{
case 1: new_event->watching = watch_sim_le_1; break;
/* type */
switch (byte_order)
{
- case 0:
+ case BFD_ENDIAN_UNKNOWN:
switch (nr_bytes)
{
case 1: new_event->watching = watch_core_targ_1; break;
default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
}
break;
- case BIG_ENDIAN:
+ case BFD_ENDIAN_BIG:
switch (nr_bytes)
{
case 1: new_event->watching = watch_core_be_1; break;
default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");
}
break;
- case LITTLE_ENDIAN:
+ case BFD_ENDIAN_LITTLE:
switch (nr_bytes)
{
case 1: new_event->watching = watch_core_le_1; break;
int events_were_last,
int events_were_next)
{
- sim_events *events = STATE_EVENTS(sd);
+ sim_events *events = STATE_EVENTS (sd);
if (events_were_last)
{
/* Halted part way through event processing */
(void)
sim_events_process (SIM_DESC sd)
{
- sim_events *events = STATE_EVENTS(sd);
- signed64 event_time = sim_events_time(sd);
+ sim_events *events = STATE_EVENTS (sd);
+ signed64 event_time = sim_events_time (sd);
/* Clear work_pending before checking nr_held. Clearing
work_pending after nr_held (with out a lock could loose an
if (events->nr_held > 0)
{
int i;
-
+
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-LOCK-*/
sigset_t old_mask;
sigset_t new_mask;
- sigfillset(&new_mask);
- sigprocmask(SIG_SETMASK, &new_mask, &old_mask);
+ sigfillset (&new_mask);
+ sigprocmask (SIG_SETMASK, &new_mask, &old_mask);
#endif
for (i = 0; i < events->nr_held; i++)
entry->data);
}
events->nr_held = 0;
-
+
#if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)
/*-UNLOCK-*/
- sigprocmask(SIG_SETMASK, &old_mask, NULL);
+ sigprocmask (SIG_SETMASK, &old_mask, NULL);
#endif
-
+
}
-
+
/* Process any watchpoints. Be careful to allow a watchpoint to
appear/disappear under our feet.
To ensure that watchpoints are processed only once per cycle,
{
sim_event_handler *handler = to_do->handler;
void *data = to_do->data;
- ETRACE((_ETRACE,
- "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
- (long) event_time,
- (long) to_do,
- (long) handler,
- (long) data,
- (to_do->trace != NULL) ? ", " : "",
- (to_do->trace != NULL) ? to_do->trace : ""));
+ ETRACE ((_ETRACE,
+ "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
+ (long) event_time,
+ (long) to_do,
+ (long) handler,
+ (long) data,
+ (to_do->trace != NULL) ? ", " : "",
+ (to_do->trace != NULL) ? to_do->trace : ""));
sim_events_free (sd, to_do);
handler (sd, data);
}
events->watchedpoints = to_do;
}
}
-
+
/* consume all events for this or earlier times. Be careful to
allow an event to appear/disappear under our feet */
while (events->queue->time_of_event <
void *data = to_do->data;
events->queue = to_do->next;
update_time_from_event (sd);
- ETRACE((_ETRACE,
- "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
- (long) event_time,
- (long) to_do,
- (long) handler,
- (long) data,
- (to_do->trace != NULL) ? ", " : "",
- (to_do->trace != NULL) ? to_do->trace : ""));
+ ETRACE ((_ETRACE,
+ "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",
+ (long) event_time,
+ (long) to_do,
+ (long) handler,
+ (long) data,
+ (to_do->trace != NULL) ? ", " : "",
+ (to_do->trace != NULL) ? to_do->trace : ""));
sim_events_free (sd, to_do);
handler (sd, data);
}
-
+
/* put things back where they belong ready for the next iteration */
events->watchpoints = events->watchedpoints;
events->watchedpoints = NULL;
if (events->watchpoints != NULL)
events->work_pending = 1;
-
+
/* advance the time */
SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);
SIM_ASSERT (events->queue != NULL); /* always poll event */