mirror of https://gitee.com/openkylin/qemu.git
trace: [tracetool] Minimize the amount of per-backend code
Backends now only contain the essential backend-specific code, and most of the work is moved to frontend code. Signed-off-by: Lluís Vilanova <vilanova@ac.upc.edu> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
ef0bd3bba6
commit
1dad2ce973
|
@ -109,14 +109,10 @@ def process(events, log, analyzer):
|
|||
if isinstance(log, str):
|
||||
log = open(log, 'rb')
|
||||
|
||||
enabled_events = []
|
||||
dropped_event = Event.build("Dropped_Event(uint64_t num_events_dropped)")
|
||||
edict = {dropped_event_id: dropped_event}
|
||||
|
||||
for e in events:
|
||||
if 'disable' not in e.properties:
|
||||
enabled_events.append(e)
|
||||
for num, event in enumerate(enabled_events):
|
||||
for num, event in enumerate(events):
|
||||
edict[num] = event
|
||||
|
||||
def build_fn(analyzer, event):
|
||||
|
|
|
@ -266,10 +266,7 @@ def generate(fevents, format, backend,
|
|||
if not tracetool.backend.exists(backend):
|
||||
raise TracetoolError("unknown backend: %s" % backend)
|
||||
backend = backend.replace("-", "_")
|
||||
|
||||
if not tracetool.backend.compatible(backend, format):
|
||||
raise TracetoolError("backend '%s' not compatible with format '%s'" %
|
||||
(backend, format))
|
||||
backend = tracetool.backend.Wrapper(backend, format)
|
||||
|
||||
import tracetool.backend.dtrace
|
||||
tracetool.backend.dtrace.BINARY = binary
|
||||
|
@ -277,16 +274,4 @@ def generate(fevents, format, backend,
|
|||
|
||||
events = _read_events(fevents)
|
||||
|
||||
if backend == "nop":
|
||||
( e.properies.add("disable") for e in events )
|
||||
|
||||
tracetool.format.generate_begin(format, events)
|
||||
tracetool.backend.generate("nop", format,
|
||||
[ e
|
||||
for e in events
|
||||
if "disable" in e.properties ])
|
||||
tracetool.backend.generate(backend, format,
|
||||
[ e
|
||||
for e in events
|
||||
if "disable" not in e.properties ])
|
||||
tracetool.format.generate_end(format, events)
|
||||
tracetool.format.generate(events, format, backend)
|
||||
|
|
|
@ -30,17 +30,24 @@
|
|||
Backend functions
|
||||
-----------------
|
||||
|
||||
======== =======================================================================
|
||||
Function Description
|
||||
======== =======================================================================
|
||||
<format> Called to generate the format- and backend-specific code for each of
|
||||
the specified events. If the function does not exist, the backend is
|
||||
considered not compatible with the given format.
|
||||
======== =======================================================================
|
||||
All the following functions are optional, and no output will be generated if
|
||||
they do not exist.
|
||||
|
||||
=============================== ==============================================
|
||||
Function Description
|
||||
=============================== ==============================================
|
||||
generate_<format>_begin(events) Generate backend- and format-specific file
|
||||
header contents.
|
||||
generate_<format>_end(events) Generate backend- and format-specific file
|
||||
footer contents.
|
||||
generate_<format>(event) Generate backend- and format-specific contents
|
||||
for the given event.
|
||||
=============================== ==============================================
|
||||
|
||||
"""
|
||||
|
||||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__license__ = "GPL version 2 or (at your option) any later version"
|
||||
|
||||
__maintainer__ = "Stefan Hajnoczi"
|
||||
|
@ -91,39 +98,24 @@ def exists(name):
|
|||
return tracetool.try_import("tracetool.backend." + name)[1]
|
||||
|
||||
|
||||
def compatible(backend, format):
|
||||
"""Whether a backend is compatible with the given format."""
|
||||
if not exists(backend):
|
||||
raise ValueError("unknown backend: %s" % backend)
|
||||
class Wrapper:
|
||||
def __init__(self, backend, format):
|
||||
self._backend = backend.replace("-", "_")
|
||||
self._format = format.replace("-", "_")
|
||||
assert exists(self._backend)
|
||||
assert tracetool.format.exists(self._format)
|
||||
|
||||
backend = backend.replace("-", "_")
|
||||
format = format.replace("-", "_")
|
||||
def _run_function(self, name, *args, **kwargs):
|
||||
func = tracetool.try_import("tracetool.backend." + self._backend,
|
||||
name % self._format, None)[1]
|
||||
if func is not None:
|
||||
func(*args, **kwargs)
|
||||
|
||||
if backend == "nop":
|
||||
return True
|
||||
else:
|
||||
func = tracetool.try_import("tracetool.backend." + backend,
|
||||
format, None)[1]
|
||||
return func is not None
|
||||
def generate_begin(self, events):
|
||||
self._run_function("generate_%s_begin", events)
|
||||
|
||||
def generate(self, event):
|
||||
self._run_function("generate_%s", event)
|
||||
|
||||
def _empty(events):
|
||||
pass
|
||||
|
||||
def generate(backend, format, events):
|
||||
"""Generate the per-event output for the given (backend, format) pair."""
|
||||
if not compatible(backend, format):
|
||||
raise ValueError("backend '%s' not compatible with format '%s'" %
|
||||
(backend, format))
|
||||
|
||||
backend = backend.replace("-", "_")
|
||||
format = format.replace("-", "_")
|
||||
|
||||
if backend == "nop":
|
||||
func = tracetool.try_import("tracetool.format." + format,
|
||||
"nop", _empty)[1]
|
||||
else:
|
||||
func = tracetool.try_import("tracetool.backend." + backend,
|
||||
format, None)[1]
|
||||
|
||||
func(events)
|
||||
def generate_end(self, events):
|
||||
self._run_function("generate_%s_end", events)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
PROBEPREFIX = None
|
||||
|
||||
def _probeprefix():
|
||||
def probeprefix():
|
||||
if PROBEPREFIX is None:
|
||||
raise ValueError("you must set PROBEPREFIX")
|
||||
return PROBEPREFIX
|
||||
|
@ -29,81 +29,18 @@ def _probeprefix():
|
|||
|
||||
BINARY = None
|
||||
|
||||
def _binary():
|
||||
def binary():
|
||||
if BINARY is None:
|
||||
raise ValueError("you must set BINARY")
|
||||
return BINARY
|
||||
|
||||
|
||||
def c(events):
|
||||
pass
|
||||
|
||||
|
||||
def h(events):
|
||||
def generate_h_begin(events):
|
||||
out('#include "trace/generated-tracers-dtrace.h"',
|
||||
'')
|
||||
|
||||
for e in events:
|
||||
out('static inline void %(api)s(%(args)s) {',
|
||||
' QEMU_%(uppername)s(%(argnames)s);',
|
||||
'}',
|
||||
api = e.api(),
|
||||
args = e.args,
|
||||
uppername = e.name.upper(),
|
||||
argnames = ", ".join(e.args.names()),
|
||||
)
|
||||
|
||||
|
||||
def d(events):
|
||||
out('provider qemu {')
|
||||
|
||||
for e in events:
|
||||
args = str(e.args)
|
||||
|
||||
# DTrace provider syntax expects foo() for empty
|
||||
# params, not foo(void)
|
||||
if args == 'void':
|
||||
args = ''
|
||||
|
||||
# Define prototype for probe arguments
|
||||
out('',
|
||||
'probe %(name)s(%(args)s);',
|
||||
name = e.name,
|
||||
args = args,
|
||||
)
|
||||
|
||||
out('',
|
||||
'};')
|
||||
|
||||
|
||||
# Technically 'self' is not used by systemtap yet, but
|
||||
# they recommended we keep it in the reserved list anyway
|
||||
RESERVED_WORDS = (
|
||||
'break', 'catch', 'continue', 'delete', 'else', 'for',
|
||||
'foreach', 'function', 'global', 'if', 'in', 'limit',
|
||||
'long', 'next', 'probe', 'return', 'self', 'string',
|
||||
'try', 'while'
|
||||
)
|
||||
|
||||
def stap(events):
|
||||
for e in events:
|
||||
# Define prototype for probe arguments
|
||||
out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
|
||||
'{',
|
||||
probeprefix = _probeprefix(),
|
||||
name = e.name,
|
||||
binary = _binary(),
|
||||
)
|
||||
|
||||
i = 1
|
||||
if len(e.args) > 0:
|
||||
for name in e.args.names():
|
||||
# Append underscore to reserved keywords
|
||||
if name in RESERVED_WORDS:
|
||||
name += '_'
|
||||
out(' %s = $arg%d;' % (name, i))
|
||||
i += 1
|
||||
|
||||
out('}')
|
||||
|
||||
out()
|
||||
def generate_h(event):
|
||||
out(' QEMU_%(uppername)s(%(argnames)s);',
|
||||
uppername=event.name.upper(),
|
||||
argnames=", ".join(event.args.names()))
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Generic event description.
|
||||
|
||||
This is a dummy backend to establish appropriate frontend/backend compatibility
|
||||
checks.
|
||||
"""
|
||||
|
||||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__license__ = "GPL version 2 or (at your option) any later version"
|
||||
|
||||
__maintainer__ = "Stefan Hajnoczi"
|
||||
__email__ = "stefanha@linux.vnet.ibm.com"
|
||||
|
||||
|
||||
def events_h(events):
|
||||
pass
|
||||
|
||||
def events_c(events):
|
||||
pass
|
|
@ -19,36 +19,30 @@
|
|||
PUBLIC = True
|
||||
|
||||
|
||||
def c(events):
|
||||
pass
|
||||
|
||||
def h(events):
|
||||
def generate_h_begin(events):
|
||||
out('#include "trace/ftrace.h"',
|
||||
'#include "trace/control.h"',
|
||||
'',
|
||||
)
|
||||
'')
|
||||
|
||||
for e in events:
|
||||
argnames = ", ".join(e.args.names())
|
||||
if len(e.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out('static inline void trace_%(name)s(%(args)s)',
|
||||
'{',
|
||||
' char ftrace_buf[MAX_TRACE_STRLEN];',
|
||||
' int unused __attribute__ ((unused));',
|
||||
' int trlen;',
|
||||
' bool _state = trace_event_get_state(%(event_id)s);',
|
||||
' if (_state) {',
|
||||
' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
|
||||
' "%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||
' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
|
||||
' unused = write(trace_marker_fd, ftrace_buf, trlen);',
|
||||
' }',
|
||||
'}',
|
||||
name = e.name,
|
||||
args = e.args,
|
||||
event_id = "TRACE_" + e.name.upper(),
|
||||
fmt = e.fmt.rstrip("\n"),
|
||||
argnames = argnames,
|
||||
)
|
||||
def generate_h(event):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out(' {',
|
||||
' char ftrace_buf[MAX_TRACE_STRLEN];',
|
||||
' int unused __attribute__ ((unused));',
|
||||
' int trlen;',
|
||||
' if (trace_event_get_state(%(event_id)s)) {',
|
||||
' trlen = snprintf(ftrace_buf, MAX_TRACE_STRLEN,',
|
||||
' "%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||
' trlen = MIN(trlen, MAX_TRACE_STRLEN - 1);',
|
||||
' unused = write(trace_marker_fd, ftrace_buf, trlen);',
|
||||
' }',
|
||||
' }',
|
||||
name=event.name,
|
||||
args=event.args,
|
||||
event_id="TRACE_" + event.name.upper(),
|
||||
fmt=event.fmt.rstrip("\n"),
|
||||
argnames=argnames)
|
||||
|
|
|
@ -26,76 +26,74 @@ def is_string(arg):
|
|||
else:
|
||||
return False
|
||||
|
||||
def c(events):
|
||||
|
||||
def generate_h_begin(events):
|
||||
for event in events:
|
||||
out('void _simple_%(api)s(%(args)s);',
|
||||
api=event.api(),
|
||||
args=event.args)
|
||||
out('')
|
||||
|
||||
|
||||
def generate_h(event):
|
||||
out(' _simple_%(api)s(%(args)s);',
|
||||
api=event.api(),
|
||||
args=", ".join(event.args.names()))
|
||||
|
||||
|
||||
def generate_c_begin(events):
|
||||
out('#include "trace.h"',
|
||||
'#include "trace/control.h"',
|
||||
'#include "trace/simple.h"',
|
||||
'')
|
||||
|
||||
|
||||
def generate_c(event):
|
||||
out('void _simple_%(api)s(%(args)s)',
|
||||
'{',
|
||||
' TraceBufferRecord rec;',
|
||||
api=event.api(),
|
||||
args=event.args)
|
||||
sizes = []
|
||||
for type_, name in event.args:
|
||||
if is_string(type_):
|
||||
out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
|
||||
name=name)
|
||||
strsizeinfo = "4 + arg%s_len" % name
|
||||
sizes.append(strsizeinfo)
|
||||
else:
|
||||
sizes.append("8")
|
||||
sizestr = " + ".join(sizes)
|
||||
if len(event.args) == 0:
|
||||
sizestr = '0'
|
||||
|
||||
|
||||
out('',
|
||||
' if (!trace_event_get_state(%(event_id)s)) {',
|
||||
' return;',
|
||||
' }',
|
||||
'',
|
||||
)
|
||||
' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
|
||||
' return; /* Trace Buffer Full, Event Dropped ! */',
|
||||
' }',
|
||||
event_id='TRACE_' + event.name.upper(),
|
||||
size_str=sizestr)
|
||||
|
||||
for num, event in enumerate(events):
|
||||
out('void %(api)s(%(args)s)',
|
||||
'{',
|
||||
' TraceBufferRecord rec;',
|
||||
api = event.api(),
|
||||
args = event.args,
|
||||
)
|
||||
sizes = []
|
||||
if len(event.args) > 0:
|
||||
for type_, name in event.args:
|
||||
# string
|
||||
if is_string(type_):
|
||||
out(' size_t arg%(name)s_len = %(name)s ? MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
|
||||
name = name,
|
||||
)
|
||||
strsizeinfo = "4 + arg%s_len" % name
|
||||
sizes.append(strsizeinfo)
|
||||
out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
|
||||
name=name)
|
||||
# pointer var (not string)
|
||||
elif type_.endswith('*'):
|
||||
out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
|
||||
name=name)
|
||||
# primitive data type
|
||||
else:
|
||||
sizes.append("8")
|
||||
sizestr = " + ".join(sizes)
|
||||
if len(event.args) == 0:
|
||||
sizestr = '0'
|
||||
out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
|
||||
name=name)
|
||||
|
||||
|
||||
out('',
|
||||
' TraceEvent *eventp = trace_event_id(%(event_enum)s);',
|
||||
' bool _state = trace_event_get_state_dynamic(eventp);',
|
||||
' if (!_state) {',
|
||||
' return;',
|
||||
' }',
|
||||
'',
|
||||
' if (trace_record_start(&rec, %(event_id)s, %(size_str)s)) {',
|
||||
' return; /* Trace Buffer Full, Event Dropped ! */',
|
||||
' }',
|
||||
event_enum = 'TRACE_' + event.name.upper(),
|
||||
event_id = num,
|
||||
size_str = sizestr,
|
||||
)
|
||||
|
||||
if len(event.args) > 0:
|
||||
for type_, name in event.args:
|
||||
# string
|
||||
if is_string(type_):
|
||||
out(' trace_record_write_str(&rec, %(name)s, arg%(name)s_len);',
|
||||
name = name,
|
||||
)
|
||||
# pointer var (not string)
|
||||
elif type_.endswith('*'):
|
||||
out(' trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)%(name)s);',
|
||||
name = name,
|
||||
)
|
||||
# primitive data type
|
||||
else:
|
||||
out(' trace_record_write_u64(&rec, (uint64_t)%(name)s);',
|
||||
name = name,
|
||||
)
|
||||
|
||||
out(' trace_record_finish(&rec);',
|
||||
'}',
|
||||
'')
|
||||
|
||||
|
||||
def h(events):
|
||||
for event in events:
|
||||
out('void %(api)s(%(args)s);',
|
||||
api = event.api(),
|
||||
args = event.args,
|
||||
)
|
||||
out(' trace_record_finish(&rec);',
|
||||
'}',
|
||||
'')
|
||||
|
|
|
@ -19,31 +19,21 @@
|
|||
PUBLIC = True
|
||||
|
||||
|
||||
def c(events):
|
||||
pass
|
||||
|
||||
def h(events):
|
||||
def generate_h_begin(events):
|
||||
out('#include <stdio.h>',
|
||||
'#include "trace/control.h"',
|
||||
'',
|
||||
)
|
||||
'')
|
||||
|
||||
for e in events:
|
||||
argnames = ", ".join(e.args.names())
|
||||
if len(e.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out('static inline void %(api)s(%(args)s)',
|
||||
'{',
|
||||
' bool _state = trace_event_get_state(%(event_id)s);',
|
||||
' if (_state) {',
|
||||
' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||
' }',
|
||||
'}',
|
||||
api = e.api(),
|
||||
name = e.name,
|
||||
args = e.args,
|
||||
event_id = "TRACE_" + e.name.upper(),
|
||||
fmt = e.fmt.rstrip("\n"),
|
||||
argnames = argnames,
|
||||
)
|
||||
def generate_h(event):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out(' if (trace_event_get_state(%(event_id)s)) {',
|
||||
' fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
|
||||
' }',
|
||||
event_id="TRACE_" + event.name.upper(),
|
||||
name=event.name,
|
||||
fmt=event.fmt.rstrip("\n"),
|
||||
argnames=argnames)
|
||||
|
|
|
@ -18,66 +18,18 @@
|
|||
|
||||
PUBLIC = True
|
||||
|
||||
def c(events):
|
||||
pass
|
||||
|
||||
|
||||
def h(events):
|
||||
def generate_h_begin(events):
|
||||
out('#include <lttng/tracepoint.h>',
|
||||
'#include "trace/generated-ust-provider.h"',
|
||||
'')
|
||||
for e in events:
|
||||
argnames = ", ".join(e.args.names())
|
||||
if len(e.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
out('static inline void %(api)s(%(args)s)',
|
||||
'{',
|
||||
' tracepoint(qemu, %(name)s%(tp_args)s);',
|
||||
'}',
|
||||
'',
|
||||
api = e.api()
|
||||
name = e.name,
|
||||
args = e.args,
|
||||
tp_args = argnames,
|
||||
)
|
||||
|
||||
def ust_events_c(events):
|
||||
pass
|
||||
def generate_h(event):
|
||||
argnames = ", ".join(event.args.names())
|
||||
if len(event.args) > 0:
|
||||
argnames = ", " + argnames
|
||||
|
||||
def ust_events_h(events):
|
||||
for e in events:
|
||||
if len(e.args) > 0:
|
||||
out('TRACEPOINT_EVENT(',
|
||||
' qemu,',
|
||||
' %(name)s,',
|
||||
' TP_ARGS(%(args)s),',
|
||||
' TP_FIELDS(',
|
||||
name = e.name,
|
||||
args = ", ".join(", ".join(i) for i in e.args),
|
||||
)
|
||||
|
||||
for t,n in e.args:
|
||||
if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
|
||||
out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
|
||||
elif ('double' in t) or ('float' in t):
|
||||
out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
|
||||
elif ('char *' in t) or ('char*' in t):
|
||||
out(' ctf_string(' + n + ', ' + n + ')')
|
||||
elif ('void *' in t) or ('void*' in t):
|
||||
out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
|
||||
|
||||
out(' )',
|
||||
')',
|
||||
'')
|
||||
|
||||
else:
|
||||
out('TRACEPOINT_EVENT(',
|
||||
' qemu,',
|
||||
' %(name)s,',
|
||||
' TP_ARGS(void),',
|
||||
' TP_FIELDS()',
|
||||
')',
|
||||
'',
|
||||
name = e.name,
|
||||
)
|
||||
out(' tracepoint(qemu, %(name)s%(tp_args)s);',
|
||||
name=event.name,
|
||||
tp_args=argnames)
|
||||
|
|
|
@ -20,17 +20,12 @@
|
|||
Format functions
|
||||
----------------
|
||||
|
||||
All the following functions are optional, and no output will be generated if
|
||||
they do not exist.
|
||||
|
||||
======== =======================================================================
|
||||
======== ==================================================================
|
||||
Function Description
|
||||
======== =======================================================================
|
||||
begin Called to generate the format-specific file header.
|
||||
end Called to generate the format-specific file footer.
|
||||
nop Called to generate the per-event contents when the event is disabled or
|
||||
the selected backend is 'nop'.
|
||||
======== =======================================================================
|
||||
======== ==================================================================
|
||||
generate Called to generate a format-specific file.
|
||||
======== ==================================================================
|
||||
|
||||
"""
|
||||
|
||||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
|
@ -79,25 +74,12 @@ def exists(name):
|
|||
return tracetool.try_import("tracetool.format." + name)[1]
|
||||
|
||||
|
||||
def _empty(events):
|
||||
pass
|
||||
|
||||
def generate_begin(name, events):
|
||||
"""Generate the header of the format-specific file."""
|
||||
if not exists(name):
|
||||
raise ValueError("unknown format: %s" % name)
|
||||
|
||||
name = name.replace("-", "_")
|
||||
func = tracetool.try_import("tracetool.format." + name,
|
||||
"begin", _empty)[1]
|
||||
func(events)
|
||||
|
||||
def generate_end(name, events):
|
||||
"""Generate the footer of the format-specific file."""
|
||||
if not exists(name):
|
||||
raise ValueError("unknown format: %s" % name)
|
||||
|
||||
name = name.replace("-", "_")
|
||||
func = tracetool.try_import("tracetool.format." + name,
|
||||
"end", _empty)[1]
|
||||
func(events)
|
||||
def generate(events, format, backend):
|
||||
if not exists(format):
|
||||
raise ValueError("unknown format: %s" % format)
|
||||
format = format.replace("-", "_")
|
||||
func = tracetool.try_import("tracetool.format." + format,
|
||||
"generate")[1]
|
||||
if func is None:
|
||||
raise AttributeError("format has no 'generate': %s" % format)
|
||||
func(events, backend)
|
||||
|
|
|
@ -16,5 +16,13 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */')
|
||||
def generate(events, backend):
|
||||
events = [e for e in events
|
||||
if "disable" not in e.properties]
|
||||
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'')
|
||||
backend.generate_begin(events)
|
||||
for event in events:
|
||||
backend.generate(event)
|
||||
backend.generate_end(events)
|
||||
|
|
|
@ -16,5 +16,27 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */')
|
||||
def generate(events, backend):
|
||||
events = [e for e in events
|
||||
if "disable" not in e.properties]
|
||||
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */'
|
||||
'',
|
||||
'provider qemu {')
|
||||
|
||||
for e in events:
|
||||
args = str(e.args)
|
||||
|
||||
# DTrace provider syntax expects foo() for empty
|
||||
# params, not foo(void)
|
||||
if args == 'void':
|
||||
args = ''
|
||||
|
||||
# Define prototype for probe arguments
|
||||
out('',
|
||||
'probe %(name)s(%(args)s);',
|
||||
name=e.name,
|
||||
args=args)
|
||||
|
||||
out('',
|
||||
'};')
|
||||
|
|
|
@ -16,14 +16,13 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
def generate(events, backend):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'',
|
||||
'#include "trace.h"',
|
||||
'#include "trace/generated-events.h"',
|
||||
'#include "trace/control.h"',
|
||||
'',
|
||||
)
|
||||
'')
|
||||
|
||||
out('TraceEvent trace_events[TRACE_EVENT_COUNT] = {')
|
||||
|
||||
|
@ -31,9 +30,7 @@ def begin(events):
|
|||
out(' { .id = %(id)s, .name = \"%(name)s\", .sstate = %(sstate)s, .dstate = 0 },',
|
||||
id = "TRACE_" + e.name.upper(),
|
||||
name = e.name,
|
||||
sstate = "TRACE_%s_ENABLED" % e.name.upper(),
|
||||
)
|
||||
sstate = "TRACE_%s_ENABLED" % e.name.upper())
|
||||
|
||||
out('};',
|
||||
'',
|
||||
)
|
||||
'')
|
||||
|
|
|
@ -16,15 +16,14 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
def generate(events, backend):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'',
|
||||
'#ifndef TRACE__GENERATED_EVENTS_H',
|
||||
'#define TRACE__GENERATED_EVENTS_H',
|
||||
'',
|
||||
'#include <stdbool.h>',
|
||||
''
|
||||
)
|
||||
'')
|
||||
|
||||
# event identifiers
|
||||
out('typedef enum {')
|
||||
|
@ -33,8 +32,7 @@ def begin(events):
|
|||
out(' TRACE_%s,' % e.name.upper())
|
||||
|
||||
out(' TRACE_EVENT_COUNT',
|
||||
'} TraceEventID;',
|
||||
)
|
||||
'} TraceEventID;')
|
||||
|
||||
# static state
|
||||
for e in events:
|
||||
|
@ -46,5 +44,4 @@ def begin(events):
|
|||
|
||||
out('#include "trace/event-internal.h"',
|
||||
'',
|
||||
'#endif /* TRACE__GENERATED_EVENTS_H */',
|
||||
)
|
||||
'#endif /* TRACE__GENERATED_EVENTS_H */')
|
||||
|
|
|
@ -16,23 +16,29 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
def generate(events, backend):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'',
|
||||
'#ifndef TRACE__GENERATED_TRACERS_H',
|
||||
'#define TRACE__GENERATED_TRACERS_H',
|
||||
'',
|
||||
'#include "qemu-common.h"')
|
||||
'#include "qemu-common.h"',
|
||||
'')
|
||||
|
||||
def end(events):
|
||||
out('#endif /* TRACE__GENERATED_TRACERS_H */')
|
||||
backend.generate_begin(events)
|
||||
|
||||
def nop(events):
|
||||
for e in events:
|
||||
out('',
|
||||
'static inline void %(api)s(%(args)s)',
|
||||
'{',
|
||||
'}',
|
||||
api = e.api(),
|
||||
args = e.args,
|
||||
)
|
||||
api=e.api(),
|
||||
args=e.args)
|
||||
|
||||
if "disable" not in e.properties:
|
||||
backend.generate(e)
|
||||
|
||||
out('}')
|
||||
|
||||
backend.generate_end(events)
|
||||
|
||||
out('#endif /* TRACE__GENERATED_TRACERS_H */')
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"""
|
||||
|
||||
__author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__copyright__ = "Copyright 2012, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
|
||||
__license__ = "GPL version 2 or (at your option) any later version"
|
||||
|
||||
__maintainer__ = "Stefan Hajnoczi"
|
||||
|
@ -14,7 +14,43 @@
|
|||
|
||||
|
||||
from tracetool import out
|
||||
from tracetool.backend.dtrace import binary, probeprefix
|
||||
|
||||
|
||||
def begin(events):
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */')
|
||||
# Technically 'self' is not used by systemtap yet, but
|
||||
# they recommended we keep it in the reserved list anyway
|
||||
RESERVED_WORDS = (
|
||||
'break', 'catch', 'continue', 'delete', 'else', 'for',
|
||||
'foreach', 'function', 'global', 'if', 'in', 'limit',
|
||||
'long', 'next', 'probe', 'return', 'self', 'string',
|
||||
'try', 'while'
|
||||
)
|
||||
|
||||
|
||||
def generate(events, backend):
|
||||
events = [e for e in events
|
||||
if "disable" not in e.properties]
|
||||
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'')
|
||||
|
||||
for e in events:
|
||||
# Define prototype for probe arguments
|
||||
out('probe %(probeprefix)s.%(name)s = process("%(binary)s").mark("%(name)s")',
|
||||
'{',
|
||||
probeprefix=probeprefix(),
|
||||
name=e.name,
|
||||
binary=binary())
|
||||
|
||||
i = 1
|
||||
if len(e.args) > 0:
|
||||
for name in e.args.names():
|
||||
# Append underscore to reserved keywords
|
||||
if name in RESERVED_WORDS:
|
||||
name += '_'
|
||||
out(' %s = $arg%d;' % (name, i))
|
||||
i += 1
|
||||
|
||||
out('}')
|
||||
|
||||
out()
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
def generate(events, backend):
|
||||
events = [e for e in events
|
||||
if "disabled" not in e.properties]
|
||||
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'',
|
||||
'#define TRACEPOINT_DEFINE',
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
from tracetool import out
|
||||
|
||||
|
||||
def begin(events):
|
||||
def generate(events, backend):
|
||||
events = [e for e in events
|
||||
if "disabled" not in e.properties]
|
||||
|
||||
out('/* This file is autogenerated by tracetool, do not edit. */',
|
||||
'',
|
||||
'#undef TRACEPOINT_PROVIDER',
|
||||
|
@ -50,7 +53,40 @@ def begin(events):
|
|||
'#endif',
|
||||
'')
|
||||
|
||||
def end(events):
|
||||
for e in events:
|
||||
if len(e.args) > 0:
|
||||
out('TRACEPOINT_EVENT(',
|
||||
' qemu,',
|
||||
' %(name)s,',
|
||||
' TP_ARGS(%(args)s),',
|
||||
' TP_FIELDS(',
|
||||
name=e.name,
|
||||
args=", ".join(", ".join(i) for i in e.args))
|
||||
|
||||
for t, n in e.args:
|
||||
if ('int' in t) or ('long' in t) or ('unsigned' in t) or ('size_t' in t):
|
||||
out(' ctf_integer(' + t + ', ' + n + ', ' + n + ')')
|
||||
elif ('double' in t) or ('float' in t):
|
||||
out(' ctf_float(' + t + ', ' + n + ', ' + n + ')')
|
||||
elif ('char *' in t) or ('char*' in t):
|
||||
out(' ctf_string(' + n + ', ' + n + ')')
|
||||
elif ('void *' in t) or ('void*' in t):
|
||||
out(' ctf_integer_hex(unsigned long, ' + n + ', ' + n + ')')
|
||||
|
||||
out(' )',
|
||||
')',
|
||||
'')
|
||||
|
||||
else:
|
||||
out('TRACEPOINT_EVENT(',
|
||||
' qemu,',
|
||||
' %(name)s,',
|
||||
' TP_ARGS(void),',
|
||||
' TP_FIELDS()',
|
||||
')',
|
||||
'',
|
||||
name=e.name)
|
||||
|
||||
out('#endif /* TRACE__GENERATED_UST_H */',
|
||||
'',
|
||||
'/* This part must be outside ifdef protection */',
|
||||
|
|
|
@ -31,7 +31,7 @@ $(obj)/generated-events.h: $(obj)/generated-events.h-timestamp
|
|||
$(obj)/generated-events.h-timestamp: $(SRC_PATH)/trace-events
|
||||
$(call quiet-command,$(TRACETOOL) \
|
||||
--format=events-h \
|
||||
--backend=events \
|
||||
--backend=$(TRACE_BACKEND) \
|
||||
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
|
||||
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
|
||||
|
||||
|
@ -39,7 +39,7 @@ $(obj)/generated-events.c: $(obj)/generated-events.c-timestamp $(BUILD_DIR)/conf
|
|||
$(obj)/generated-events.c-timestamp: $(SRC_PATH)/trace-events
|
||||
$(call quiet-command,$(TRACETOOL) \
|
||||
--format=events-c \
|
||||
--backend=events \
|
||||
--backend=$(TRACE_BACKEND) \
|
||||
< $< > $@," GEN $(patsubst %-timestamp,%,$@)")
|
||||
@cmp -s $@ $(patsubst %-timestamp,%,$@) || cp $@ $(patsubst %-timestamp,%,$@)
|
||||
|
||||
|
|
Loading…
Reference in New Issue