]>
git.proxmox.com Git - qemu.git/blob - simpletrace.c
477730871c70950b36c80dfc9184ad0085fbd0b9
4 * Copyright IBM, Corp. 2010
6 * This work is licensed under the terms of the GNU GPL, version 2. See
7 * the COPYING file in the top-level directory.
17 /** Trace file header event ID */
18 #define HEADER_EVENT_ID (~(uint64_t)0) /* avoids conflicting with TraceEventIDs */
20 /** Trace file magic number */
21 #define HEADER_MAGIC 0xf2b177cb0aa429b4ULL
23 /** Trace file version number, bump if format changes */
24 #define HEADER_VERSION 0
26 /** Trace buffer entry */
29 uint64_t timestamp_ns
;
39 TRACE_BUF_LEN
= 64 * 1024 / sizeof(TraceRecord
),
42 static TraceRecord trace_buf
[TRACE_BUF_LEN
];
43 static unsigned int trace_idx
;
44 static FILE *trace_fp
;
46 static bool write_header(FILE *fp
)
48 static const TraceRecord header
= {
49 .event
= HEADER_EVENT_ID
,
50 .timestamp_ns
= HEADER_MAGIC
,
54 return fwrite(&header
, sizeof header
, 1, fp
) == 1;
57 static void flush_trace_buffer(void)
60 trace_fp
= fopen("trace.log", "w");
62 write_header(trace_fp
);
66 size_t unused
; /* for when fwrite(3) is declared warn_unused_result */
67 unused
= fwrite(trace_buf
, trace_idx
* sizeof(trace_buf
[0]), 1, trace_fp
);
70 /* Discard written trace records */
74 void st_set_trace_file_enabled(bool enable
)
76 if (enable
== trace_file_enabled
) {
77 return; /* no change */
80 /* Flush/discard trace buffer */
81 st_flush_trace_buffer();
83 /* To disable, close trace file */
89 trace_file_enabled
= enable
;
92 static void trace(TraceEventID event
, uint64_t x1
, uint64_t x2
, uint64_t x3
,
93 uint64_t x4
, uint64_t x5
, uint64_t x6
)
95 TraceRecord
*rec
= &trace_buf
[trace_idx
];
98 /* TODO Windows? It would be good to use qemu-timer here but that isn't
99 * linked into qemu-tools. Also we should avoid recursion in the tracing
100 * code, therefore it is useful to be self-contained.
102 clock_gettime(CLOCK_MONOTONIC
, &ts
);
105 rec
->timestamp_ns
= ts
.tv_sec
* 1000000000LL + ts
.tv_nsec
;
113 if (++trace_idx
== TRACE_BUF_LEN
) {
114 flush_trace_buffer();
118 void trace0(TraceEventID event
)
120 trace(event
, 0, 0, 0, 0, 0, 0);
123 void trace1(TraceEventID event
, uint64_t x1
)
125 trace(event
, x1
, 0, 0, 0, 0, 0);
128 void trace2(TraceEventID event
, uint64_t x1
, uint64_t x2
)
130 trace(event
, x1
, x2
, 0, 0, 0, 0);
133 void trace3(TraceEventID event
, uint64_t x1
, uint64_t x2
, uint64_t x3
)
135 trace(event
, x1
, x2
, x3
, 0, 0, 0);
138 void trace4(TraceEventID event
, uint64_t x1
, uint64_t x2
, uint64_t x3
, uint64_t x4
)
140 trace(event
, x1
, x2
, x3
, x4
, 0, 0);
143 void trace5(TraceEventID event
, uint64_t x1
, uint64_t x2
, uint64_t x3
, uint64_t x4
, uint64_t x5
)
145 trace(event
, x1
, x2
, x3
, x4
, x5
, 0);
148 void trace6(TraceEventID event
, uint64_t x1
, uint64_t x2
, uint64_t x3
, uint64_t x4
, uint64_t x5
, uint64_t x6
)
150 trace(event
, x1
, x2
, x3
, x4
, x5
, x6
);
154 * Flush the trace buffer on exit
156 static void __attribute__((constructor
)) st_init(void)
158 atexit(st_flush_trace_buffer
);