Background
==========
The current filter interpreter function signature looks like this:
uint64_t lttng_bytecode_filter_interpret(void *filter_data,
const char *filter_stack_data);
The upcoming capture interpreter function will need an output parameter
to extract the top of stack register. It will look like this:
uint64_t lttng_bytecode_capture_interpret(void *capture_data,
const char *capture_stack_data,
struct output_register *output);
Problems
========
We can't reuse the same function pointer field in `struct
lttng_bytecode_runtime` as the two interpreter functions will have
different signatures.
We can't change the signature of this existing filter function because
it's used in the tracepoint probes.
Solution
========
Add a union of callbacks to hold both interpreter functions. This also
doesn't change the layout of the `struct lttng_bytecode_runtime`
objects.
Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I9fcd6def9ce7783087b9648ddbf5ec71fb7b997a
struct lttng_bytecode_runtime {
/* Associated bytecode */
struct lttng_ust_bytecode_node *bc;
struct lttng_bytecode_runtime {
/* Associated bytecode */
struct lttng_ust_bytecode_node *bc;
- uint64_t (*filter)(void *interpreter_data,
- const char *interpreter_stack_data);
+ union {
+ uint64_t (*filter)(void *interpreter_data,
+ const char *interpreter_stack_data);
+ } interpreter_funcs;
int link_failed;
struct cds_list_head node; /* list of bytecode runtime in event */
/*
int link_failed;
struct cds_list_head node; /* list of bytecode runtime in event */
/*
__event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
_TP_ARGS_DATA_VAR(_args)); \
tp_list_for_each_entry_rcu(__filter_bc_runtime, &__event->filter_bytecode_runtime_head, node) { \
__event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
_TP_ARGS_DATA_VAR(_args)); \
tp_list_for_each_entry_rcu(__filter_bc_runtime, &__event->filter_bytecode_runtime_head, node) { \
- if (caa_unlikely(__filter_bc_runtime->filter(__filter_bc_runtime, \
+ if (caa_unlikely(__filter_bc_runtime->interpreter_funcs.filter(__filter_bc_runtime, \
__stackvar.__filter_stack_data) & LTTNG_INTERPRETER_RECORD_FLAG)) { \
__filter_record = 1; \
break; \
__stackvar.__filter_stack_data) & LTTNG_INTERPRETER_RECORD_FLAG)) { \
__filter_record = 1; \
break; \
__event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
_TP_ARGS_DATA_VAR(_args)); \
tp_list_for_each_entry_rcu(__filter_bc_runtime, &__event_notifier->filter_bytecode_runtime_head, node) { \
__event_prepare_filter_stack__##_provider##___##_name(__stackvar.__filter_stack_data, \
_TP_ARGS_DATA_VAR(_args)); \
tp_list_for_each_entry_rcu(__filter_bc_runtime, &__event_notifier->filter_bytecode_runtime_head, node) { \
- if (caa_unlikely(__filter_bc_runtime->filter(__filter_bc_runtime, \
+ if (caa_unlikely(__filter_bc_runtime->interpreter_funcs.filter(__filter_bc_runtime, \
__stackvar.__filter_stack_data) & LTTNG_INTERPRETER_RECORD_FLAG)) \
__filter_record = 1; \
} \
__stackvar.__filter_stack_data) & LTTNG_INTERPRETER_RECORD_FLAG)) \
__filter_record = 1; \
} \
if (ret) {
goto link_error;
}
if (ret) {
goto link_error;
}
- runtime->p.filter = lttng_bytecode_filter_interpret;
+
+ switch (bytecode->type) {
+ case LTTNG_UST_BYTECODE_NODE_TYPE_FILTER:
+ runtime->p.interpreter_funcs.filter = lttng_bytecode_filter_interpret;
+ break;
+ default:
+ abort();
+ }
+
runtime->p.link_failed = 0;
cds_list_add_rcu(&runtime->p.node, insert_loc);
dbg_printf("Linking successful.\n");
return 0;
link_error:
runtime->p.link_failed = 0;
cds_list_add_rcu(&runtime->p.node, insert_loc);
dbg_printf("Linking successful.\n");
return 0;
link_error:
- runtime->p.filter = lttng_bytecode_filter_interpret_false;
+ switch (bytecode->type) {
+ case LTTNG_UST_BYTECODE_NODE_TYPE_FILTER:
+ runtime->p.interpreter_funcs.filter = lttng_bytecode_filter_interpret_false;
+ break;
+ default:
+ abort();
+ }
+
runtime->p.link_failed = 1;
cds_list_add_rcu(&runtime->p.node, insert_loc);
alloc_error:
runtime->p.link_failed = 1;
cds_list_add_rcu(&runtime->p.node, insert_loc);
alloc_error:
struct lttng_ust_bytecode_node *bc = runtime->bc;
if (!bc->enabler->enabled || runtime->link_failed)
struct lttng_ust_bytecode_node *bc = runtime->bc;
if (!bc->enabler->enabled || runtime->link_failed)
- runtime->filter = lttng_bytecode_filter_interpret_false;
+ runtime->interpreter_funcs.filter = lttng_bytecode_filter_interpret_false;
- runtime->filter = lttng_bytecode_filter_interpret;
+ runtime->interpreter_funcs.filter = lttng_bytecode_filter_interpret;