On 18/02/2015 12:56, Pavel Dovgalyuk wrote: > This patch adds calls to replay functions into the icount setup block. > In record mode number of executed instructions is written to the log. > In replay mode number of istructions to execute is taken from the replay log.
So much better! If there is a v10, please add a comment about how the iothread is woken up---before the call to qemu_notify_event() and here in the commit message. Reviewed-by: Paolo Bonzini <pbonz...@redhat.com> Paolo > Signed-off-by: Pavel Dovgalyuk <pavel.dovga...@ispras.ru> > --- > cpus.c | 38 +++++++++++++++++++++++++------------- > replay/replay.c | 26 ++++++++++++++++++++++++++ > replay/replay.h | 4 ++++ > 3 files changed, 55 insertions(+), 13 deletions(-) > > diff --git a/cpus.c b/cpus.c > index 04124ca..511a0c5 100644 > --- a/cpus.c > +++ b/cpus.c > @@ -41,6 +41,7 @@ > #include "qemu/seqlock.h" > #include "qapi-event.h" > #include "hw/nmi.h" > +#include "replay/replay.h" > > #ifndef _WIN32 > #include "qemu/compatfd.h" > @@ -1306,6 +1307,28 @@ int vm_stop_force_state(RunState state) > } > } > > +static int64_t tcg_get_icount_limit(void) > +{ > + int64_t deadline; > + > + if (replay_mode != REPLAY_MODE_PLAY) { > + deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); > + > + /* Maintain prior (possibly buggy) behaviour where if no deadline > + * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more > than > + * INT32_MAX nanoseconds ahead, we still use INT32_MAX > + * nanoseconds. > + */ > + if ((deadline < 0) || (deadline > INT32_MAX)) { > + deadline = INT32_MAX; > + } > + > + return qemu_icount_round(deadline); > + } else { > + return replay_get_instructions(); > + } > +} > + > static int tcg_cpu_exec(CPUArchState *env) > { > CPUState *cpu = ENV_GET_CPU(env); > @@ -1319,24 +1342,12 @@ static int tcg_cpu_exec(CPUArchState *env) > #endif > if (use_icount) { > int64_t count; > - int64_t deadline; > int decr; > timers_state.qemu_icount -= (cpu->icount_decr.u16.low > + cpu->icount_extra); > cpu->icount_decr.u16.low = 0; > cpu->icount_extra = 0; > - deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); > - > - /* Maintain prior (possibly buggy) behaviour where if no deadline > - * was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more > than > - * INT32_MAX nanoseconds ahead, we still use INT32_MAX > - * nanoseconds. > - */ > - if ((deadline < 0) || (deadline > INT32_MAX)) { > - deadline = INT32_MAX; > - } > - > - count = qemu_icount_round(deadline); > + count = tcg_get_icount_limit(); > timers_state.qemu_icount += count; > decr = (count > 0xffff) ? 0xffff : count; > count -= decr; > @@ -1354,6 +1365,7 @@ static int tcg_cpu_exec(CPUArchState *env) > + cpu->icount_extra); > cpu->icount_decr.u32 = 0; > cpu->icount_extra = 0; > + replay_account_executed_instructions(); > } > return ret; > } > diff --git a/replay/replay.c b/replay/replay.c > index a43bbbc..a6a5145 100755 > --- a/replay/replay.c > +++ b/replay/replay.c > @@ -58,3 +58,29 @@ uint64_t replay_get_current_step(void) > { > return cpu_get_icount_raw(); > } > + > +int replay_get_instructions(void) > +{ > + int res = 0; > + replay_mutex_lock(); > + if (skip_async_events(EVENT_INSTRUCTION)) { > + res = replay_state.instructions_count; > + } > + replay_mutex_unlock(); > + return res; > +} > + > +void replay_account_executed_instructions(void) > +{ > + if (replay_mode == REPLAY_MODE_PLAY > + && replay_state.instructions_count > 0) { > + int count = (int)(replay_get_current_step() > + - replay_state.current_step); > + replay_state.instructions_count -= count; > + replay_state.current_step += count; > + if (replay_state.instructions_count == 0) { > + replay_has_unread_data = 0; > + qemu_notify_event(); > + } > + } > +} > diff --git a/replay/replay.h b/replay/replay.h > index a03c748..d19715f 100755 > --- a/replay/replay.h > +++ b/replay/replay.h > @@ -22,5 +22,9 @@ extern ReplayMode replay_mode; > > /*! Returns number of executed instructions. */ > uint64_t replay_get_current_step(void); > +/*! Returns number of instructions to execute in replay mode. */ > +int replay_get_instructions(void); > +/*! Updates instructions counter in replay mode. */ > +void replay_account_executed_instructions(void); > > #endif > > >