Skip to content

Commit

Permalink
replay: simplify async event processing
Browse files Browse the repository at this point in the history
This patch joins replay event id and async event id into single byte in the log.
It makes processing a bit faster and log a bit smaller.

Signed-off-by: Pavel Dovgalyuk <[email protected]>
Reviewed-by: Richard Henderson <[email protected]>

--

v2: minor enum fixes (suggested by Richard Henderson)
Message-Id: <165364838393.688121.8191379555130516329.stgit@pasha-ThinkPad-X280>
Signed-off-by: Paolo Bonzini <[email protected]>
  • Loading branch information
Dovgalyuk authored and bonzini committed Jun 6, 2022
1 parent 60618e2 commit 3e21408
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 42 deletions.
36 changes: 14 additions & 22 deletions replay/replay-events.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,8 @@ static void replay_save_event(Event *event)
{
if (replay_mode != REPLAY_MODE_PLAY) {
/* put the event into the file */
replay_put_event(EVENT_ASYNC);
replay_put_byte(event->event_kind);
g_assert(event->event_kind < REPLAY_ASYNC_COUNT);
replay_put_event(EVENT_ASYNC + event->event_kind);

/* save event-specific data */
switch (event->event_kind) {
Expand Down Expand Up @@ -220,14 +220,10 @@ void replay_save_events(void)
static Event *replay_read_event(void)
{
Event *event;
if (replay_state.read_event_kind == -1) {
replay_state.read_event_kind = replay_get_byte();
replay_state.read_event_id = -1;
replay_check_error();
}
ReplayAsyncEventKind event_kind = replay_state.data_kind - EVENT_ASYNC;

/* Events that has not to be in the queue */
switch (replay_state.read_event_kind) {
switch (event_kind) {
case REPLAY_ASYNC_EVENT_BH:
case REPLAY_ASYNC_EVENT_BH_ONESHOT:
if (replay_state.read_event_id == -1) {
Expand All @@ -236,17 +232,17 @@ static Event *replay_read_event(void)
break;
case REPLAY_ASYNC_EVENT_INPUT:
event = g_new0(Event, 1);
event->event_kind = replay_state.read_event_kind;
event->event_kind = event_kind;
event->opaque = replay_read_input_event();
return event;
case REPLAY_ASYNC_EVENT_INPUT_SYNC:
event = g_new0(Event, 1);
event->event_kind = replay_state.read_event_kind;
event->event_kind = event_kind;
event->opaque = 0;
return event;
case REPLAY_ASYNC_EVENT_CHAR_READ:
event = g_new0(Event, 1);
event->event_kind = replay_state.read_event_kind;
event->event_kind = event_kind;
event->opaque = replay_event_char_read_load();
return event;
case REPLAY_ASYNC_EVENT_BLOCK:
Expand All @@ -256,18 +252,17 @@ static Event *replay_read_event(void)
break;
case REPLAY_ASYNC_EVENT_NET:
event = g_new0(Event, 1);
event->event_kind = replay_state.read_event_kind;
event->event_kind = event_kind;
event->opaque = replay_event_net_load();
return event;
default:
error_report("Unknown ID %d of replay event",
replay_state.read_event_kind);
error_report("Unknown ID %d of replay event", event_kind);
exit(1);
break;
}

QTAILQ_FOREACH(event, &events_list, events) {
if (event->event_kind == replay_state.read_event_kind
if (event->event_kind == event_kind
&& (replay_state.read_event_id == -1
|| replay_state.read_event_id == event->id)) {
break;
Expand All @@ -276,26 +271,23 @@ static Event *replay_read_event(void)

if (event) {
QTAILQ_REMOVE(&events_list, event, events);
} else {
return NULL;
}

/* Read event-specific data */

return event;
}

/* Called with replay mutex locked */
void replay_read_events(void)
{
g_assert(replay_mutex_locked());
while (replay_state.data_kind == EVENT_ASYNC) {
while (replay_state.data_kind >= EVENT_ASYNC
&& replay_state.data_kind <= EVENT_ASYNC_LAST) {
Event *event = replay_read_event();
if (!event) {
break;
}
replay_finish_event();
replay_state.read_event_kind = -1;
replay_state.read_event_id = -1;
replay_run_event(event);

g_free(event);
Expand All @@ -304,7 +296,7 @@ void replay_read_events(void)

void replay_init_events(void)
{
replay_state.read_event_kind = -1;
replay_state.read_event_id = -1;
}

void replay_finish_events(void)
Expand Down
31 changes: 14 additions & 17 deletions replay/replay-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
*
*/

/* Asynchronous events IDs */

typedef enum ReplayAsyncEventKind {
REPLAY_ASYNC_EVENT_BH,
REPLAY_ASYNC_EVENT_BH_ONESHOT,
REPLAY_ASYNC_EVENT_INPUT,
REPLAY_ASYNC_EVENT_INPUT_SYNC,
REPLAY_ASYNC_EVENT_CHAR_READ,
REPLAY_ASYNC_EVENT_BLOCK,
REPLAY_ASYNC_EVENT_NET,
REPLAY_ASYNC_COUNT
} ReplayAsyncEventKind;

/* Any changes to order/number of events will need to bump REPLAY_VERSION */
enum ReplayEvents {
/* for instruction event */
Expand All @@ -22,6 +35,7 @@ enum ReplayEvents {
EVENT_EXCEPTION,
/* for async events */
EVENT_ASYNC,
EVENT_ASYNC_LAST = EVENT_ASYNC + REPLAY_ASYNC_COUNT - 1,
/* for shutdown requests, range allows recovery of ShutdownCause */
EVENT_SHUTDOWN,
EVENT_SHUTDOWN_LAST = EVENT_SHUTDOWN + SHUTDOWN_CAUSE__MAX,
Expand Down Expand Up @@ -49,21 +63,6 @@ enum ReplayEvents {
EVENT_COUNT
};

/* Asynchronous events IDs */

enum ReplayAsyncEventKind {
REPLAY_ASYNC_EVENT_BH,
REPLAY_ASYNC_EVENT_BH_ONESHOT,
REPLAY_ASYNC_EVENT_INPUT,
REPLAY_ASYNC_EVENT_INPUT_SYNC,
REPLAY_ASYNC_EVENT_CHAR_READ,
REPLAY_ASYNC_EVENT_BLOCK,
REPLAY_ASYNC_EVENT_NET,
REPLAY_ASYNC_COUNT
};

typedef enum ReplayAsyncEventKind ReplayAsyncEventKind;

typedef struct ReplayState {
/*! Cached clock values. */
int64_t cached_clock[REPLAY_CLOCK_COUNT];
Expand All @@ -83,8 +82,6 @@ typedef struct ReplayState {
uint64_t block_request_id;
/*! Prior value of the host clock */
uint64_t host_clock_last;
/*! Asynchronous event type read from the log */
int32_t read_event_kind;
/*! Asynchronous event id read from the log */
uint64_t read_event_id;
} ReplayState;
Expand Down
1 change: 0 additions & 1 deletion replay/replay-snapshot.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ static const VMStateDescription vmstate_replay = {
VMSTATE_UINT32(has_unread_data, ReplayState),
VMSTATE_UINT64(file_offset, ReplayState),
VMSTATE_UINT64(block_request_id, ReplayState),
VMSTATE_INT32(read_event_kind, ReplayState),
VMSTATE_UINT64(read_event_id, ReplayState),
VMSTATE_END_OF_LIST()
},
Expand Down
5 changes: 3 additions & 2 deletions replay/replay.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

/* Current version of the replay mechanism.
Increase it when file format changes. */
#define REPLAY_VERSION 0xe0200b
#define REPLAY_VERSION 0xe0200c
/* Size of replay log header */
#define HEADER_SIZE (sizeof(uint32_t) + sizeof(uint64_t))

Expand Down Expand Up @@ -221,7 +221,8 @@ bool replay_has_event(void)
replay_account_executed_instructions();
res = EVENT_CHECKPOINT <= replay_state.data_kind
&& replay_state.data_kind <= EVENT_CHECKPOINT_LAST;
res = res || replay_state.data_kind == EVENT_ASYNC;
res = res || (EVENT_ASYNC <= replay_state.data_kind
&& replay_state.data_kind <= EVENT_ASYNC_LAST);
}
return res;
}
Expand Down

0 comments on commit 3e21408

Please sign in to comment.