aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/core/ptimer.c3
-rw-r--r--include/sysemu/replay.h3
-rw-r--r--replay/replay-events.c25
-rw-r--r--replay/replay-internal.h1
4 files changed, 28 insertions, 4 deletions
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index 8437bd6e8b..edf077cfd0 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -9,6 +9,7 @@
#include "qemu/timer.h"
#include "hw/ptimer.h"
#include "qemu/host-utils.h"
+#include "sysemu/replay.h"
struct ptimer_state
{
@@ -27,7 +28,7 @@ struct ptimer_state
static void ptimer_trigger(ptimer_state *s)
{
if (s->bh) {
- qemu_bh_schedule(s->bh);
+ replay_bh_schedule_event(s->bh);
}
}
diff --git a/include/sysemu/replay.h b/include/sysemu/replay.h
index e2696fe396..fdf46f8089 100644
--- a/include/sysemu/replay.h
+++ b/include/sysemu/replay.h
@@ -15,6 +15,7 @@
#include <stdbool.h>
#include <stdint.h>
#include "qapi-types.h"
+#include "qemu/typedefs.h"
/* replay clock kinds */
enum ReplayClockKind {
@@ -97,5 +98,7 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint);
void replay_disable_events(void);
/*! Returns true when saving events is enabled */
bool replay_events_enabled(void);
+/*! Adds bottom half event to the queue */
+void replay_bh_schedule_event(QEMUBH *bh);
#endif
diff --git a/replay/replay-events.c b/replay/replay-events.c
index 8dcc96d51e..8db2c7ace0 100644
--- a/replay/replay-events.c
+++ b/replay/replay-events.c
@@ -13,6 +13,7 @@
#include "qemu/error-report.h"
#include "sysemu/replay.h"
#include "replay-internal.h"
+#include "block/aio.h"
typedef struct Event {
ReplayAsyncEventKind event_kind;
@@ -35,6 +36,9 @@ static bool events_enabled;
static void replay_run_event(Event *event)
{
switch (event->event_kind) {
+ case REPLAY_ASYNC_EVENT_BH:
+ aio_bh_call(event->opaque);
+ break;
default:
error_report("Replay: invalid async event ID (%d) in the queue",
event->event_kind);
@@ -89,7 +93,6 @@ void replay_clear_events(void)
}
/*! Adds specified async event to the queue */
-#if 0
static void replay_add_event(ReplayAsyncEventKind event_kind,
void *opaque,
void *opaque2, uint64_t id)
@@ -117,7 +120,16 @@ static void replay_add_event(ReplayAsyncEventKind event_kind,
QTAILQ_INSERT_TAIL(&events_list, event, events);
replay_mutex_unlock();
}
-#endif
+
+void replay_bh_schedule_event(QEMUBH *bh)
+{
+ if (replay_mode != REPLAY_MODE_NONE) {
+ uint64_t id = replay_get_current_step();
+ replay_add_event(REPLAY_ASYNC_EVENT_BH, bh, NULL, id);
+ } else {
+ qemu_bh_schedule(bh);
+ }
+}
static void replay_save_event(Event *event, int checkpoint)
{
@@ -129,10 +141,12 @@ static void replay_save_event(Event *event, int checkpoint)
/* save event-specific data */
switch (event->event_kind) {
+ case REPLAY_ASYNC_EVENT_BH:
+ replay_put_qword(event->id);
+ break;
default:
error_report("Unknown ID %d of replay event", read_event_kind);
exit(1);
- break;
}
}
}
@@ -168,6 +182,11 @@ static Event *replay_read_event(int checkpoint)
/* Events that has not to be in the queue */
switch (read_event_kind) {
+ case REPLAY_ASYNC_EVENT_BH:
+ if (read_id == -1) {
+ read_id = replay_get_qword();
+ }
+ break;
default:
error_report("Unknown ID %d of replay event", read_event_kind);
exit(1);
diff --git a/replay/replay-internal.h b/replay/replay-internal.h
index bf64be54d7..7ba60642e1 100644
--- a/replay/replay-internal.h
+++ b/replay/replay-internal.h
@@ -39,6 +39,7 @@ enum ReplayEvents {
/* Asynchronous events IDs */
enum ReplayAsyncEventKind {
+ REPLAY_ASYNC_EVENT_BH,
REPLAY_ASYNC_COUNT
};