mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-25 13:00:09 +01:00
util/u_trace: add support for variable length trace points
Use case being :
struct tp {
...
char string[0];
};
Signed-off-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Reviewed-by: Emma Anholt <emma@anholt.net>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16655>
This commit is contained in:
parent
f1ab070d7f
commit
a34fcaf326
3 changed files with 51 additions and 11 deletions
|
|
@ -801,18 +801,20 @@ u_trace_disable_event_range(struct u_trace_iterator begin_it,
|
|||
* functions.
|
||||
*/
|
||||
void *
|
||||
u_trace_append(struct u_trace *ut, void *cs, const struct u_tracepoint *tp)
|
||||
u_trace_appendv(struct u_trace *ut, void *cs,
|
||||
const struct u_tracepoint *tp, unsigned variable_sz)
|
||||
{
|
||||
struct u_trace_chunk *chunk = get_chunk(ut, tp->payload_sz);
|
||||
unsigned tp_idx = chunk->num_traces++;
|
||||
|
||||
assert(tp->payload_sz == ALIGN_NPOT(tp->payload_sz, 8));
|
||||
|
||||
unsigned payload_sz = ALIGN_NPOT(tp->payload_sz + variable_sz, 8);
|
||||
struct u_trace_chunk *chunk = get_chunk(ut, payload_sz);
|
||||
unsigned tp_idx = chunk->num_traces++;
|
||||
|
||||
/* sub-allocate storage for trace payload: */
|
||||
void *payload = NULL;
|
||||
if (tp->payload_sz > 0) {
|
||||
if (payload_sz > 0) {
|
||||
payload = chunk->payload->next;
|
||||
chunk->payload->next += tp->payload_sz;
|
||||
chunk->payload->next += payload_sz;
|
||||
}
|
||||
|
||||
/* record a timestamp for the trace: */
|
||||
|
|
|
|||
|
|
@ -53,11 +53,17 @@ class Tracepoint(object):
|
|||
assert isinstance(args, list)
|
||||
assert name not in TRACEPOINTS
|
||||
|
||||
|
||||
self.name = name
|
||||
self.args = args
|
||||
if tp_struct is None:
|
||||
tp_struct = args
|
||||
self.tp_struct = tp_struct
|
||||
self.has_variable_arg = False
|
||||
for arg in self.tp_struct:
|
||||
if arg.length_arg != None:
|
||||
self.has_variable_arg = True
|
||||
break
|
||||
self.tp_print = tp_print
|
||||
self.tp_perfetto = tp_perfetto
|
||||
self.tp_markers = tp_markers
|
||||
|
|
@ -97,7 +103,7 @@ class TracepointArgStruct():
|
|||
class TracepointArg(object):
|
||||
"""Class that represents either an argument being passed or a field in a struct
|
||||
"""
|
||||
def __init__(self, type, var, c_format, name=None, to_prim_type=None):
|
||||
def __init__(self, type, var, c_format, name=None, to_prim_type=None, length_arg=None, copy_func=None):
|
||||
"""Parameters:
|
||||
|
||||
- type: argument's C type.
|
||||
|
|
@ -107,6 +113,7 @@ class TracepointArg(object):
|
|||
be displayed in output or perfetto, otherwise var will be used.
|
||||
- to_prim_type: (optional) C function to convert from arg's type to a type
|
||||
compatible with c_format.
|
||||
- length_arg: whether this argument is a variable length array
|
||||
"""
|
||||
assert isinstance(type, str)
|
||||
assert isinstance(var, str)
|
||||
|
|
@ -119,6 +126,8 @@ class TracepointArg(object):
|
|||
name = var
|
||||
self.name = name
|
||||
self.to_prim_type = to_prim_type
|
||||
self.length_arg = length_arg
|
||||
self.copy_func = copy_func
|
||||
|
||||
|
||||
HEADERS = []
|
||||
|
|
@ -215,7 +224,7 @@ void ${trace_toggle_name}_config_variable(void);
|
|||
*/
|
||||
struct trace_${trace_name} {
|
||||
% for arg in trace.tp_struct:
|
||||
${arg.type} ${arg.name};
|
||||
${arg.type} ${arg.name}${"[0]" if arg.length_arg else ""};
|
||||
% endfor
|
||||
% if len(trace.args) == 0:
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -455,10 +464,25 @@ void __trace_${trace_name}(
|
|||
struct trace_${trace_name} entry;
|
||||
UNUSED struct trace_${trace_name} *__entry =
|
||||
enabled_traces & U_TRACE_TYPE_REQUIRE_QUEUING ?
|
||||
% if trace.has_variable_arg:
|
||||
(struct trace_${trace_name} *)u_trace_appendv(ut, ${cs_param_value + ","} &__tp_${trace_name},
|
||||
0
|
||||
% for arg in trace.tp_struct:
|
||||
% if arg.length_arg is not None:
|
||||
+ ${arg.length_arg}
|
||||
% endif
|
||||
% endfor
|
||||
) :
|
||||
% else:
|
||||
(struct trace_${trace_name} *)u_trace_append(ut, ${cs_param_value + ","} &__tp_${trace_name}) :
|
||||
% endif
|
||||
&entry;
|
||||
% for arg in trace.tp_struct:
|
||||
% if arg.length_arg is None:
|
||||
__entry->${arg.name} = ${arg.var};
|
||||
% else:
|
||||
${arg.copy_func}(__entry->${arg.name}, ${arg.var}, ${arg.length_arg});
|
||||
% endif
|
||||
% endfor
|
||||
% if trace.tp_markers is not None:
|
||||
if (enabled_traces & U_TRACE_TYPE_MARKERS)
|
||||
|
|
|
|||
|
|
@ -54,9 +54,23 @@ struct u_tracepoint {
|
|||
};
|
||||
|
||||
/**
|
||||
* Append a tracepoint, returning pointer that can be filled with trace
|
||||
* payload.
|
||||
* Append a tracepoint followed by some amount of memory specified by
|
||||
* variable_sz, returning pointer that can be filled with trace payload.
|
||||
*/
|
||||
void * u_trace_append(struct u_trace *ut, void *cs, const struct u_tracepoint *tp);
|
||||
void * u_trace_appendv(struct u_trace *ut, void *cs,
|
||||
const struct u_tracepoint *tp, unsigned variable_sz);
|
||||
|
||||
/**
|
||||
* Append a trace event, returning pointer to buffer of tp->payload_sz
|
||||
* to be filled in with trace payload. Called by generated tracepoint
|
||||
* functions.
|
||||
*/
|
||||
static inline void *
|
||||
u_trace_append(struct u_trace *ut, void *cs, const struct u_tracepoint *tp)
|
||||
{
|
||||
return u_trace_appendv(ut, cs, tp, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* _U_TRACE_PRIV_H */
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue