]> git.proxmox.com Git - mirror_qemu.git/blame - replay/replay-internal.c
contrib: Clean up includes
[mirror_qemu.git] / replay / replay-internal.c
CommitLineData
c92079f4
PD
1/*
2 * replay-internal.c
3 *
4 * Copyright (c) 2010-2015 Institute for System Programming
5 * of the Russian Academy of Sciences.
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2 or later.
8 * See the COPYING file in the top-level directory.
9 *
10 */
11
12#include "qemu-common.h"
26bc60ac 13#include "sysemu/replay.h"
c92079f4
PD
14#include "replay-internal.h"
15#include "qemu/error-report.h"
16#include "sysemu/sysemu.h"
17
18unsigned int replay_data_kind = -1;
19static unsigned int replay_has_unread_data;
20
c16861ef
PD
21/* Mutex to protect reading and writing events to the log.
22 replay_data_kind and replay_has_unread_data are also protected
23 by this mutex.
24 It also protects replay events queue which stores events to be
25 written or read to the log. */
26static QemuMutex lock;
27
c92079f4
PD
28/* File for replay writing */
29FILE *replay_file;
30
31void replay_put_byte(uint8_t byte)
32{
33 if (replay_file) {
34 putc(byte, replay_file);
35 }
36}
37
38void replay_put_event(uint8_t event)
39{
26bc60ac 40 assert(event < EVENT_COUNT);
c92079f4
PD
41 replay_put_byte(event);
42}
43
44
45void replay_put_word(uint16_t word)
46{
47 replay_put_byte(word >> 8);
48 replay_put_byte(word);
49}
50
51void replay_put_dword(uint32_t dword)
52{
53 replay_put_word(dword >> 16);
54 replay_put_word(dword);
55}
56
57void replay_put_qword(int64_t qword)
58{
59 replay_put_dword(qword >> 32);
60 replay_put_dword(qword);
61}
62
63void replay_put_array(const uint8_t *buf, size_t size)
64{
65 if (replay_file) {
66 replay_put_dword(size);
67 fwrite(buf, 1, size, replay_file);
68 }
69}
70
71uint8_t replay_get_byte(void)
72{
73 uint8_t byte = 0;
74 if (replay_file) {
75 byte = getc(replay_file);
76 }
77 return byte;
78}
79
80uint16_t replay_get_word(void)
81{
82 uint16_t word = 0;
83 if (replay_file) {
84 word = replay_get_byte();
85 word = (word << 8) + replay_get_byte();
86 }
87
88 return word;
89}
90
91uint32_t replay_get_dword(void)
92{
93 uint32_t dword = 0;
94 if (replay_file) {
95 dword = replay_get_word();
96 dword = (dword << 16) + replay_get_word();
97 }
98
99 return dword;
100}
101
102int64_t replay_get_qword(void)
103{
104 int64_t qword = 0;
105 if (replay_file) {
106 qword = replay_get_dword();
107 qword = (qword << 32) + replay_get_dword();
108 }
109
110 return qword;
111}
112
113void replay_get_array(uint8_t *buf, size_t *size)
114{
115 if (replay_file) {
116 *size = replay_get_dword();
117 if (fread(buf, 1, *size, replay_file) != *size) {
118 error_report("replay read error");
119 }
120 }
121}
122
123void replay_get_array_alloc(uint8_t **buf, size_t *size)
124{
125 if (replay_file) {
126 *size = replay_get_dword();
127 *buf = g_malloc(*size);
128 if (fread(*buf, 1, *size, replay_file) != *size) {
129 error_report("replay read error");
130 }
131 }
132}
133
134void replay_check_error(void)
135{
136 if (replay_file) {
137 if (feof(replay_file)) {
138 error_report("replay file is over");
139 qemu_system_vmstop_request_prepare();
140 qemu_system_vmstop_request(RUN_STATE_PAUSED);
141 } else if (ferror(replay_file)) {
142 error_report("replay file is over or something goes wrong");
143 qemu_system_vmstop_request_prepare();
144 qemu_system_vmstop_request(RUN_STATE_INTERNAL_ERROR);
145 }
146 }
147}
148
149void replay_fetch_data_kind(void)
150{
151 if (replay_file) {
152 if (!replay_has_unread_data) {
153 replay_data_kind = replay_get_byte();
26bc60ac
PD
154 if (replay_data_kind == EVENT_INSTRUCTION) {
155 replay_state.instructions_count = replay_get_dword();
156 }
c92079f4
PD
157 replay_check_error();
158 replay_has_unread_data = 1;
26bc60ac
PD
159 if (replay_data_kind >= EVENT_COUNT) {
160 error_report("Replay: unknown event kind %d", replay_data_kind);
161 exit(1);
162 }
c92079f4
PD
163 }
164 }
165}
166
167void replay_finish_event(void)
168{
169 replay_has_unread_data = 0;
170 replay_fetch_data_kind();
171}
c16861ef
PD
172
173void replay_mutex_init(void)
174{
175 qemu_mutex_init(&lock);
176}
177
178void replay_mutex_destroy(void)
179{
180 qemu_mutex_destroy(&lock);
181}
182
183void replay_mutex_lock(void)
184{
185 qemu_mutex_lock(&lock);
186}
187
188void replay_mutex_unlock(void)
189{
190 qemu_mutex_unlock(&lock);
191}
26bc60ac
PD
192
193/*! Saves cached instructions. */
194void replay_save_instructions(void)
195{
196 if (replay_file && replay_mode == REPLAY_MODE_RECORD) {
197 replay_mutex_lock();
198 int diff = (int)(replay_get_current_step() - replay_state.current_step);
199 if (diff > 0) {
200 replay_put_event(EVENT_INSTRUCTION);
201 replay_put_dword(diff);
202 replay_state.current_step += diff;
203 }
204 replay_mutex_unlock();
205 }
206}