]> Git Repo - qemu.git/blob - replay/replay-internal.c
replay: introduce mutex to protect the replay log
[qemu.git] / replay / replay-internal.c
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"
13 #include "replay-internal.h"
14 #include "qemu/error-report.h"
15 #include "sysemu/sysemu.h"
16
17 unsigned int replay_data_kind = -1;
18 static unsigned int replay_has_unread_data;
19
20 /* Mutex to protect reading and writing events to the log.
21    replay_data_kind and replay_has_unread_data are also protected
22    by this mutex.
23    It also protects replay events queue which stores events to be
24    written or read to the log. */
25 static QemuMutex lock;
26
27 /* File for replay writing */
28 FILE *replay_file;
29
30 void replay_put_byte(uint8_t byte)
31 {
32     if (replay_file) {
33         putc(byte, replay_file);
34     }
35 }
36
37 void replay_put_event(uint8_t event)
38 {
39     replay_put_byte(event);
40 }
41
42
43 void replay_put_word(uint16_t word)
44 {
45     replay_put_byte(word >> 8);
46     replay_put_byte(word);
47 }
48
49 void replay_put_dword(uint32_t dword)
50 {
51     replay_put_word(dword >> 16);
52     replay_put_word(dword);
53 }
54
55 void replay_put_qword(int64_t qword)
56 {
57     replay_put_dword(qword >> 32);
58     replay_put_dword(qword);
59 }
60
61 void replay_put_array(const uint8_t *buf, size_t size)
62 {
63     if (replay_file) {
64         replay_put_dword(size);
65         fwrite(buf, 1, size, replay_file);
66     }
67 }
68
69 uint8_t replay_get_byte(void)
70 {
71     uint8_t byte = 0;
72     if (replay_file) {
73         byte = getc(replay_file);
74     }
75     return byte;
76 }
77
78 uint16_t replay_get_word(void)
79 {
80     uint16_t word = 0;
81     if (replay_file) {
82         word = replay_get_byte();
83         word = (word << 8) + replay_get_byte();
84     }
85
86     return word;
87 }
88
89 uint32_t replay_get_dword(void)
90 {
91     uint32_t dword = 0;
92     if (replay_file) {
93         dword = replay_get_word();
94         dword = (dword << 16) + replay_get_word();
95     }
96
97     return dword;
98 }
99
100 int64_t replay_get_qword(void)
101 {
102     int64_t qword = 0;
103     if (replay_file) {
104         qword = replay_get_dword();
105         qword = (qword << 32) + replay_get_dword();
106     }
107
108     return qword;
109 }
110
111 void replay_get_array(uint8_t *buf, size_t *size)
112 {
113     if (replay_file) {
114         *size = replay_get_dword();
115         if (fread(buf, 1, *size, replay_file) != *size) {
116             error_report("replay read error");
117         }
118     }
119 }
120
121 void replay_get_array_alloc(uint8_t **buf, size_t *size)
122 {
123     if (replay_file) {
124         *size = replay_get_dword();
125         *buf = g_malloc(*size);
126         if (fread(*buf, 1, *size, replay_file) != *size) {
127             error_report("replay read error");
128         }
129     }
130 }
131
132 void replay_check_error(void)
133 {
134     if (replay_file) {
135         if (feof(replay_file)) {
136             error_report("replay file is over");
137             qemu_system_vmstop_request_prepare();
138             qemu_system_vmstop_request(RUN_STATE_PAUSED);
139         } else if (ferror(replay_file)) {
140             error_report("replay file is over or something goes wrong");
141             qemu_system_vmstop_request_prepare();
142             qemu_system_vmstop_request(RUN_STATE_INTERNAL_ERROR);
143         }
144     }
145 }
146
147 void replay_fetch_data_kind(void)
148 {
149     if (replay_file) {
150         if (!replay_has_unread_data) {
151             replay_data_kind = replay_get_byte();
152             replay_check_error();
153             replay_has_unread_data = 1;
154         }
155     }
156 }
157
158 void replay_finish_event(void)
159 {
160     replay_has_unread_data = 0;
161     replay_fetch_data_kind();
162 }
163
164 void replay_mutex_init(void)
165 {
166     qemu_mutex_init(&lock);
167 }
168
169 void replay_mutex_destroy(void)
170 {
171     qemu_mutex_destroy(&lock);
172 }
173
174 void replay_mutex_lock(void)
175 {
176     qemu_mutex_lock(&lock);
177 }
178
179 void replay_mutex_unlock(void)
180 {
181     qemu_mutex_unlock(&lock);
182 }
This page took 0.033789 seconds and 4 git commands to generate.