d759c951f3
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>
74 lines
2.4 KiB
C
74 lines
2.4 KiB
C
/*
|
|
* replay-audio.c
|
|
*
|
|
* Copyright (c) 2010-2017 Institute for System Programming
|
|
* of the Russian Academy of Sciences.
|
|
*
|
|
* This work is licensed under the terms of the GNU GPL, version 2 or later.
|
|
* See the COPYING file in the top-level directory.
|
|
*
|
|
*/
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu/error-report.h"
|
|
#include "sysemu/replay.h"
|
|
#include "replay-internal.h"
|
|
#include "sysemu/sysemu.h"
|
|
#include "audio/audio.h"
|
|
|
|
void replay_audio_out(int *played)
|
|
{
|
|
if (replay_mode == REPLAY_MODE_RECORD) {
|
|
g_assert(replay_mutex_locked());
|
|
replay_save_instructions();
|
|
replay_put_event(EVENT_AUDIO_OUT);
|
|
replay_put_dword(*played);
|
|
} else if (replay_mode == REPLAY_MODE_PLAY) {
|
|
g_assert(replay_mutex_locked());
|
|
replay_account_executed_instructions();
|
|
if (replay_next_event_is(EVENT_AUDIO_OUT)) {
|
|
*played = replay_get_dword();
|
|
replay_finish_event();
|
|
} else {
|
|
error_report("Missing audio out event in the replay log");
|
|
abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
void replay_audio_in(int *recorded, void *samples, int *wpos, int size)
|
|
{
|
|
int pos;
|
|
uint64_t left, right;
|
|
if (replay_mode == REPLAY_MODE_RECORD) {
|
|
g_assert(replay_mutex_locked());
|
|
replay_save_instructions();
|
|
replay_put_event(EVENT_AUDIO_IN);
|
|
replay_put_dword(*recorded);
|
|
replay_put_dword(*wpos);
|
|
for (pos = (*wpos - *recorded + size) % size ; pos != *wpos
|
|
; pos = (pos + 1) % size) {
|
|
audio_sample_to_uint64(samples, pos, &left, &right);
|
|
replay_put_qword(left);
|
|
replay_put_qword(right);
|
|
}
|
|
} else if (replay_mode == REPLAY_MODE_PLAY) {
|
|
g_assert(replay_mutex_locked());
|
|
replay_account_executed_instructions();
|
|
if (replay_next_event_is(EVENT_AUDIO_IN)) {
|
|
*recorded = replay_get_dword();
|
|
*wpos = replay_get_dword();
|
|
for (pos = (*wpos - *recorded + size) % size ; pos != *wpos
|
|
; pos = (pos + 1) % size) {
|
|
left = replay_get_qword();
|
|
right = replay_get_qword();
|
|
audio_sample_from_uint64(samples, pos, left, right);
|
|
}
|
|
replay_finish_event();
|
|
} else {
|
|
error_report("Missing audio in event in the replay log");
|
|
abort();
|
|
}
|
|
}
|
|
}
|