Browse files

- added naive implementation of realtime mode

- added --realtime command line option
- added internal wsim VCD events defined in machine.c
- machine_run() interface simplification (main / gdbremote / console_cmd)
- stats correction in machine_dump_stats()


git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/wsim@628 c0ef0dea-404d-0410-ad65-84cceb5f200a
  • Loading branch information...
1 parent e212587 commit f6923d57a1a8ab477dc1f55e62f8e4a3a6a482b4 afraboul committed Jun 18, 2011
Showing with 225 additions and 128 deletions.
  1. +16 −3 libconsole/console_cmd.c
  2. +5 −5 libgdb/gdbremote.c
  3. +134 −95 machine/machine.c
  4. +9 −3 machine/machine.h
  5. +10 −4 machine/machine_fd.h
  6. +17 −14 src/main.c
  7. +33 −4 src/options.c
  8. +1 −0 src/options.h
View
19 libconsole/console_cmd.c
@@ -240,10 +240,15 @@ con_cmd_val console_cmd_set(console_cmd_params p)
con_cmd_val console_cmd_run (console_cmd_params p)
{
+ struct machine_opt_t m;
+
DBG_PRINT("wsim:con:cmd:run\n");
assert(libselect_fd_register(p->cs->fd_input, SIG_CON_IO) != -1);
/* do something */
- machine_run_free();
+ m.realtime = 0;
+ m.insn = 0;
+ m.time = 0;
+ machine_run(&m);
assert(libselect_fd_unregister(p->cs->fd_input) != -1);
if ((mcu_signal_get() & SIG_CON_IO) == 0)
@@ -262,12 +267,16 @@ con_cmd_val console_cmd_run (console_cmd_params p)
con_cmd_val console_cmd_run_insn(console_cmd_params p)
{
+ struct machine_opt_t m;
uint64_t n = atoll(p->options[0]);
DBG_PRINT("wsim:con:cmd:run_insn: run for %"PRIu64" instructions\n",n);
assert(libselect_fd_register(p->cs->fd_input, SIG_CON_IO) != -1);
/* do something */
- machine_run_insn(n);
+ m.realtime = 0;
+ m.insn = n;
+ m.time = 0;
+ machine_run(&m);
assert(libselect_fd_unregister(p->cs->fd_input) != -1);
if ((mcu_signal_get() & SIG_CON_IO))
@@ -286,12 +295,16 @@ con_cmd_val console_cmd_run_insn(console_cmd_params p)
con_cmd_val console_cmd_run_time(console_cmd_params p)
{
+ struct machine_opt_t m;
uint64_t n = atoll(p->options[0]);
DBG_PRINT("wsim:con:cmd:run_time: run for %"PRIu64" ns\n",n);
assert(libselect_fd_register(p->cs->fd_input, SIG_CON_IO) != -1);
/* do something */
- machine_run_time(n);
+ m.realtime = 0;
+ m.insn = n;
+ m.time = 0;
+ machine_run(&m);
assert(libselect_fd_unregister(p->cs->fd_input) != -1);
if ((mcu_signal_get() & SIG_CON_IO))
View
10 libgdb/gdbremote.c
@@ -165,7 +165,7 @@ static void
gdbremote_putpacket (struct gdbremote_t *gdb, char *buffer)
{
- int ret;
+ int UNUSED ret;
int retry = -1;
unsigned char cret;
/* $<packet info>#<checksum>. */
@@ -409,8 +409,8 @@ static void gdbremote_write_memory_binary(struct gdbremote_t *gdb, char *buffer,
{
char *token;
char delim[] = " ,;:";
- uint32_t addr;
- uint32_t length;
+ uint32_t UNUSED addr;
+ uint32_t UNUSED length;
/* buffer[0] == 'X' */
/* X ADDR,LENGTH:XX... -- write mem */
@@ -669,7 +669,7 @@ gdbremote_single_step(struct gdbremote_t *gdb, char *buffer, int UNUSED size)
* stop (at this time this is left to GDB_SINGLE signal) */
mcu_signal_add(SIG_GDB_SINGLE);
- machine_run_free();
+ machine_run(NULL);
DMSG_LIB_GDB("gdbremote: exit single step at 0x%04x (next 0x%4x, reg[0] 0x%04x) with signal = 0x%x (%s)\n",
mcu_get_pc(),mcu_get_pc_next(),mcu_register_get(0),mcu_signal_get(),mcu_signal_str());
@@ -750,7 +750,7 @@ gdbremote_continue(struct gdbremote_t *gdb, char UNUSED *buffer, int UNUSED size
assert(libselect_fd_register(gdb->skt.socket, SIG_GDB_IO) != -1);
do
{
- machine_run_free();
+ machine_run(NULL);
}
while ((mcu_signal_get() & GDB_STOP_BITMASK) == 0);
/* we stop on anything but WORLDSENS_IO */
View
229 machine/machine.c
@@ -10,6 +10,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
+#include <sys/time.h>
+#include <unistd.h>
#include "arch/common/hardware.h"
#include "devices/devices.h"
@@ -22,21 +24,34 @@
#include "machine.h"
-#define WSIM_RECORD_INTERNAL_EVENTS 1
+#define WSIM_RECORD_INTERNAL_EVENTS 0
#if WSIM_RECORD_INTERNAL_EVENTS != 0
-#define MACHINE_TRC_BACKTRACK() tracer_event_add_id(32, "backtrack", "wsim")
-#define MACHINE_TRC_BACKTRACK_RECORD() tracer_event_record(machine.backtrack_trc, machine.backtrack)
+#define MACHINE_TRC_BACKTRACK() tracer_event_add_id(32, "backtrack", "wsim")
+#define MACHINE_TRC_BACKTRACK_RECORD() tracer_event_record(machine.backtrack_trc, machine.backtrack)
+#define MACHINE_TRC_REALTIME() tracer_event_add_id(32, "realtime", "wsim")
+#define MACHINE_TRC_REALTIME_RECORD(delta) tracer_event_record(machine.realtime_trc, delta)
+#define MACHINE_TRC_LOGWRITE() tracer_event_add_id(32, "logwrite", "wsim")
+#define MACHINE_TRC_LOGWRITE_RECORD(delta) tracer_event_record(machine.logwrite_trc, delta)
#else
-#define MACHINE_TRC_BACKTRACK() 0
-#define MACHINE_TRC_BACKTRACK_RECORD() do { } while (0)
+#define MACHINE_TRC_BACKTRACK() 0
+#define MACHINE_TRC_BACKTRACK_RECORD() do { } while (0)
+#define MACHINE_TRC_REALTIME() 0
+#define MACHINE_TRC_REALTIME_RECORD(delta) do { } while (0)
+#define MACHINE_TRC_LOGWRITE() 0
+#define MACHINE_TRC_LOGWRITEL_RECORD(delta) do { } while (0)
#endif
/**
* global variable
**/
-struct machine_t machine;
-static elf32_t machine_elf = NULL;
+struct machine_t machine;
+static elf32_t machine_elf = NULL;
+
+
+#define LIMIT_REALTIME 0x01
+#define LIMIT_TIME 0x02
+#define LIMIT_INSN 0x04
/* ************************************************** */
/* ************************************************** */
@@ -79,12 +94,17 @@ int machine_create()
machine.state = NULL;
machine.state_backup = NULL;
machine.nanotime_incr = 0;
+ machine.run_limit = 0;
+ machine.run_time = 0;
+ machine.run_insn = 0;
machine.device_max = 0;
memset(machine.device, '\0',sizeof(struct device_t)*DEVICE_MAX);
memset(machine.device_size, '\0',sizeof(int)*DEVICE_MAX);
machine.backtrack = 0;
machine.backtrack_trc = MACHINE_TRC_BACKTRACK();
+ machine.realtime_trc = MACHINE_TRC_REALTIME();
+ machine.logwrite_trc = MACHINE_TRC_LOGWRITE();
machine.ui.framebuffer_background = 0;
/* create devices = mcu + peripherals */
@@ -205,22 +225,48 @@ void machine_exit(int arg)
/* ************************************************** */
/* ************************************************** */
-static inline uint32_t machine_run(void)
+static inline wsimtime_t system_gettime()
{
- uint32_t sig;
+ struct timeval t;
+ wsimtime_t ntime;
+ gettimeofday(&t, NULL);
+ ntime = t.tv_sec * 1000 * 1000 + t.tv_usec; // us
+ return ntime;
+}
+static inline void system_waitmicro(int64_t micro)
+{
+ /*
+ struct timespec t;
+ t.tv_sec = micro / 1000000;
+ t.tv_nsec = micro * 1000;
+ nanosleep(&t);
+ */
+ usleep(micro);
+}
+
+static inline uint32_t machine_run_internal(void)
+{
+ uint32_t sig;
+ wsimtime_t realtime_last_wsim;
+ wsimtime_t realtime_last_sys;
+
mcu_system_clock_speed_tracer_update();
+ machine_state_save();
- do {
+ realtime_last_wsim = MACHINE_TIME_GET_NANO();
+ realtime_last_sys = system_gettime();
- mcu_run(); // MCU step
- devices_update(); // call platform
+ do {
+ /* run */
+ mcu_run(); // MCU step and devices
+ devices_update(); // call platform devices
mcu_update_done(); // MCU step done
-
MACHINE_TIME_CLR_INCR();
-
sig = mcu_signal_get();
- if ((sig & SIG_MAC) != 0)
+
+ /* memory access control MAC */
+ if ( (sig & SIG_MAC) != 0 )
{
mcu_signal_remove(SIG_MAC);
if ((sig & MAC_TO_SIG(MAC_MUST_WRITE_FIRST)) != 0)
@@ -248,106 +294,99 @@ static inline uint32_t machine_run(void)
}
}
- } while (sig == 0);
-
- return sig;
-}
+ /* time and instruction counters */
+ if (machine.run_limit != 0)
+ {
+ if ((machine.run_limit & LIMIT_INSN) && (mcu_get_cycles() >= machine.run_insn))
+ {
+ mcu_signal_add(SIG_RUN_INSN);
+ sig = mcu_signal_get();
+ return sig;
+ }
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
+ if ((machine.run_limit & LIMIT_TIME) && (MACHINE_TIME_GET_NANO() >= machine.run_time))
+ {
+ mcu_signal_add(SIG_RUN_TIME);
+ sig = mcu_signal_get();
+ return sig;
+ }
-inline void machine_run_free(void)
-{
- uint32_t UNUSED sig;
- sig = machine_run();
-
- HW_DMSG_MISC("machine:run: stopped at 0x%04x with signal 0x%x=%s\n",mcu_get_pc(),sig,mcu_signal_str());
- /*
- * Allowed outside tools signals
- * SIG_GDB | SIG_CONSOLE | SIG_WORLDSENS_IO
- */
-}
+#define REALTIME_PRECISION 50*1000*1000UL /* x0 ms */
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
+ if ((machine.run_limit & LIMIT_REALTIME) &&
+ ((MACHINE_TIME_GET_NANO() - realtime_last_wsim) > REALTIME_PRECISION))
+ {
+ int64_t delta;
+ wsimtime_t delta_wsim;
+ wsimtime_t delta_sys;
+ delta_wsim = MACHINE_TIME_GET_NANO() - realtime_last_wsim;
+ delta_sys = system_gettime() - realtime_last_sys;
+ delta = delta_wsim / 1000 - delta_sys;
+ if (delta > 0)
+ {
+ /* catch up */
+ system_waitmicro( delta ); // micro
+ }
+ else
+ {
+ /* wsim is late */
+ HW_DMSG_MISC("wsim: realtime mode behind schedule by %05d usec (%03d ms) at %"PRIu64"\n",
+ -delta, -delta / 1000, MACHINE_TIME_GET_NANO() / 1000000);
+
+ }
+ MACHINE_TRC_REALTIME_RECORD(delta);
+ realtime_last_wsim = MACHINE_TIME_GET_NANO();
+ realtime_last_sys = system_gettime();
+ }
+ }
-#define TEST_SIGNAL_EXIT(sig) \
- ((sig & SIG_CON_IO) ) || \
- ((sig & SIG_WORLDSENS_KILL) ) || \
- ((sig & SIG_MCU) && (sig & SIG_MCU_ILL) ) || \
- ((sig & SIG_HOST) && (sig & SIG_HOST_SIGNAL))
+ } while (sig == 0);
-void TEST_SIGNAL_PRINT(char *name)
-{
- OUTPUT("wsim:run:%s: exit at 0x%04x with signal 0x%x -- %s\n",
- name,mcu_get_pc(), mcu_signal_get(), mcu_signal_str());
- REAL_STDOUT("wsim:run:%s: exit at 0x%04x with signal %s\n",
- name,mcu_get_pc(), mcu_signal_str());
+ return sig;
}
/* ************************************************** */
/* ************************************************** */
/* ************************************************** */
-uint64_t machine_run_insn(uint64_t insn)
+void machine_run(struct machine_opt_t *m)
{
- uint32_t sig;
- uint64_t i;
- HW_DMSG_MISC("machine: will run for %" PRIu64 " instructions\n",insn);
+ uint32_t UNUSED sig;
- mcu_signal_add(SIG_RUN_INSN);
- machine_state_save();
+ machine.run_realtime = 0;
+ machine.run_time = 0;
+ machine.run_insn = 0;
- for(i=0; i < insn; i++)
+ if (m != NULL)
{
- mcu_signal_add(SIG_RUN_INSN);
- (void)machine_run();
- mcu_signal_remove(SIG_RUN_INSN);
-
- sig = mcu_signal_get();
- if (sig)
+ if (m->realtime)
{
- if (TEST_SIGNAL_EXIT(sig))
- {
- TEST_SIGNAL_PRINT("insn");
- return i;
- }
+ machine.run_limit |= LIMIT_REALTIME;
+ HW_DMSG_MISC("machine: will run realtime\n");
}
- }
- return insn;
-}
-
-/* ************************************************** */
-/* ************************************************** */
-/* ************************************************** */
-
-wsimtime_t machine_run_time(wsimtime_t nanotime)
-{
- uint32_t sig;
- HW_DMSG_MISC("machine: will run for %" PRIu64 " nano seconds\n",nanotime);
-
- mcu_signal_add(SIG_RUN_TIME);
- machine_state_save();
-
- while (MACHINE_TIME_GET_NANO() < nanotime)
- {
- mcu_signal_add(SIG_RUN_TIME);
- (void)machine_run();
- mcu_signal_remove(SIG_RUN_TIME);
-
- sig = mcu_signal_get();
- if (sig)
+
+ if (m->insn > 0)
{
- if (TEST_SIGNAL_EXIT(sig))
- {
- TEST_SIGNAL_PRINT("time");
- return MACHINE_TIME_GET_NANO();
- }
+ machine.run_limit |= LIMIT_INSN;
+ machine.run_insn = m->insn;
+ HW_DMSG_MISC("machine: will run for %" PRIu64 " instructions\n",run_insn);
+ }
+
+ if (m->time > 0)
+ {
+ machine.run_limit |= LIMIT_TIME;
+ machine.run_time = m->time;
+ HW_DMSG_MISC("machine: will run for %" PRIu64 " nano seconds\n",nanotime);
}
}
- return MACHINE_TIME_GET_NANO();
+
+ sig = machine_run_internal();
+
+ HW_DMSG_MISC("machine:run: stopped at 0x%04x with signal 0x%x=%s\n",mcu_get_pc(),sig,mcu_signal_str());
+ /*
+ * Allowed outside tools signals
+ * SIG_GDB | SIG_CONSOLE | SIG_WORLDSENS_IO
+ */
}
/* ************************************************** */
View
12 machine/machine.h
@@ -13,6 +13,14 @@
#include "devices/devices.h"
#include "libelf/libelf.h"
+
+struct machine_opt_t {
+ uint64_t insn;
+ wsimtime_t time;
+ int realtime;
+};
+
+
int machine_options_add();
/**
@@ -69,9 +77,7 @@ wsimtime_t machine_get_nanotime(void);
* machine_run
**/
void machine_exit (int arg);
-void machine_run_free (void);
-uint64_t machine_run_insn (uint64_t insn);
-wsimtime_t machine_run_time (wsimtime_t nanotime);
+void machine_run (struct machine_opt_t *m);
/**
* machine state allocate
View
14 machine/machine_fd.h
@@ -43,11 +43,11 @@ struct watchpoint_t {
};
struct machine_state_t {
- uint64_t nanotime;
- uint64_t nanotime_incr;
- char watchpoint_modify_on_first_write[MONITOR_MAX_WATCHPOINT];
+ wsimtime_t nanotime;
+ wsimtime_t nanotime_incr;
+ char watchpoint_modify_on_first_write[MONITOR_MAX_WATCHPOINT];
/* devices_state must be last */
- uint8_t devices_state[0];
+ uint8_t devices_state[0];
};
/* ************************************************** */
@@ -77,12 +77,18 @@ struct machine_t
*
**/
int nanotime_incr;
+ int run_limit;
+ int run_realtime;
+ wsimtime_t run_time;
+ uint64_t run_insn;
/**
* trace log
**/
uint32_t backtrack;
tracer_id_t backtrack_trc;
+ tracer_id_t realtime_trc;
+ tracer_id_t logwrite_trc;
/**
* ui
View
31 src/main.c
@@ -84,8 +84,10 @@ void signal_quit(int signum)
static void main_dump_stats()
{
#define NANO (1000*1000*1000)
-#define MICRO (1000)
- int64_t unanotime = -1;
+#define MICRO (1000*1000)
+#define MILLI (1000)
+
+ int64_t unanotime = 0;
/* int64_t snanotime = -1; */
#if defined(FUNC_GETRUSAGE_DEFINED)
@@ -94,8 +96,7 @@ static void main_dump_stats()
/* explicit cast to prevent overflow */
/* utime : user time */
/* stime : system time */
- unanotime = ((uint64_t)ru.ru_utime.tv_sec) * NANO + ((uint64_t)ru.ru_utime.tv_usec) * MICRO;
- /* snanotime = ((uint64_t)ru.ru_stime.tv_sec) * NANO + ((uint64_t)ru.ru_stime.tv_usec) * MICRO; */
+ unanotime = ((uint64_t)ru.ru_utime.tv_sec) * NANO + ((uint64_t)ru.ru_utime.tv_usec) * 1000;
#endif
@@ -105,8 +106,9 @@ static void main_dump_stats()
OUTPUT("-----------\n");
if (unanotime > 0)
{
- OUTPUT(" simulation user time : %d.%03d s (%"PRId64" ns)\n",
- unanotime / NANO, unanotime / 1000000, unanotime);
+ int64_t sec = unanotime / NANO;
+ int64_t msec = (unanotime - sec*1000000000) / 1000000;
+ OUTPUT(" simulation user time : %d.%03d s (%"PRId64" ns)\n", sec, msec, unanotime);
/*
* OUTPUT(" system simulation time : %d.%03d s\n",
* ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 1000);
@@ -132,10 +134,12 @@ static void main_run_mode(struct options_t* o)
signal(SIGUSR2,signal_quit);
signal(SIGPIPE,signal_quit);
#endif
-
+
+ struct machine_opt_t m;
+
machine_reset();
machine_state_save();
-
+
/* so far so good, run() */
switch (o->sim_mode)
{
@@ -145,15 +149,14 @@ static void main_run_mode(struct options_t* o)
case SIM_MODE_GDB:
libgdb_target_mode_main(o->gdb_port);
break;
-
+
case SIM_MODE_RUN:
- machine_run_free();
- break;
case SIM_MODE_INSN:
- machine_run_insn(o->sim_insn);
- break;
case SIM_MODE_TIME:
- machine_run_time(o->sim_time);
+ m.insn = o->sim_insn;
+ m.time = o->sim_time;
+ m.realtime = o->realtime;
+ machine_run(&m);
break;
default:
View
37 src/options.c
@@ -38,16 +38,17 @@
#define DEFAULT_MULTICAST_IP "224.0.0.1"
#define DEFAULT_MULTICAST_PORT 9999
#define DEFAULT_NODE_ID 1
-
+#define DEFAULT_REALTIME 0
/* ************************************************** */
/* ************************************************** */
/* ************************************************** */
/* liblogger cannot be used during option parse */
-#define __DEBUG_OPTIONS
-#ifdef DEBUG_OPTIONS
+#define DEBUG_OPTIONS 0
+
+#if DEBUG_OPTIONS != 0
# define OPT_DMSG(x...) fprintf(stderr,x)
#else
# define OPT_DMSG(x...) do { } while(0)
@@ -87,6 +88,13 @@ static struct moption_t modearg_opt = {
.value = NULL
};
+static struct moption_t realtime_opt = {
+ .longname = "realtime",
+ .type = no_argument,
+ .helpstring = "realtime simulation speed",
+ .value = NULL
+};
+
/* traces & logs */
static struct moption_t logfile_opt = {
.longname = "logfile",
@@ -263,6 +271,7 @@ void options_start()
options_add_base(& version_opt );
options_add_base(& mode_opt );
options_add_base(& modearg_opt );
+ options_add_base(& realtime_opt );
options_add_base(& preload_opt );
options_add_base(& noelf_opt );
/* options_add_base(& dump_opt ); */
@@ -377,6 +386,11 @@ void options_print_params(struct options_t* s)
break;
}
+ if (s->realtime)
+ {
+ OPT_PRINT(" realtime mode set\n");
+ }
+
if ((s->do_elfload == 1) && (stat(s->progname, &fs) == -1))
{
fprintf(stdout," ** Cannot stat elf file\n");
@@ -420,6 +434,7 @@ void options_read_cmdline(struct options_t *s, int *argc, char *argv[])
sprintf(s->preload, "none");
s->sim_mode = DEFAULT_SIM_MODE;
+ s->realtime = DEFAULT_REALTIME;
s->gdb_port = DEFAULT_GDB_PORT;
s->sim_insn = DEFAULT_RUN_INSN;
s->sim_time = DEFAULT_RUN_TIME;
@@ -556,7 +571,12 @@ void options_read_cmdline(struct options_t *s, int *argc, char *argv[])
}
}
-
+ if (realtime_opt.isset)
+ {
+ OPT_DMSG(" realtime set\n");
+ s->realtime = 1;
+ }
+
if (verbose_opt.isset)
{
OPT_DMSG(" verbose set\n");
@@ -671,6 +691,15 @@ void options_read_cmdline(struct options_t *s, int *argc, char *argv[])
exit(1);
}
+ if (realtime_opt.isset && (wsnet1_mode_opt.isset || wsnet2_mode_opt.isset))
+ {
+ OPT_WARNING("\n==================================================\n");
+ OPT_WARNING(" wsnet mode cannot be used with the realtime option\n");
+ OPT_WARNING(" realtime mode is disabled\n");
+ OPT_WARNING("\n==================================================\n");
+ s->realtime = 0;
+ }
+
OPT_DMSG("parseindex = %d, argc = %d\n",parseindex,*argc);
if (parseindex < *argc)
{
View
1 src/options.h
@@ -72,6 +72,7 @@ struct options_t {
unsigned short gdb_port;
uint64_t sim_insn;
uint64_t sim_time;
+ int realtime;
};

0 comments on commit f6923d5

Please sign in to comment.