root / simpletrace.c @ a74cdab4
History | View | Annotate | Download (8.6 kB)
1 | 26f7227b | Stefan Hajnoczi | /*
|
---|---|---|---|
2 | 26f7227b | Stefan Hajnoczi | * Simple trace backend
|
3 | 26f7227b | Stefan Hajnoczi | *
|
4 | 26f7227b | Stefan Hajnoczi | * Copyright IBM, Corp. 2010
|
5 | 26f7227b | Stefan Hajnoczi | *
|
6 | 26f7227b | Stefan Hajnoczi | * This work is licensed under the terms of the GNU GPL, version 2. See
|
7 | 26f7227b | Stefan Hajnoczi | * the COPYING file in the top-level directory.
|
8 | 26f7227b | Stefan Hajnoczi | *
|
9 | 26f7227b | Stefan Hajnoczi | */
|
10 | 26f7227b | Stefan Hajnoczi | |
11 | 26f7227b | Stefan Hajnoczi | #include <stdlib.h> |
12 | 26f7227b | Stefan Hajnoczi | #include <stdint.h> |
13 | 26f7227b | Stefan Hajnoczi | #include <stdio.h> |
14 | 26f7227b | Stefan Hajnoczi | #include <time.h> |
15 | 0b5538c3 | Stefan Hajnoczi | #include <signal.h> |
16 | 0b5538c3 | Stefan Hajnoczi | #include <pthread.h> |
17 | c57c846a | Blue Swirl | #include "qemu-timer.h" |
18 | 26f7227b | Stefan Hajnoczi | #include "trace.h" |
19 | 26f7227b | Stefan Hajnoczi | |
20 | 26f7227b | Stefan Hajnoczi | /** Trace file header event ID */
|
21 | 26f7227b | Stefan Hajnoczi | #define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */ |
22 | 26f7227b | Stefan Hajnoczi | |
23 | 26f7227b | Stefan Hajnoczi | /** Trace file magic number */
|
24 | 26f7227b | Stefan Hajnoczi | #define HEADER_MAGIC 0xf2b177cb0aa429b4ULL |
25 | 26f7227b | Stefan Hajnoczi | |
26 | 26f7227b | Stefan Hajnoczi | /** Trace file version number, bump if format changes */
|
27 | 26f7227b | Stefan Hajnoczi | #define HEADER_VERSION 0 |
28 | 26f7227b | Stefan Hajnoczi | |
29 | 0b5538c3 | Stefan Hajnoczi | /** Records were dropped event ID */
|
30 | 0b5538c3 | Stefan Hajnoczi | #define DROPPED_EVENT_ID (~(uint64_t)0 - 1) |
31 | 0b5538c3 | Stefan Hajnoczi | |
32 | 0b5538c3 | Stefan Hajnoczi | /** Trace record is valid */
|
33 | 0b5538c3 | Stefan Hajnoczi | #define TRACE_RECORD_VALID ((uint64_t)1 << 63) |
34 | 0b5538c3 | Stefan Hajnoczi | |
35 | 26f7227b | Stefan Hajnoczi | /** Trace buffer entry */
|
36 | 26f7227b | Stefan Hajnoczi | typedef struct { |
37 | 26f7227b | Stefan Hajnoczi | uint64_t event; |
38 | 26f7227b | Stefan Hajnoczi | uint64_t timestamp_ns; |
39 | 26f7227b | Stefan Hajnoczi | uint64_t x1; |
40 | 26f7227b | Stefan Hajnoczi | uint64_t x2; |
41 | 26f7227b | Stefan Hajnoczi | uint64_t x3; |
42 | 26f7227b | Stefan Hajnoczi | uint64_t x4; |
43 | 26f7227b | Stefan Hajnoczi | uint64_t x5; |
44 | 26f7227b | Stefan Hajnoczi | uint64_t x6; |
45 | 26f7227b | Stefan Hajnoczi | } TraceRecord; |
46 | 26f7227b | Stefan Hajnoczi | |
47 | 26f7227b | Stefan Hajnoczi | enum {
|
48 | 0b5538c3 | Stefan Hajnoczi | TRACE_BUF_LEN = 4096,
|
49 | 0b5538c3 | Stefan Hajnoczi | TRACE_BUF_FLUSH_THRESHOLD = TRACE_BUF_LEN / 4,
|
50 | 26f7227b | Stefan Hajnoczi | }; |
51 | 26f7227b | Stefan Hajnoczi | |
52 | 0b5538c3 | Stefan Hajnoczi | /*
|
53 | 0b5538c3 | Stefan Hajnoczi | * Trace records are written out by a dedicated thread. The thread waits for
|
54 | 0b5538c3 | Stefan Hajnoczi | * records to become available, writes them out, and then waits again.
|
55 | 0b5538c3 | Stefan Hajnoczi | */
|
56 | 0b5538c3 | Stefan Hajnoczi | static pthread_mutex_t trace_lock = PTHREAD_MUTEX_INITIALIZER;
|
57 | 0b5538c3 | Stefan Hajnoczi | static pthread_cond_t trace_available_cond = PTHREAD_COND_INITIALIZER;
|
58 | 0b5538c3 | Stefan Hajnoczi | static pthread_cond_t trace_empty_cond = PTHREAD_COND_INITIALIZER;
|
59 | 0b5538c3 | Stefan Hajnoczi | static bool trace_available; |
60 | 0b5538c3 | Stefan Hajnoczi | static bool trace_writeout_enabled; |
61 | 0b5538c3 | Stefan Hajnoczi | |
62 | 26f7227b | Stefan Hajnoczi | static TraceRecord trace_buf[TRACE_BUF_LEN];
|
63 | 26f7227b | Stefan Hajnoczi | static unsigned int trace_idx; |
64 | 26f7227b | Stefan Hajnoczi | static FILE *trace_fp;
|
65 | c5ceb523 | Stefan Hajnoczi | static char *trace_file_name = NULL; |
66 | 26f7227b | Stefan Hajnoczi | |
67 | c5ceb523 | Stefan Hajnoczi | /**
|
68 | 0b5538c3 | Stefan Hajnoczi | * Read a trace record from the trace buffer
|
69 | 0b5538c3 | Stefan Hajnoczi | *
|
70 | 0b5538c3 | Stefan Hajnoczi | * @idx Trace buffer index
|
71 | 0b5538c3 | Stefan Hajnoczi | * @record Trace record to fill
|
72 | 0b5538c3 | Stefan Hajnoczi | *
|
73 | 0b5538c3 | Stefan Hajnoczi | * Returns false if the record is not valid.
|
74 | c5ceb523 | Stefan Hajnoczi | */
|
75 | 0b5538c3 | Stefan Hajnoczi | static bool get_trace_record(unsigned int idx, TraceRecord *record) |
76 | 9410b56c | Prerna Saxena | { |
77 | 0b5538c3 | Stefan Hajnoczi | if (!(trace_buf[idx].event & TRACE_RECORD_VALID)) {
|
78 | 0b5538c3 | Stefan Hajnoczi | return false; |
79 | 9410b56c | Prerna Saxena | } |
80 | 9410b56c | Prerna Saxena | |
81 | 0b5538c3 | Stefan Hajnoczi | __sync_synchronize(); /* read memory barrier before accessing record */
|
82 | 0b5538c3 | Stefan Hajnoczi | |
83 | 0b5538c3 | Stefan Hajnoczi | *record = trace_buf[idx]; |
84 | 0b5538c3 | Stefan Hajnoczi | record->event &= ~TRACE_RECORD_VALID; |
85 | c5ceb523 | Stefan Hajnoczi | return true; |
86 | 9410b56c | Prerna Saxena | } |
87 | 9410b56c | Prerna Saxena | |
88 | 0b5538c3 | Stefan Hajnoczi | /**
|
89 | 0b5538c3 | Stefan Hajnoczi | * Kick writeout thread
|
90 | 0b5538c3 | Stefan Hajnoczi | *
|
91 | 0b5538c3 | Stefan Hajnoczi | * @wait Whether to wait for writeout thread to complete
|
92 | 0b5538c3 | Stefan Hajnoczi | */
|
93 | 0b5538c3 | Stefan Hajnoczi | static void flush_trace_file(bool wait) |
94 | 26f7227b | Stefan Hajnoczi | { |
95 | 0b5538c3 | Stefan Hajnoczi | pthread_mutex_lock(&trace_lock); |
96 | 0b5538c3 | Stefan Hajnoczi | trace_available = true;
|
97 | 0b5538c3 | Stefan Hajnoczi | pthread_cond_signal(&trace_available_cond); |
98 | c5ceb523 | Stefan Hajnoczi | |
99 | 0b5538c3 | Stefan Hajnoczi | if (wait) {
|
100 | 0b5538c3 | Stefan Hajnoczi | pthread_cond_wait(&trace_empty_cond, &trace_lock); |
101 | 26f7227b | Stefan Hajnoczi | } |
102 | 0b5538c3 | Stefan Hajnoczi | |
103 | 0b5538c3 | Stefan Hajnoczi | pthread_mutex_unlock(&trace_lock); |
104 | c5ceb523 | Stefan Hajnoczi | } |
105 | c5ceb523 | Stefan Hajnoczi | |
106 | 0b5538c3 | Stefan Hajnoczi | static void wait_for_trace_records_available(void) |
107 | c5ceb523 | Stefan Hajnoczi | { |
108 | 0b5538c3 | Stefan Hajnoczi | pthread_mutex_lock(&trace_lock); |
109 | 0b5538c3 | Stefan Hajnoczi | while (!(trace_available && trace_writeout_enabled)) {
|
110 | 0b5538c3 | Stefan Hajnoczi | pthread_cond_signal(&trace_empty_cond); |
111 | 0b5538c3 | Stefan Hajnoczi | pthread_cond_wait(&trace_available_cond, &trace_lock); |
112 | c5ceb523 | Stefan Hajnoczi | } |
113 | 0b5538c3 | Stefan Hajnoczi | trace_available = false;
|
114 | 0b5538c3 | Stefan Hajnoczi | pthread_mutex_unlock(&trace_lock); |
115 | 26f7227b | Stefan Hajnoczi | } |
116 | 26f7227b | Stefan Hajnoczi | |
117 | 0b5538c3 | Stefan Hajnoczi | static void *writeout_thread(void *opaque) |
118 | 26f7227b | Stefan Hajnoczi | { |
119 | 0b5538c3 | Stefan Hajnoczi | TraceRecord record; |
120 | 0b5538c3 | Stefan Hajnoczi | unsigned int writeout_idx = 0; |
121 | 0b5538c3 | Stefan Hajnoczi | unsigned int num_available, idx; |
122 | 0b5538c3 | Stefan Hajnoczi | size_t unused; |
123 | 0b5538c3 | Stefan Hajnoczi | |
124 | 0b5538c3 | Stefan Hajnoczi | for (;;) {
|
125 | 0b5538c3 | Stefan Hajnoczi | wait_for_trace_records_available(); |
126 | 0b5538c3 | Stefan Hajnoczi | |
127 | 0b5538c3 | Stefan Hajnoczi | num_available = trace_idx - writeout_idx; |
128 | 0b5538c3 | Stefan Hajnoczi | if (num_available > TRACE_BUF_LEN) {
|
129 | 0b5538c3 | Stefan Hajnoczi | record = (TraceRecord){ |
130 | 0b5538c3 | Stefan Hajnoczi | .event = DROPPED_EVENT_ID, |
131 | 0b5538c3 | Stefan Hajnoczi | .x1 = num_available, |
132 | 0b5538c3 | Stefan Hajnoczi | }; |
133 | 0b5538c3 | Stefan Hajnoczi | unused = fwrite(&record, sizeof(record), 1, trace_fp); |
134 | 0b5538c3 | Stefan Hajnoczi | writeout_idx += num_available; |
135 | 0b5538c3 | Stefan Hajnoczi | } |
136 | 26f7227b | Stefan Hajnoczi | |
137 | 0b5538c3 | Stefan Hajnoczi | idx = writeout_idx % TRACE_BUF_LEN; |
138 | 0b5538c3 | Stefan Hajnoczi | while (get_trace_record(idx, &record)) {
|
139 | 0b5538c3 | Stefan Hajnoczi | trace_buf[idx].event = 0; /* clear valid bit */ |
140 | 0b5538c3 | Stefan Hajnoczi | unused = fwrite(&record, sizeof(record), 1, trace_fp); |
141 | 0b5538c3 | Stefan Hajnoczi | idx = ++writeout_idx % TRACE_BUF_LEN; |
142 | 0b5538c3 | Stefan Hajnoczi | } |
143 | 26f7227b | Stefan Hajnoczi | |
144 | 0b5538c3 | Stefan Hajnoczi | fflush(trace_fp); |
145 | 26f7227b | Stefan Hajnoczi | } |
146 | 0b5538c3 | Stefan Hajnoczi | return NULL; |
147 | 26f7227b | Stefan Hajnoczi | } |
148 | 26f7227b | Stefan Hajnoczi | |
149 | 26f7227b | Stefan Hajnoczi | static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, |
150 | 26f7227b | Stefan Hajnoczi | uint64_t x4, uint64_t x5, uint64_t x6) |
151 | 26f7227b | Stefan Hajnoczi | { |
152 | 0b5538c3 | Stefan Hajnoczi | unsigned int idx; |
153 | 0b5538c3 | Stefan Hajnoczi | uint64_t timestamp; |
154 | 26f7227b | Stefan Hajnoczi | |
155 | 22890ab5 | Prerna Saxena | if (!trace_list[event].state) {
|
156 | 22890ab5 | Prerna Saxena | return;
|
157 | 22890ab5 | Prerna Saxena | } |
158 | 22890ab5 | Prerna Saxena | |
159 | 0b5538c3 | Stefan Hajnoczi | timestamp = get_clock(); |
160 | 0b5538c3 | Stefan Hajnoczi | |
161 | 0b5538c3 | Stefan Hajnoczi | idx = __sync_fetch_and_add(&trace_idx, 1) % TRACE_BUF_LEN;
|
162 | 0b5538c3 | Stefan Hajnoczi | trace_buf[idx] = (TraceRecord){ |
163 | 0b5538c3 | Stefan Hajnoczi | .event = event, |
164 | 0b5538c3 | Stefan Hajnoczi | .timestamp_ns = timestamp, |
165 | 0b5538c3 | Stefan Hajnoczi | .x1 = x1, |
166 | 0b5538c3 | Stefan Hajnoczi | .x2 = x2, |
167 | 0b5538c3 | Stefan Hajnoczi | .x3 = x3, |
168 | 0b5538c3 | Stefan Hajnoczi | .x4 = x4, |
169 | 0b5538c3 | Stefan Hajnoczi | .x5 = x5, |
170 | 0b5538c3 | Stefan Hajnoczi | .x6 = x6, |
171 | 0b5538c3 | Stefan Hajnoczi | }; |
172 | 0b5538c3 | Stefan Hajnoczi | __sync_synchronize(); /* write barrier before marking as valid */
|
173 | 0b5538c3 | Stefan Hajnoczi | trace_buf[idx].event |= TRACE_RECORD_VALID; |
174 | 0b5538c3 | Stefan Hajnoczi | |
175 | 0b5538c3 | Stefan Hajnoczi | if ((idx + 1) % TRACE_BUF_FLUSH_THRESHOLD == 0) { |
176 | 0b5538c3 | Stefan Hajnoczi | flush_trace_file(false);
|
177 | 26f7227b | Stefan Hajnoczi | } |
178 | 26f7227b | Stefan Hajnoczi | } |
179 | 26f7227b | Stefan Hajnoczi | |
180 | 26f7227b | Stefan Hajnoczi | void trace0(TraceEventID event)
|
181 | 26f7227b | Stefan Hajnoczi | { |
182 | 26f7227b | Stefan Hajnoczi | trace(event, 0, 0, 0, 0, 0, 0); |
183 | 26f7227b | Stefan Hajnoczi | } |
184 | 26f7227b | Stefan Hajnoczi | |
185 | 26f7227b | Stefan Hajnoczi | void trace1(TraceEventID event, uint64_t x1)
|
186 | 26f7227b | Stefan Hajnoczi | { |
187 | 26f7227b | Stefan Hajnoczi | trace(event, x1, 0, 0, 0, 0, 0); |
188 | 26f7227b | Stefan Hajnoczi | } |
189 | 26f7227b | Stefan Hajnoczi | |
190 | 26f7227b | Stefan Hajnoczi | void trace2(TraceEventID event, uint64_t x1, uint64_t x2)
|
191 | 26f7227b | Stefan Hajnoczi | { |
192 | 26f7227b | Stefan Hajnoczi | trace(event, x1, x2, 0, 0, 0, 0); |
193 | 26f7227b | Stefan Hajnoczi | } |
194 | 26f7227b | Stefan Hajnoczi | |
195 | 26f7227b | Stefan Hajnoczi | void trace3(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3)
|
196 | 26f7227b | Stefan Hajnoczi | { |
197 | 26f7227b | Stefan Hajnoczi | trace(event, x1, x2, x3, 0, 0, 0); |
198 | 26f7227b | Stefan Hajnoczi | } |
199 | 26f7227b | Stefan Hajnoczi | |
200 | 26f7227b | Stefan Hajnoczi | void trace4(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4)
|
201 | 26f7227b | Stefan Hajnoczi | { |
202 | 26f7227b | Stefan Hajnoczi | trace(event, x1, x2, x3, x4, 0, 0); |
203 | 26f7227b | Stefan Hajnoczi | } |
204 | 26f7227b | Stefan Hajnoczi | |
205 | 26f7227b | Stefan Hajnoczi | void trace5(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5)
|
206 | 26f7227b | Stefan Hajnoczi | { |
207 | 26f7227b | Stefan Hajnoczi | trace(event, x1, x2, x3, x4, x5, 0);
|
208 | 26f7227b | Stefan Hajnoczi | } |
209 | 26f7227b | Stefan Hajnoczi | |
210 | 26f7227b | Stefan Hajnoczi | void trace6(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3, uint64_t x4, uint64_t x5, uint64_t x6)
|
211 | 26f7227b | Stefan Hajnoczi | { |
212 | 26f7227b | Stefan Hajnoczi | trace(event, x1, x2, x3, x4, x5, x6); |
213 | 26f7227b | Stefan Hajnoczi | } |
214 | 26f7227b | Stefan Hajnoczi | |
215 | 0b5538c3 | Stefan Hajnoczi | void st_set_trace_file_enabled(bool enable) |
216 | 0b5538c3 | Stefan Hajnoczi | { |
217 | 0b5538c3 | Stefan Hajnoczi | if (enable == !!trace_fp) {
|
218 | 0b5538c3 | Stefan Hajnoczi | return; /* no change */ |
219 | 0b5538c3 | Stefan Hajnoczi | } |
220 | 0b5538c3 | Stefan Hajnoczi | |
221 | 0b5538c3 | Stefan Hajnoczi | /* Halt trace writeout */
|
222 | 0b5538c3 | Stefan Hajnoczi | flush_trace_file(true);
|
223 | 0b5538c3 | Stefan Hajnoczi | trace_writeout_enabled = false;
|
224 | 0b5538c3 | Stefan Hajnoczi | flush_trace_file(true);
|
225 | 0b5538c3 | Stefan Hajnoczi | |
226 | 0b5538c3 | Stefan Hajnoczi | if (enable) {
|
227 | 0b5538c3 | Stefan Hajnoczi | static const TraceRecord header = { |
228 | 0b5538c3 | Stefan Hajnoczi | .event = HEADER_EVENT_ID, |
229 | 0b5538c3 | Stefan Hajnoczi | .timestamp_ns = HEADER_MAGIC, |
230 | 0b5538c3 | Stefan Hajnoczi | .x1 = HEADER_VERSION, |
231 | 0b5538c3 | Stefan Hajnoczi | }; |
232 | 0b5538c3 | Stefan Hajnoczi | |
233 | 0b5538c3 | Stefan Hajnoczi | trace_fp = fopen(trace_file_name, "w");
|
234 | 0b5538c3 | Stefan Hajnoczi | if (!trace_fp) {
|
235 | 0b5538c3 | Stefan Hajnoczi | return;
|
236 | 0b5538c3 | Stefan Hajnoczi | } |
237 | 0b5538c3 | Stefan Hajnoczi | |
238 | 0b5538c3 | Stefan Hajnoczi | if (fwrite(&header, sizeof header, 1, trace_fp) != 1) { |
239 | 0b5538c3 | Stefan Hajnoczi | fclose(trace_fp); |
240 | 0b5538c3 | Stefan Hajnoczi | trace_fp = NULL;
|
241 | 0b5538c3 | Stefan Hajnoczi | return;
|
242 | 0b5538c3 | Stefan Hajnoczi | } |
243 | 0b5538c3 | Stefan Hajnoczi | |
244 | 0b5538c3 | Stefan Hajnoczi | /* Resume trace writeout */
|
245 | 0b5538c3 | Stefan Hajnoczi | trace_writeout_enabled = true;
|
246 | 0b5538c3 | Stefan Hajnoczi | flush_trace_file(false);
|
247 | 0b5538c3 | Stefan Hajnoczi | } else {
|
248 | 0b5538c3 | Stefan Hajnoczi | fclose(trace_fp); |
249 | 0b5538c3 | Stefan Hajnoczi | trace_fp = NULL;
|
250 | 0b5538c3 | Stefan Hajnoczi | } |
251 | 0b5538c3 | Stefan Hajnoczi | } |
252 | 0b5538c3 | Stefan Hajnoczi | |
253 | 26f7227b | Stefan Hajnoczi | /**
|
254 | 0b5538c3 | Stefan Hajnoczi | * Set the name of a trace file
|
255 | 0b5538c3 | Stefan Hajnoczi | *
|
256 | 0b5538c3 | Stefan Hajnoczi | * @file The trace file name or NULL for the default name-<pid> set at
|
257 | 0b5538c3 | Stefan Hajnoczi | * config time
|
258 | 26f7227b | Stefan Hajnoczi | */
|
259 | 0b5538c3 | Stefan Hajnoczi | bool st_set_trace_file(const char *file) |
260 | 26f7227b | Stefan Hajnoczi | { |
261 | 0b5538c3 | Stefan Hajnoczi | st_set_trace_file_enabled(false);
|
262 | 0b5538c3 | Stefan Hajnoczi | |
263 | 0b5538c3 | Stefan Hajnoczi | free(trace_file_name); |
264 | 0b5538c3 | Stefan Hajnoczi | |
265 | 0b5538c3 | Stefan Hajnoczi | if (!file) {
|
266 | 0b5538c3 | Stefan Hajnoczi | if (asprintf(&trace_file_name, CONFIG_TRACE_FILE, getpid()) < 0) { |
267 | 0b5538c3 | Stefan Hajnoczi | trace_file_name = NULL;
|
268 | 0b5538c3 | Stefan Hajnoczi | return false; |
269 | 0b5538c3 | Stefan Hajnoczi | } |
270 | 0b5538c3 | Stefan Hajnoczi | } else {
|
271 | 0b5538c3 | Stefan Hajnoczi | if (asprintf(&trace_file_name, "%s", file) < 0) { |
272 | 0b5538c3 | Stefan Hajnoczi | trace_file_name = NULL;
|
273 | 0b5538c3 | Stefan Hajnoczi | return false; |
274 | 0b5538c3 | Stefan Hajnoczi | } |
275 | 0b5538c3 | Stefan Hajnoczi | } |
276 | 0b5538c3 | Stefan Hajnoczi | |
277 | 0b5538c3 | Stefan Hajnoczi | st_set_trace_file_enabled(true);
|
278 | 0b5538c3 | Stefan Hajnoczi | return true; |
279 | 0b5538c3 | Stefan Hajnoczi | } |
280 | 0b5538c3 | Stefan Hajnoczi | |
281 | 0b5538c3 | Stefan Hajnoczi | void st_print_trace_file_status(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) |
282 | 0b5538c3 | Stefan Hajnoczi | { |
283 | 0b5538c3 | Stefan Hajnoczi | stream_printf(stream, "Trace file \"%s\" %s.\n",
|
284 | 0b5538c3 | Stefan Hajnoczi | trace_file_name, trace_fp ? "on" : "off"); |
285 | 26f7227b | Stefan Hajnoczi | } |
286 | 22890ab5 | Prerna Saxena | |
287 | 22890ab5 | Prerna Saxena | void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) |
288 | 22890ab5 | Prerna Saxena | { |
289 | 22890ab5 | Prerna Saxena | unsigned int i; |
290 | 22890ab5 | Prerna Saxena | |
291 | 0b5538c3 | Stefan Hajnoczi | for (i = 0; i < TRACE_BUF_LEN; i++) { |
292 | 0b5538c3 | Stefan Hajnoczi | TraceRecord record; |
293 | 0b5538c3 | Stefan Hajnoczi | |
294 | 0b5538c3 | Stefan Hajnoczi | if (!get_trace_record(i, &record)) {
|
295 | 0b5538c3 | Stefan Hajnoczi | continue;
|
296 | 0b5538c3 | Stefan Hajnoczi | } |
297 | a12c668f | Blue Swirl | stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64 |
298 | a12c668f | Blue Swirl | " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n", |
299 | 0b5538c3 | Stefan Hajnoczi | record.event, record.x1, record.x2, |
300 | 0b5538c3 | Stefan Hajnoczi | record.x3, record.x4, record.x5, |
301 | 0b5538c3 | Stefan Hajnoczi | record.x6); |
302 | 22890ab5 | Prerna Saxena | } |
303 | 22890ab5 | Prerna Saxena | } |
304 | 22890ab5 | Prerna Saxena | |
305 | 22890ab5 | Prerna Saxena | void st_print_trace_events(FILE *stream, int (*stream_printf)(FILE *stream, const char *fmt, ...)) |
306 | 22890ab5 | Prerna Saxena | { |
307 | 22890ab5 | Prerna Saxena | unsigned int i; |
308 | 22890ab5 | Prerna Saxena | |
309 | 22890ab5 | Prerna Saxena | for (i = 0; i < NR_TRACE_EVENTS; i++) { |
310 | 22890ab5 | Prerna Saxena | stream_printf(stream, "%s [Event ID %u] : state %u\n",
|
311 | 22890ab5 | Prerna Saxena | trace_list[i].tp_name, i, trace_list[i].state); |
312 | 22890ab5 | Prerna Saxena | } |
313 | 22890ab5 | Prerna Saxena | } |
314 | 22890ab5 | Prerna Saxena | |
315 | 0b5538c3 | Stefan Hajnoczi | bool st_change_trace_event_state(const char *name, bool enabled) |
316 | 22890ab5 | Prerna Saxena | { |
317 | 22890ab5 | Prerna Saxena | unsigned int i; |
318 | 22890ab5 | Prerna Saxena | |
319 | 22890ab5 | Prerna Saxena | for (i = 0; i < NR_TRACE_EVENTS; i++) { |
320 | 0b5538c3 | Stefan Hajnoczi | if (!strcmp(trace_list[i].tp_name, name)) {
|
321 | 0b5538c3 | Stefan Hajnoczi | trace_list[i].state = enabled; |
322 | 0b5538c3 | Stefan Hajnoczi | return true; |
323 | 22890ab5 | Prerna Saxena | } |
324 | 22890ab5 | Prerna Saxena | } |
325 | 0b5538c3 | Stefan Hajnoczi | return false; |
326 | 0b5538c3 | Stefan Hajnoczi | } |
327 | 0b5538c3 | Stefan Hajnoczi | |
328 | 0b5538c3 | Stefan Hajnoczi | void st_flush_trace_buffer(void) |
329 | 0b5538c3 | Stefan Hajnoczi | { |
330 | 0b5538c3 | Stefan Hajnoczi | flush_trace_file(true);
|
331 | 22890ab5 | Prerna Saxena | } |
332 | 22890ab5 | Prerna Saxena | |
333 | 31d3c9b8 | Stefan Hajnoczi | bool st_init(const char *file) |
334 | 22890ab5 | Prerna Saxena | { |
335 | 0b5538c3 | Stefan Hajnoczi | pthread_t thread; |
336 | 0b5538c3 | Stefan Hajnoczi | pthread_attr_t attr; |
337 | 0b5538c3 | Stefan Hajnoczi | sigset_t set, oldset; |
338 | 0b5538c3 | Stefan Hajnoczi | int ret;
|
339 | 0b5538c3 | Stefan Hajnoczi | |
340 | 0b5538c3 | Stefan Hajnoczi | pthread_attr_init(&attr); |
341 | 0b5538c3 | Stefan Hajnoczi | pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); |
342 | 22890ab5 | Prerna Saxena | |
343 | 0b5538c3 | Stefan Hajnoczi | sigfillset(&set); |
344 | 0b5538c3 | Stefan Hajnoczi | pthread_sigmask(SIG_SETMASK, &set, &oldset); |
345 | 0b5538c3 | Stefan Hajnoczi | ret = pthread_create(&thread, &attr, writeout_thread, NULL);
|
346 | 0b5538c3 | Stefan Hajnoczi | pthread_sigmask(SIG_SETMASK, &oldset, NULL);
|
347 | 0b5538c3 | Stefan Hajnoczi | |
348 | 0b5538c3 | Stefan Hajnoczi | if (ret != 0) { |
349 | 31d3c9b8 | Stefan Hajnoczi | return false; |
350 | 22890ab5 | Prerna Saxena | } |
351 | 0b5538c3 | Stefan Hajnoczi | |
352 | 0b5538c3 | Stefan Hajnoczi | atexit(st_flush_trace_buffer); |
353 | 0b5538c3 | Stefan Hajnoczi | st_set_trace_file(file); |
354 | 31d3c9b8 | Stefan Hajnoczi | return true; |
355 | 22890ab5 | Prerna Saxena | } |