qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v2] trace backend: introduce multi tracing backend


From: Kazuya Saito
Subject: [Qemu-devel] [PATCH v2] trace backend: introduce multi tracing backend
Date: Thu, 13 Feb 2014 15:52:54 +0900
User-agent: Mozilla/5.0 (Windows NT 6.1; rv:24.0) Gecko/20100101 Thunderbird/24.3.0

This patch implements "multi tracing backend" which enables several
tracing backend simultaneously.

QEMU has multiple trace backends, but one of them needs to be chosen at
compile time.  When investigating issues of QEMU, it'd be much more
convenient if we can use multiple trace backends without recompiling,
especially 'ftrace backend' and 'dtrace backend'.  From the performance
perspective, 'ftrace backend' should be the one which runs while the
system is in operation, and it provides useful information.  But, for
some issues, 'dtrace backend' is needed for investigation as 'dtrace
backend' provides more information.  This patch enables both 'ftrace
backend' and 'dtrace backend' (, and some other backends if necessary)
at compile time so that we can switch between the two without
recompiling.

usage:
We have only to set some tracing backends as follows.

  $ ./configure --enable-trace-backend=ftrace,dtrace

Of course, we can compile with single backend as well as before.

  $ ./configure --enable-trace-backend=simple

Changes from v1:
- Based on tracing-next branch
- Support ust backend
- Change the way to check whether each tracing backend is included in
  $trace_backend into the way to use grep
- Add comment on compatible checking in tracetool.generate()
- Change tracetool.backend.compatible() to check "supported_formats" of
  each backend
- Eliminate CONFIG_TRACE_DTRACE include from tracetool/backend/common.py
- Define SDT_USE_VARIADIC in genrated-tracers.h in order to avoid
  compilation error when enabling dtrace and ust simultaneously
- Revert tracetool.backend.dtrace.{d(),stap()} back
- Change multi.c:trace_backend_init() to figure out what is wrong when
  *_backend_init() fails

Signed-off-by: Kazuya Saito <address@hidden>
---
 Makefile                              |    4 +-
 configure                             |   16 +++--
 scripts/tracetool.py                  |    9 ++-
 scripts/tracetool/__init__.py         |   31 +++++---
 scripts/tracetool/backend/__init__.py |   32 +++++----
 scripts/tracetool/backend/common.py   |  101 ++++++++++++++++++++++++++
 scripts/tracetool/backend/dtrace.py   |   33 +++++----
 scripts/tracetool/backend/events.py   |    2 +-
 scripts/tracetool/backend/ftrace.py   |   60 ++++++++-------
 scripts/tracetool/backend/simple.py   |  128 ++++++++++++++++-----------------
 scripts/tracetool/backend/stderr.py   |   43 ++++++-----
 scripts/tracetool/backend/ust.py      |   36 +++++-----
 trace/Makefile.objs                   |   22 ++++--
 trace/ftrace.c                        |   25 +------
 trace/ftrace.h                        |    1 +
 trace/multi.c                         |   51 +++++++++++++
 trace/simple.c                        |   18 +-----
 trace/simple.h                        |    1 +
 trace/stderr.c                        |   30 --------
 19 files changed, 382 insertions(+), 261 deletions(-)
 create mode 100644 scripts/tracetool/backend/common.py
 create mode 100644 trace/multi.c
 delete mode 100644 trace/stderr.c

diff --git a/Makefile b/Makefile
index ca51193..302752d 100644
--- a/Makefile
+++ b/Makefile
@@ -52,12 +52,12 @@ GENERATED_HEADERS += trace/generated-events.h
 GENERATED_SOURCES += trace/generated-events.c

 GENERATED_HEADERS += trace/generated-tracers.h
-ifeq ($(TRACE_BACKEND),dtrace)
+ifeq ($(findstring dtrace,$(TRACE_BACKEND)),dtrace)
 GENERATED_HEADERS += trace/generated-tracers-dtrace.h
 endif
 GENERATED_SOURCES += trace/generated-tracers.c

-ifeq ($(TRACE_BACKEND),ust)
+ifeq ($(findstring ust,$(TRACE_BACKEND)),ust)
 GENERATED_HEADERS += trace/generated-ust-provider.h
 GENERATED_SOURCES += trace/generated-ust.c
 endif
diff --git a/configure b/configure
index 2a14014..405cfb0 100755
--- a/configure
+++ b/configure
@@ -3363,7 +3363,7 @@ fi

 ##########################################
 # For 'ust' backend, test if ust headers are present
-if test "$trace_backend" = "ust"; then
+if echo "$trace_backend" | grep ust >/dev/null; then
   cat > $TMPC << EOF
 #include <lttng/tracepoint.h>
 int main(void) { return 0; }
@@ -3389,7 +3389,7 @@ fi

 ##########################################
 # For 'dtrace' backend, test if 'dtrace' command is present
-if test "$trace_backend" = "dtrace"; then
+if echo "$trace_backend" | grep dtrace >/dev/null; then
   if ! has 'dtrace' ; then
     error_exit "dtrace command is not found in PATH $PATH"
   fi
@@ -4280,26 +4280,27 @@ echo "TRACE_BACKEND=$trace_backend" >> $config_host_mak
 if test "$trace_backend" = "nop"; then
   echo "CONFIG_TRACE_NOP=y" >> $config_host_mak
 fi
-if test "$trace_backend" = "simple"; then
+
+if echo "$trace_backend" | grep simple >/dev/null; then
   echo "CONFIG_TRACE_SIMPLE=y" >> $config_host_mak
   trace_default=no
   # Set the appropriate trace file.
   trace_file="\"$trace_file-\" FMT_pid"
 fi
-if test "$trace_backend" = "stderr"; then
+if echo "$trace_backend" | grep stderr >/dev/null; then
   echo "CONFIG_TRACE_STDERR=y" >> $config_host_mak
   trace_default=no
 fi
-if test "$trace_backend" = "ust"; then
+if echo "$trace_backend" | grep ust >/dev/null; then
   echo "CONFIG_TRACE_UST=y" >> $config_host_mak
 fi
-if test "$trace_backend" = "dtrace"; then
+if echo "$trace_backend" | grep dtrace >/dev/null; then
   echo "CONFIG_TRACE_DTRACE=y" >> $config_host_mak
   if test "$trace_backend_stap" = "yes" ; then
     echo "CONFIG_TRACE_SYSTEMTAP=y" >> $config_host_mak
   fi
 fi
-if test "$trace_backend" = "ftrace"; then
+if echo "$trace_backend" | grep ftrace >/dev/null; then
   if test "$linux" = "yes" ; then
     echo "CONFIG_TRACE_FTRACE=y" >> $config_host_mak
     trace_default=no
@@ -4307,6 +4308,7 @@ if test "$trace_backend" = "ftrace"; then
     feature_not_found "ftrace(trace backend)"
   fi
 fi
+
 echo "CONFIG_TRACE_FILE=$trace_file" >> $config_host_mak
 if test "$trace_default" = "yes"; then
   echo "CONFIG_TRACE_DEFAULT=y" >> $config_host_mak
diff --git a/scripts/tracetool.py b/scripts/tracetool.py
index 5f4890f..2c7c0c0 100755
--- a/scripts/tracetool.py
+++ b/scripts/tracetool.py
@@ -112,10 +112,11 @@ def main(args):
         error_opt("backend not set")

     if check_backend:
-        if tracetool.backend.exists(arg_backend):
-            sys.exit(0)
-        else:
-            sys.exit(1)
+        for backend in arg_backend.split(","):
+            if tracetool.backend.exists(backend):
+                sys.exit(0)
+            else:
+                sys.exit(1)

     if arg_format == "stap":
         if binary is None:
diff --git a/scripts/tracetool/__init__.py b/scripts/tracetool/__init__.py
index 175df08..a1431d8 100644
--- a/scripts/tracetool/__init__.py
+++ b/scripts/tracetool/__init__.py
@@ -242,16 +242,23 @@ def generate(fevents, format, backend,
     if not tracetool.format.exists(mformat):
         raise TracetoolError("unknown format: %s" % format)

-    backend = str(backend)
-    if len(backend) is 0:
-        raise TracetoolError("backend not set")
-    mbackend = backend.replace("-", "_")
-    if not tracetool.backend.exists(mbackend):
-        raise TracetoolError("unknown backend: %s" % backend)
+    backends = str(backend).split(",")
+    for backend in backends:
+        if len(backend) is 0:
+            raise TracetoolError("backend not set")

-    if not tracetool.backend.compatible(mbackend, mformat):
-        raise TracetoolError("backend '%s' not compatible with format '%s'" %
-                             (backend, format))
+    # At least one backend must support the format
+    compat = False
+    for backend in backends:
+        mbackend = backend.replace("-", "_")
+        if not tracetool.backend.exists(mbackend):
+            raise TracetoolError("unknown backend: %s" % backend)
+
+        compat |= tracetool.backend.compatible(mbackend, mformat)
+
+    if not compat:
+        raise TracetoolError("backends '%s' not compatible with format '%s'" %
+                             (",".join(backends), format))

     import tracetool.backend.dtrace
     tracetool.backend.dtrace.BINARY = binary
@@ -259,15 +266,15 @@ def generate(fevents, format, backend,

     events = _read_events(fevents)

-    if backend == "nop":
+    if backends == ["nop"]:
         ( e.properies.add("disable") for e in events )

     tracetool.format.generate_begin(mformat, events)
-    tracetool.backend.generate("nop", format,
+    tracetool.backend.generate(["nop"], format,
                                [ e
                                  for e in events
                                  if "disable" in e.properties ])
-    tracetool.backend.generate(backend, format,
+    tracetool.backend.generate(backends, format,
                                [ e
                                  for e in events
                                  if "disable" not in e.properties ])
diff --git a/scripts/tracetool/backend/__init__.py 
b/scripts/tracetool/backend/__init__.py
index f0314ee..4c703d7 100644
--- a/scripts/tracetool/backend/__init__.py
+++ b/scripts/tracetool/backend/__init__.py
@@ -102,28 +102,34 @@ def compatible(backend, format):
     if backend == "nop":
         return True
     else:
-        func = tracetool.try_import("tracetool.backend." + backend,
-                                    format, None)[1]
-        return func is not None
+        # Check whether format is declared in supported_formats.
+        supported_formats = tracetool.try_import("tracetool.backend." + 
backend,
+                                                 "supported_formats")[1]
+        return format in supported_formats


 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))
+def generate(backends, format, events):
+    """Generate the per-event output for the given (backends, format) pair."""

-    backend = backend.replace("-", "_")
+    # At least one backend must support the format
+    compat = False
+    for backend in backends:
+        compat |= compatible(backend, format)
+    if not compat:
+        raise ValueError("backends '%s' not compatible with format '%s'" %
+                         (",".join(backends), format))
+
+    backends = map(lambda x: x.replace("-", "_"), backends)
     format = format.replace("-", "_")

-    if backend == "nop":
+    if backends == ["nop"]:
         func = tracetool.try_import("tracetool.format." + format,
                                     "nop", _empty)[1]
+        func(events)
     else:
-        func = tracetool.try_import("tracetool.backend." + backend,
+        func = tracetool.try_import("tracetool.backend.common",
                                     format, None)[1]
-
-    func(events)
+        func(backends, events)
diff --git a/scripts/tracetool/backend/common.py 
b/scripts/tracetool/backend/common.py
new file mode 100644
index 0000000..2974606
--- /dev/null
+++ b/scripts/tracetool/backend/common.py
@@ -0,0 +1,101 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+Common part of tracing backend.
+"""
+
+__author__     = "Kazuya Saito <address@hidden>"
+__copyright__  = "Copyright (C) 2014 Fujitsu, Ltd."
+__license__    = "GPL version 2 or (at your option) any later version"
+
+__maintainer__ = "Stefan Hajnoczi"
+__email__      = "address@hidden"
+
+
+from tracetool import out
+import tracetool
+
+PUBLIC = False
+
+def c(backends, events):
+    func_head_lst = []
+    func_body_lst = []
+    for backend in backends:
+        func_head_lst.append(tracetool.try_import("tracetool.backend." + 
backend,
+                                                  "c_head", None)[1])
+        func_body_lst.append(tracetool.try_import("tracetool.backend." + 
backend,
+                                                  "c_body", None)[1])
+
+    out('#include "trace/control.h"',
+        '#include "trace.h"',
+        '',
+        )
+    for func_head in func_head_lst:
+        func_head()
+
+    for num, event in enumerate(events):
+        out('void trace_%(name)s(%(args)s) {',
+            name = event.name,
+            args = event.args)
+
+        for func_body in func_body_lst:
+            func_body(num, event)
+        out('}')
+
+def h(backends, events):
+    func_head_lst = []
+    func_body_lst = []
+    for backend in backends:
+        func_head_lst.append(tracetool.try_import("tracetool.backend." + 
backend,
+                                                  "h_head", None)[1])
+        func_body_lst.append(tracetool.try_import("tracetool.backend." + 
backend,
+                                                  "h_body", None)[1])
+
+    for func_head in func_head_lst:
+        func_head()
+
+    for event in events:
+        out('void trace_%(name)s(%(args)s);',
+            name = event.name,
+            args = event.args)
+
+        for func_body in func_body_lst:
+            func_body(event)
+
+def stap(backends, events):
+    # Only dtrace backend has format "stap"
+    func = tracetool.try_import("tracetool.backend.dtrace",
+                                "stap", None)[1]
+    func(events)
+
+def d(backends, events):
+    # Only dtrace backend has format "d"
+    func = tracetool.try_import("tracetool.backend.dtrace",
+                                "d", None)[1]
+    func(events)
+
+def events_h(backends, events):
+    # Only events backend has format "events_h"
+    func = tracetool.try_import("tracetool.backend.events",
+                                "events_h", None)[1]
+    func(events)
+
+def events_c(backends, events):
+    # Only events backend has format "events_c"
+    func = tracetool.try_import("tracetool.backend.events",
+                                "events_c", None)[1]
+    func(events)
+
+def ust_events_c(backends, events):
+    # Only ust backend has format "ust_events_c"
+    func = tracetool.try_import("tracetool.backend.ust",
+                                "ust_events_c", None)[1]
+    func(events)
+
+def ust_events_h(backends, events):
+    # Only ust backend has format "ust_events_h"
+    func = tracetool.try_import("tracetool.backend.ust",
+                                "ust_events_h", None)[1]
+    func(events)
+
diff --git a/scripts/tracetool/backend/dtrace.py 
b/scripts/tracetool/backend/dtrace.py
index e31bc79..620a373 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -21,6 +21,8 @@ PUBLIC = True

 PROBEPREFIX = None

+supported_formats = ['c', 'h', 'd', 'stap']
+
 def _probeprefix():
     if PROBEPREFIX is None:
         raise ValueError("you must set PROBEPREFIX")
@@ -34,25 +36,25 @@ def _binary():
         raise ValueError("you must set BINARY")
     return BINARY

-
-def c(events):
+def c_head():
     pass

-
-def h(events):
-    out('#include "trace/generated-tracers-dtrace.h"',
+def c_body(num, event):
+    out('{ /* dtrace */',
+        '    QEMU_%(uppername)s(%(argnames)s);',
+        '}',
+        uppername = event.name.upper(),
+        argnames = ", ".join(event.args.names()),
+        )
+
+def h_head():
+    out('#define SDT_USE_VARIADIC',
+        '#include <sys/sdt.h>',
+        '#include "trace/generated-tracers-dtrace.h"',
         '')

-    for e in events:
-        out('static inline void trace_%(name)s(%(args)s) {',
-            '    QEMU_%(uppername)s(%(argnames)s);',
-            '}',
-            name = e.name,
-            args = e.args,
-            uppername = e.name.upper(),
-            argnames = ", ".join(e.args.names()),
-            )
-
+def h_body(event):
+    pass

 def d(events):
     out('provider qemu {')
@@ -107,3 +109,4 @@ def stap(events):
         out('}')

     out()
+
diff --git a/scripts/tracetool/backend/events.py 
b/scripts/tracetool/backend/events.py
index 5afce3e..19600b7 100644
--- a/scripts/tracetool/backend/events.py
+++ b/scripts/tracetool/backend/events.py
@@ -15,7 +15,7 @@ __license__    = "GPL version 2 or (at your option) any later 
version"
 __maintainer__ = "Stefan Hajnoczi"
 __email__      = "address@hidden"

-
+supported_formats = ['events_c', 'events_h']
 def events_h(events):
     pass

diff --git a/scripts/tracetool/backend/ftrace.py 
b/scripts/tracetool/backend/ftrace.py
index 888c361..f9a6485 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -18,37 +18,41 @@ from tracetool import out

 PUBLIC = True

+supported_formats = ['c', 'h']

-def c(events):
-    pass
+def c_head():
+    out('#include "trace/ftrace.h"',
+        '',
+        )

-def h(events):
+def c_body(num, event):
+    argnames = ", ".join(event.args.names())
+    if len(event.args) > 0:
+        argnames = ", " + argnames
+
+    out('{ /* ftrace */',
+        '    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 = event.name,
+        args = event.args,
+        event_id = "TRACE_" + event.name.upper(),
+        fmt = event.fmt.rstrip("\n"),
+        argnames = argnames,
+        )
+
+def h_head():
     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 h_body(event):
+    pass
diff --git a/scripts/tracetool/backend/simple.py 
b/scripts/tracetool/backend/simple.py
index 3dde372..cfc410a 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -18,6 +18,7 @@ from tracetool import out

 PUBLIC = True

+supported_formats = ['c', 'h']

 def is_string(arg):
     strtype = ('const char*', 'char*', 'const char *', 'char *')
@@ -26,76 +27,73 @@ def is_string(arg):
     else:
         return False

-def c(events):
-    out('#include "trace.h"',
-        '#include "trace/control.h"',
-        '#include "trace/simple.h"',
+def c_head():
+    out('#include "trace/simple.h"',
         '',
         )

-    for num, event in enumerate(events):
-        out('void trace_%(name)s(%(args)s)',
-            '{',
-            '    TraceBufferRecord rec;',
-            name = event.name,
-            args = event.args,
-            )
-        sizes = []
+def c_body(num, event):
+    out('{ /* simple */',
+        '    TraceBufferRecord rec;',
+        name = event.name,
+        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('',
+        '    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_enum)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('    size_t arg%(name)s_len = %(name)s ? 
MIN(strlen(%(name)s), MAX_TRACE_STRLEN) : 0;',
+                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,
                    )
-                strsizeinfo = "4 + arg%s_len" % name
-                sizes.append(strsizeinfo)
+            # primitive data type
             else:
-                sizes.append("8")
-        sizestr = " + ".join(sizes)
-        if len(event.args) == 0:
-            sizestr = '0'
-
-
-        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 trace_%(name)s(%(args)s);',
-            name = event.name,
-            args = event.args,
-            )
+                out('    trace_record_write_u64(&rec, (uint64_t)%(name)s);',
+                   name = name,
+                   )
+
+    out('    trace_record_finish(&rec);',
+        '}',
+        '')
+
+
+def h_head():
+     out('#include "trace/simple.h"',
+        '',
+        )
+def h_body(event):
+    pass
diff --git a/scripts/tracetool/backend/stderr.py 
b/scripts/tracetool/backend/stderr.py
index 6f93dbd..5dd7d95 100644
--- a/scripts/tracetool/backend/stderr.py
+++ b/scripts/tracetool/backend/stderr.py
@@ -18,31 +18,34 @@ from tracetool import out

 PUBLIC = True

+supported_formats = ['c', 'h']

-def c(events):
+def c_head():
     pass

-def h(events):
+def c_body(num, event):
+    argnames = ", ".join(event.args.names())
+    if len(event.args) > 0:
+        argnames = ", " + argnames
+
+    out('{ /* stderr */',
+        '    bool _state = trace_event_get_state(%(event_id)s);',
+        '    if (_state) {',
+        '        fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
+        '    }',
+        '}',
+        name = event.name,
+        args = event.args,
+        event_id = "TRACE_" + event.name.upper(),
+        fmt = event.fmt.rstrip("\n"),
+        argnames = argnames,
+        )
+
+def h_head():
     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 trace_%(name)s(%(args)s)',
-            '{',
-            '    bool _state = trace_event_get_state(%(event_id)s);',
-            '    if (_state) {',
-            '        fprintf(stderr, "%(name)s " %(fmt)s "\\n" %(argnames)s);',
-            '    }',
-            '}',
-            name = e.name,
-            args = e.args,
-            event_id = "TRACE_" + e.name.upper(),
-            fmt = e.fmt.rstrip("\n"),
-            argnames = argnames,
-            )
+def h_body(event):
+    pass
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index 41c1c75..e2316be 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -17,29 +17,31 @@ from tracetool import out


 PUBLIC = True
+supported_formats = ['c', 'h', 'ust_events_c', 'ust_events_h']

-def c(events):
+def c_head():
     pass

+def c_body(num, event):
+    argnames = ", ".join(event.args.names())
+    if len(event.args) > 0:
+        argnames = ", " + argnames

-def h(events):
+    out('{ /* ust */',
+        '    tracepoint(qemu, %(name)s%(tp_args)s);',
+        '}',
+        name = event.name,
+        args = event.args,
+        tp_args = argnames,
+        )
+
+def h_head():
     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 trace_%(name)s(%(args)s)',
-            '{',
-            '    tracepoint(qemu, %(name)s%(tp_args)s);',
-            '}',
-            '',
-            name = e.name,
-            args = e.args,
-            tp_args = argnames,
-            )
+
+def h_body(event):
+    pass

 def ust_events_c(events):
     pass
@@ -79,4 +81,4 @@ def ust_events_h(events):
                 ')',
                 '',
                 name = e.name,
-                )
\ No newline at end of file
+                )
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index d321946..825bda7 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -3,7 +3,7 @@
 ######################################################################
 # Auto-generated event descriptions for LTTng ust code

-ifeq ($(TRACE_BACKEND),ust)
+ifeq ($(findstring ust,$(TRACE_BACKEND)),ust)
 $(obj)/generated-ust-provider.h: $(obj)/generated-ust-provider.h-timestamp
 $(obj)/generated-ust-provider.h-timestamp: $(SRC_PATH)/trace-events
        $(call quiet-command,$(TRACETOOL) \
@@ -60,7 +60,7 @@ $(obj)/generated-tracers.h-timestamp: 
$(SRC_PATH)/trace-events $(BUILD_DIR)/conf
 ######################################################################
 # Auto-generated tracing routines (non-DTrace)

-ifneq ($(TRACE_BACKEND),dtrace)
+ifneq ($(findstring dtrace,$(TRACE_BACKEND)),dtrace)
 $(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
        @cmp -s $< $@ || cp $< $@
 $(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events 
$(BUILD_DIR)/config-host.mak
@@ -79,7 +79,14 @@ endif
 # Normal practice is to name DTrace probe file with a '.d' extension
 # but that gets picked up by QEMU's Makefile as an external dependency
 # rule file. So we use '.dtrace' instead
-ifeq ($(TRACE_BACKEND),dtrace)
+ifeq ($(findstring dtrace,$(TRACE_BACKEND)),dtrace)
+$(obj)/generated-tracers.c: $(obj)/generated-tracers.c-timestamp
+       @cmp -s $< $@ || cp $< $@
+$(obj)/generated-tracers.c-timestamp: $(SRC_PATH)/trace-events 
$(BUILD_DIR)/config-host.mak
+       $(call quiet-command,$(TRACETOOL) \
+               --format=c \
+               --backend=$(TRACE_BACKEND) \
+               < $< > $@,"  GEN   $(patsubst %-timestamp,%,$@)")
 $(obj)/generated-tracers.dtrace: $(obj)/generated-tracers.dtrace-timestamp
 $(obj)/generated-tracers.dtrace-timestamp: $(SRC_PATH)/trace-events 
$(BUILD_DIR)/config-host.mak
        $(call quiet-command,$(TRACETOOL) \
@@ -91,15 +98,18 @@ $(obj)/generated-tracers.dtrace-timestamp: 
$(SRC_PATH)/trace-events $(BUILD_DIR)
 $(obj)/generated-tracers-dtrace.h: $(obj)/generated-tracers.dtrace
        $(call quiet-command,dtrace -o $@ -h -s $<, "  GEN   $@")

-$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace
+$(obj)/generated-tracers.o: $(obj)/generated-tracers.dtrace 
$(obj)/generated-tracers.c $(obj)/generated-tracers.h
 endif

 ######################################################################
 # Backend code

-util-obj-$(CONFIG_TRACE_DEFAULT) += default.o
+ifeq ($(CONFIG_TRACE_DEFAULT),y)
+util-obj-y += default.o
+else
+util-obj-y += multi.o
+endif
 util-obj-$(CONFIG_TRACE_SIMPLE) += simple.o
-util-obj-$(CONFIG_TRACE_STDERR) += stderr.o
 util-obj-$(CONFIG_TRACE_FTRACE) += ftrace.o
 util-obj-$(CONFIG_TRACE_UST) += generated-ust.o
 util-obj-y += control.o
diff --git a/trace/ftrace.c b/trace/ftrace.c
index 46b7fdb..e2f118e 100644
--- a/trace/ftrace.c
+++ b/trace/ftrace.c
@@ -42,35 +42,13 @@ static int find_debugfs(char *debugfs)
     return 1;
 }

-void trace_print_events(FILE *stream, fprintf_function stream_printf)
-{
-    TraceEventID i;
-
-    for (i = 0; i < trace_event_count(); i++) {
-        TraceEvent *ev = trace_event_id(i);
-        stream_printf(stream, "%s [Event ID %u] : state %u\n",
-                      trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
-    }
-}
-
-void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
-{
-    ev->dstate = state;
-}
-
-bool trace_backend_init(const char *events, const char *file)
+bool ftrace_backend_init(const char *events, const char *file)
 {
     char debugfs[PATH_MAX];
     char path[PATH_MAX];
     int debugfs_found;
     int trace_fd = -1;

-    if (file) {
-        fprintf(stderr, "error: -trace file=...: "
-                "option not supported by the selected tracing backend\n");
-        return false;
-    }
-
     debugfs_found = find_debugfs(debugfs);
     if (debugfs_found) {
         snprintf(path, PATH_MAX, "%s/tracing/tracing_on", debugfs);
@@ -97,6 +75,5 @@ bool trace_backend_init(const char *events, const char *file)
         return false;
     }

-    trace_backend_init_events(events);
     return true;
 }
diff --git a/trace/ftrace.h b/trace/ftrace.h
index 94cb8d5..f508f33 100644
--- a/trace/ftrace.h
+++ b/trace/ftrace.h
@@ -6,5 +6,6 @@
 #define STR(x) _STR(x)

 extern int trace_marker_fd;
+bool ftrace_backend_init(const char *events, const char *file);

 #endif /* ! TRACE_FTRACE_H */
diff --git a/trace/multi.c b/trace/multi.c
new file mode 100644
index 0000000..19f7ce8
--- /dev/null
+++ b/trace/multi.c
@@ -0,0 +1,51 @@
+/*
+ * Multi trace backend
+ */
+
+#include <stdio.h>
+#include "trace.h"
+#include "trace/control.h"
+
+void trace_print_events(FILE *stream, fprintf_function stream_printf)
+{
+    TraceEventID i;
+
+    for (i = 0; i < trace_event_count(); i++) {
+        TraceEvent *ev = trace_event_id(i);
+        stream_printf(stream, "%s [Event ID %u] : state %u\n",
+                      trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
+    }
+}
+
+void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
+{
+    ev->dstate = state;
+}
+
+bool trace_backend_init(const char *events, const char *file)
+{
+#ifndef CONFIG_TRACE_SIMPLE
+    if (file) {
+        fprintf(stderr, "error: -trace file=...: "
+                "option not supported by the selected tracing backend\n");
+        return false;
+    }
+#endif
+
+#ifdef CONFIG_TRACE_SIMPLE
+    if (!simpletrace_backend_init(events, file)) {
+            fprintf(stderr, "failed to initialize simple tracing backend.\n");
+            return false;
+    }
+#endif
+
+#ifdef CONFIG_TRACE_FTRACE
+    if (!ftrace_backend_init(events, file)) {
+            fprintf(stderr, "failed to initialize ftrace backend.\n");
+            return false;
+    }
+#endif
+
+    trace_backend_init_events(events);
+    return true;
+}
diff --git a/trace/simple.c b/trace/simple.c
index 57572c4..0dfd5d4 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -366,22 +366,6 @@ void st_flush_trace_buffer(void)
     flush_trace_file(true);
 }

-void trace_print_events(FILE *stream, fprintf_function stream_printf)
-{
-    unsigned int i;
-
-    for (i = 0; i < trace_event_count(); i++) {
-        TraceEvent *ev = trace_event_id(i);
-        stream_printf(stream, "%s [Event ID %u] : state %u\n",
-                      trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
-    }
-}
-
-void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
-{
-    ev->dstate = state;
-}
-
 /* Helper function to create a thread with signals blocked.  Use glib's
  * portable threads since QEMU abstractions cannot be used due to reentrancy in
  * the tracer.  Also note the signal masking on POSIX hosts so that the thread
@@ -410,7 +394,7 @@ static GThread *trace_thread_create(GThreadFunc fn)
     return thread;
 }

-bool trace_backend_init(const char *events, const char *file)
+bool simpletrace_backend_init(const char *events, const char *file)
 {
     GThread *thread;

diff --git a/trace/simple.h b/trace/simple.h
index 5260d9a..6cc17a5 100644
--- a/trace/simple.h
+++ b/trace/simple.h
@@ -54,4 +54,5 @@ void trace_record_write_str(TraceBufferRecord *rec, const 
char *s, uint32_t slen
  */
 void trace_record_finish(TraceBufferRecord *rec);

+bool simpletrace_backend_init(const char *events, const char *file);
 #endif /* TRACE_SIMPLE_H */
diff --git a/trace/stderr.c b/trace/stderr.c
deleted file mode 100644
index e212efd..0000000
--- a/trace/stderr.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "trace.h"
-#include "trace/control.h"
-
-
-void trace_print_events(FILE *stream, fprintf_function stream_printf)
-{
-    TraceEventID i;
-
-    for (i = 0; i < trace_event_count(); i++) {
-        TraceEvent *ev = trace_event_id(i);
-        stream_printf(stream, "%s [Event ID %u] : state %u\n",
-                      trace_event_get_name(ev), i, 
trace_event_get_state_dynamic(ev));
-    }
-}
-
-void trace_event_set_state_dynamic_backend(TraceEvent *ev, bool state)
-{
-    ev->dstate = state;
-}
-
-bool trace_backend_init(const char *events, const char *file)
-{
-    if (file) {
-        fprintf(stderr, "error: -trace file=...: "
-                "option not supported by the selected tracing backend\n");
-        return false;
-    }
-    trace_backend_init_events(events);
-    return true;
-}
-- 
1.7.1





reply via email to

[Prev in Thread] Current Thread [Next in Thread]