diff --git a/src/emu/CMakeLists.txt b/src/emu/CMakeLists.txt index 71133b3..c65c99f 100644 --- a/src/emu/CMakeLists.txt +++ b/src/emu/CMakeLists.txt @@ -17,6 +17,7 @@ add_library(emu STATIC emu.c emu_args.c emu_ev.c + emu_stat.c model.c model_cpu.c model_thread.c diff --git a/src/emu/emu.c b/src/emu/emu.c index 254d41f..29879aa 100644 --- a/src/emu/emu.c +++ b/src/emu/emu.c @@ -51,6 +51,8 @@ emu_init(struct emu *emu, int argc, char *argv[]) return -1; } + emu_stat_init(&emu->stat, 0.5); + model_init(&emu->model); /* Register all the models */ @@ -138,6 +140,8 @@ emu_step(struct emu *emu) dbg("----- mvc=%s dclock=%ld -----", emu->ev->mcv, emu->ev->dclock); + emu_stat_update(&emu->stat, &emu->player); + /* Advance recorder clock */ if (recorder_advance(&emu->recorder, emu->ev->dclock) != 0) { err("recorder_advance failed"); @@ -163,6 +167,8 @@ emu_step(struct emu *emu) int emu_finish(struct emu *emu) { + emu_stat_report(&emu->stat, &emu->player); + if (model_finish(&emu->model, emu) != 0) { err("model_finish failed"); return -1; diff --git a/src/emu/emu.h b/src/emu/emu.h index 27eb18a..1791cbd 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -12,6 +12,7 @@ #include "model.h" #include "emu_ev.h" #include "recorder.h" +#include "emu_stat.h" enum error_values { ST_BAD = 666, @@ -27,6 +28,7 @@ struct emu { struct player player; struct model model; struct recorder recorder; + struct emu_stat stat; /* Quick access */ struct stream *stream; diff --git a/src/emu/emu_stat.c b/src/emu/emu_stat.c new file mode 100644 index 0000000..1b938b0 --- /dev/null +++ b/src/emu/emu_stat.c @@ -0,0 +1,51 @@ +/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#define _POSIX_C_SOURCE 200112L + +#include "emu_stat.h" + +#include +#include + +static double +get_time(void) +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (double) ts.tv_sec + (double) ts.tv_nsec * 1.0e-9; +} + +void +emu_stat_init(struct emu_stat *stat, double period_seconds) +{ + memset(stat, 0, sizeof(struct emu_stat)); + + stat->period = period_seconds; +} + +void +emu_stat_report(struct emu_stat *stat, struct player *player) +{ + double t = get_time(); + + stat->in_progress = player_progress(player); + + double iprog = stat->in_progress * 100.0; + + err("%.1f%% done", iprog); + + stat->last_time = t; +} + +void +emu_stat_update(struct emu_stat *stat, struct player *player) +{ + double t = get_time(); + + /* Not yet */ + if (t - stat->last_time < stat->period) + return; + + emu_stat_report(stat, player); +} diff --git a/src/emu/emu_stat.h b/src/emu/emu_stat.h new file mode 100644 index 0000000..c53059c --- /dev/null +++ b/src/emu/emu_stat.h @@ -0,0 +1,20 @@ +/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef EMU_STAT_H +#define EMU_STAT_H + +#include "player.h" + +/* Easier to parse emulation event */ +struct emu_stat { + double in_progress; + double period; + double last_time; +}; + +void emu_stat_init(struct emu_stat *stat, double period_seconds); +void emu_stat_update(struct emu_stat *stat, struct player *player); +void emu_stat_report(struct emu_stat *stat, struct player *player); + +#endif /* EMU_STAT_H */ diff --git a/src/emu/player.c b/src/emu/player.c index 91d3b82..3253482 100644 --- a/src/emu/player.c +++ b/src/emu/player.c @@ -41,8 +41,7 @@ step_stream(struct player *player, struct stream *stream) int ret = stream_step(stream); if (ret < 0) { - err("step_stream: cannot step stream '%s'\n", - stream->relpath); + err("cannot step stream '%s'", stream->relpath); return -1; } else if (ret > 0) { return ret; @@ -98,6 +97,7 @@ player_init(struct player *player, struct trace *trace) player->first_event = 1; player->stream = NULL; + player->trace = trace; /* Load initial streams and events */ struct stream *stream; @@ -107,7 +107,7 @@ player_init(struct player *player, struct trace *trace) /* No more events */ continue; } else if (ret < 0) { - err("player_init: step_stream failed\n"); + err("step_stream failed"); return -1; } } @@ -165,7 +165,7 @@ player_step(struct player *player) { /* Add the stream back if still active */ if (player->stream != NULL && step_stream(player, player->stream) < 0) { - err("player_step: step_stream() failed\n"); + err("step_stream() failed"); return -1; } @@ -179,12 +179,12 @@ player_step(struct player *player) struct stream *stream = heap_elem(node, struct stream, hh); if (stream == NULL) { - err("player_step: heap_elem() returned NULL\n"); + err("heap_elem() returned NULL"); return -1; } if (update_clocks(player, stream) != 0) { - err("player_step: update_clocks() failed\n"); + err("update_clocks() failed"); return -1; } @@ -208,3 +208,23 @@ player_stream(struct player *player) { return player->stream; } + +double +player_progress(struct player *player) +{ + int64_t n = 0; + double done = 0.0; + struct trace *trace = player->trace; + struct stream *stream; + DL_FOREACH(trace->streams, stream) { + done += stream_progress(stream); + n++; + } + + if (n == 0) + return 1.0; + + done /= (double) n; + + return done; +} diff --git a/src/emu/player.h b/src/emu/player.h index 72f5f02..3554669 100644 --- a/src/emu/player.h +++ b/src/emu/player.h @@ -10,6 +10,7 @@ #include struct player { + struct trace *trace; heap_head_t heap; int64_t firstclock; int64_t lastclock; @@ -23,5 +24,6 @@ int player_init(struct player *player, struct trace *trace); int player_step(struct player *player); struct emu_ev *player_ev(struct player *player); struct stream *player_stream(struct player *player); +double player_progress(struct player *player); #endif /* EMU_PLAYER_H */