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:
Lluís Vilanova 2014-02-23 20:37:40 +01:00 committed by Stefan Hajnoczi
parent ef0bd3bba6
commit 1dad2ce973
19 changed files with 303 additions and 395 deletions

View file

@ -20,17 +20,12 @@ All formats must generate their contents through the 'tracetool.out' routine.
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)

View file

@ -16,5 +16,13 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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)

View file

@ -16,5 +16,27 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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('',
'};')

View file

@ -16,14 +16,13 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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('};',
'',
)
'')

View file

@ -16,15 +16,14 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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 */')

View file

@ -16,23 +16,29 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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 */')

View file

@ -6,7 +6,7 @@ Generate .stp file (DTrace with SystemTAP only).
"""
__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 @@ __email__ = "stefanha@linux.vnet.ibm.com"
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()

View file

@ -16,7 +16,10 @@ __email__ = "stefanha@redhat.com"
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',

View file

@ -16,7 +16,10 @@ __email__ = "stefanha@redhat.com"
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 */',