Files
qemu/scripts/tracetool/format/rs.py
Paolo Bonzini 3d508e096b tracetool: add Rust DTrace/SystemTap SDT support
Implement DTrace/SystemTap SDT by emitting the following:
- The probe crate's probe!() macro is used to emit a DTrace/SystemTap
  SDT probe.
- Every trace event gets a corresponding trace_<name>_enabled() -> bool
  generated function that Rust code can use to avoid expensive
  computation when a trace event is disabled. This API works for other
  trace backends too.

`#[allow(dead_code)]` additions are necessary for QEMU's dstate in
generated trace-<dir>.rs files since they are unused by the dtrace
backend. `./configure --enable-trace-backends=` can enable multiple
backends, so keep it simple and just silence the warning instead of
trying to detect the condition when generating the dstate code can be
skipped.

The tracetool tests are updated. Take a look at
tests/tracetool/dtrace.rs to see what the new generated code looks like.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Link: https://lore.kernel.org/r/20251119205200.173170-5-stefanha@redhat.com
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2025-12-27 10:11:10 +01:00

84 lines
2.5 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
"""
trace-DIR.rs
"""
__author__ = "Tanish Desai <tanishdesai37@gmail.com>"
__copyright__ = "Copyright 2025, Tanish Desai <tanishdesai37@gmail.com>"
__license__ = "GPL version 2 or (at your option) any later version"
__maintainer__ = "Stefan Hajnoczi"
__email__ = "stefanha@redhat.com"
from tracetool import out
def generate(events, backend, group):
out('// SPDX-License-Identifier: GPL-2.0-or-later',
'// This file is @generated by tracetool, do not edit.',
'',
'#[allow(unused_imports)]',
'use std::ffi::c_char;',
'#[allow(unused_imports)]',
'use util::bindings;',
'',
'#[allow(dead_code)]',
'#[inline(always)]',
'fn trace_event_state_is_enabled(dstate: u16) -> bool {',
' (unsafe { trace_events_enabled_count }) != 0 && dstate != 0',
'}',
'',
'extern "C" {',
' #[allow(dead_code)]',
' static mut trace_events_enabled_count: u32;',
'}',)
out('extern "C" {')
for e in events:
out(' #[allow(dead_code)]',
' static mut %s: u16;' % e.api(e.QEMU_DSTATE))
out('}',
'')
backend.generate_begin(events, group)
for e in events:
out('#[inline(always)]',
'#[allow(dead_code)]',
'pub fn %(api)s() -> bool',
'{',
api=e.api(e.QEMU_RUST_DSTATE))
if "disable" not in e.properties:
backend.generate_backend_dstate(e, group)
if backend.check_trace_event_get_state:
out(' trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) ||',
event_id = 'TRACE_' + e.name.upper())
out(' false',
'}',
'',
'#[inline(always)]',
'#[allow(dead_code)]',
'pub fn %(api)s(%(args)s)',
'{',
api=e.api(e.QEMU_TRACE),
args=e.args.rust_decl())
if "disable" not in e.properties:
backend.generate(e, group, check_trace_event_get_state=False)
if backend.check_trace_event_get_state:
event_id = 'TRACE_' + e.name.upper()
out(' if trace_event_state_is_enabled(unsafe { _%(event_id)s_DSTATE}) {',
event_id = event_id,
api=e.api())
backend.generate(e, group, check_trace_event_get_state=True)
out(' }')
out('}',
'')
backend.generate_end(events, group)