mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
replay: push replay_mutex_lock up the call tree
Now instead of using the replay_lock to guard the output of the log we now use it to protect the whole execution section. This replaces what the BQL used to do when it was held during TCG execution. We also introduce some rules for locking order - mainly that you cannot take the replay_mutex while holding the BQL. This leads to some slight sophistry during start-up and extending the replay_mutex_destroy function to unlock the mutex without checking for the BQL condition so it can be cleanly dropped in the non-replay case. Signed-off-by: Alex Bennée <alex.bennee@linaro.org> Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> Tested-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru> Message-Id: <20180227095248.1060.40374.stgit@pasha-VirtualBox> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
parent
1a423896fa
commit
d759c951f3
10 changed files with 109 additions and 76 deletions
|
@ -81,7 +81,7 @@ int replay_get_instructions(void)
|
|||
void replay_account_executed_instructions(void)
|
||||
{
|
||||
if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
replay_mutex_lock();
|
||||
g_assert(replay_mutex_locked());
|
||||
if (replay_state.instructions_count > 0) {
|
||||
int count = (int)(replay_get_current_step()
|
||||
- replay_state.current_step);
|
||||
|
@ -100,24 +100,22 @@ void replay_account_executed_instructions(void)
|
|||
qemu_notify_event();
|
||||
}
|
||||
}
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
bool replay_exception(void)
|
||||
{
|
||||
|
||||
if (replay_mode == REPLAY_MODE_RECORD) {
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_save_instructions();
|
||||
replay_mutex_lock();
|
||||
replay_put_event(EVENT_EXCEPTION);
|
||||
replay_mutex_unlock();
|
||||
return true;
|
||||
} else if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
g_assert(replay_mutex_locked());
|
||||
bool res = replay_has_exception();
|
||||
if (res) {
|
||||
replay_mutex_lock();
|
||||
replay_finish_event();
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -129,10 +127,9 @@ bool replay_has_exception(void)
|
|||
{
|
||||
bool res = false;
|
||||
if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_account_executed_instructions();
|
||||
replay_mutex_lock();
|
||||
res = replay_next_event_is(EVENT_EXCEPTION);
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
|
||||
return res;
|
||||
|
@ -141,17 +138,15 @@ bool replay_has_exception(void)
|
|||
bool replay_interrupt(void)
|
||||
{
|
||||
if (replay_mode == REPLAY_MODE_RECORD) {
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_save_instructions();
|
||||
replay_mutex_lock();
|
||||
replay_put_event(EVENT_INTERRUPT);
|
||||
replay_mutex_unlock();
|
||||
return true;
|
||||
} else if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
g_assert(replay_mutex_locked());
|
||||
bool res = replay_has_interrupt();
|
||||
if (res) {
|
||||
replay_mutex_lock();
|
||||
replay_finish_event();
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -163,10 +158,9 @@ bool replay_has_interrupt(void)
|
|||
{
|
||||
bool res = false;
|
||||
if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_account_executed_instructions();
|
||||
replay_mutex_lock();
|
||||
res = replay_next_event_is(EVENT_INTERRUPT);
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
@ -174,9 +168,8 @@ bool replay_has_interrupt(void)
|
|||
void replay_shutdown_request(ShutdownCause cause)
|
||||
{
|
||||
if (replay_mode == REPLAY_MODE_RECORD) {
|
||||
replay_mutex_lock();
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_put_event(EVENT_SHUTDOWN + cause);
|
||||
replay_mutex_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -190,9 +183,9 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
|
|||
return true;
|
||||
}
|
||||
|
||||
replay_mutex_lock();
|
||||
|
||||
if (replay_mode == REPLAY_MODE_PLAY) {
|
||||
g_assert(replay_mutex_locked());
|
||||
if (replay_next_event_is(EVENT_CHECKPOINT + checkpoint)) {
|
||||
replay_finish_event();
|
||||
} else if (replay_state.data_kind != EVENT_ASYNC) {
|
||||
|
@ -205,12 +198,12 @@ bool replay_checkpoint(ReplayCheckpoint checkpoint)
|
|||
checkpoint were processed */
|
||||
res = replay_state.data_kind != EVENT_ASYNC;
|
||||
} else if (replay_mode == REPLAY_MODE_RECORD) {
|
||||
g_assert(replay_mutex_locked());
|
||||
replay_put_event(EVENT_CHECKPOINT + checkpoint);
|
||||
replay_save_events(checkpoint);
|
||||
res = true;
|
||||
}
|
||||
out:
|
||||
replay_mutex_unlock();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -233,8 +226,6 @@ static void replay_enable(const char *fname, int mode)
|
|||
|
||||
atexit(replay_finish);
|
||||
|
||||
replay_mutex_init();
|
||||
|
||||
replay_file = fopen(fname, fmode);
|
||||
if (replay_file == NULL) {
|
||||
fprintf(stderr, "Replay: open %s: %s\n", fname, strerror(errno));
|
||||
|
@ -242,8 +233,9 @@ static void replay_enable(const char *fname, int mode)
|
|||
}
|
||||
|
||||
replay_filename = g_strdup(fname);
|
||||
|
||||
replay_mode = mode;
|
||||
replay_mutex_init();
|
||||
|
||||
replay_state.data_kind = -1;
|
||||
replay_state.instructions_count = 0;
|
||||
replay_state.current_step = 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue