Commit 20018398 authored by Ze Gao's avatar Ze Gao Committed by Namhyung Kim

perf evsel: Rename get_states() to parse_task_states() and make it public

Since get_states() assumes the existence of libtraceevent, so move
to where it should belong, i.e, util/trace-event-parse.c, and also
rename it to parse_task_states().

Leave evsel_getstate() untouched as it fits well in the evsel
category.

Also make some necessary tweaks for python support, and get it
verified with: perf test python.
Signed-off-by: default avatarZe Gao <zegao@tencent.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240123070210.1669843-2-zegao@tencent.com
parent 7727d59d
......@@ -370,7 +370,7 @@ python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT
ifeq ($(CONFIG_LIBTRACEEVENT),y)
PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
else
PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c util/python-ext-sources)
PYTHON_EXT_SRCS := $(shell grep -v ^\#\\\|util/trace-event.c\\\|util/trace-event-parse.c util/python-ext-sources)
endif
PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBAPI)
......
......@@ -2851,119 +2851,6 @@ u64 evsel__intval_common(struct evsel *evsel, struct perf_sample *sample, const
return field ? format_field__intval(field, sample, evsel->needs_swap) : 0;
}
/*
* prev_state is of size long, which is 32 bits on 32 bit architectures.
* As it needs to have the same bits for both 32 bit and 64 bit architectures
* we can just assume that the flags we care about will all be within
* the 32 bits.
*/
#define MAX_STATE_BITS 32
static const char *convert_sym(struct tep_print_flag_sym *sym)
{
static char save_states[MAX_STATE_BITS + 1];
memset(save_states, 0, sizeof(save_states));
/* This is the flags for the prev_state_field, now make them into a string */
for (; sym; sym = sym->next) {
long bitmask = strtoul(sym->value, NULL, 0);
int i;
for (i = 0; !(bitmask & 1); i++)
bitmask >>= 1;
if (i >= MAX_STATE_BITS)
continue;
save_states[i] = sym->str[0];
}
return save_states;
}
static struct tep_print_arg_field *
find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_arg_field *field;
if (!arg)
return NULL;
if (arg->type == TEP_PRINT_FIELD)
return &arg->field;
if (arg->type == TEP_PRINT_OP) {
field = find_arg_field(prev_state_field, arg->op.left);
if (field && field->field == prev_state_field)
return field;
field = find_arg_field(prev_state_field, arg->op.right);
if (field && field->field == prev_state_field)
return field;
}
return NULL;
}
static struct tep_print_flag_sym *
test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_arg_field *field;
field = find_arg_field(prev_state_field, arg->flags.field);
if (!field)
return NULL;
return arg->flags.flags;
}
static struct tep_print_flag_sym *
search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_flag_sym *sym = NULL;
if (!arg)
return NULL;
if (arg->type == TEP_PRINT_OP) {
sym = search_op(prev_state_field, arg->op.left);
if (sym)
return sym;
sym = search_op(prev_state_field, arg->op.right);
if (sym)
return sym;
} else if (arg->type == TEP_PRINT_FLAGS) {
sym = test_flags(prev_state_field, arg);
}
return sym;
}
static const char *get_states(struct tep_format_field *prev_state_field)
{
struct tep_print_flag_sym *sym;
struct tep_print_arg *arg;
struct tep_event *event;
event = prev_state_field->event;
/*
* Look at the event format fields, and search for where
* the prev_state is parsed via the format flags.
*/
for (arg = event->print_fmt.args; arg; arg = arg->next) {
/*
* Currently, the __print_flags() for the prev_state
* is embedded in operations, so they too must be
* searched.
*/
sym = search_op(prev_state_field, arg);
if (sym)
return convert_sym(sym);
}
return NULL;
}
char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const char *name)
{
static struct tep_format_field *prev_state_field;
......@@ -2979,7 +2866,7 @@ char evsel__taskstate(struct evsel *evsel, struct perf_sample *sample, const cha
return state;
if (!states || field != prev_state_field) {
states = get_states(field);
states = parse_task_states(field);
if (!states)
return state;
prev_state_field = field;
......
......@@ -31,6 +31,7 @@ util/counts.c
util/print_binary.c
util/strlist.c
util/trace-event.c
util/trace-event-parse.c
../lib/rbtree.c
util/string.c
util/symbol_fprintf.c
......
......@@ -85,6 +85,7 @@ if '-DHAVE_LIBTRACEEVENT' in cflags:
extra_libraries += [ 'traceevent' ]
else:
ext_sources.remove('util/trace-event.c')
ext_sources.remove('util/trace-event-parse.c')
# use full paths with source files
ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources))
......
......@@ -122,6 +122,119 @@ void event_format__print(struct tep_event *event,
return event_format__fprintf(event, cpu, data, size, stdout);
}
/*
* prev_state is of size long, which is 32 bits on 32 bit architectures.
* As it needs to have the same bits for both 32 bit and 64 bit architectures
* we can just assume that the flags we care about will all be within
* the 32 bits.
*/
#define MAX_STATE_BITS 32
static const char *convert_sym(struct tep_print_flag_sym *sym)
{
static char save_states[MAX_STATE_BITS + 1];
memset(save_states, 0, sizeof(save_states));
/* This is the flags for the prev_state_field, now make them into a string */
for (; sym; sym = sym->next) {
long bitmask = strtoul(sym->value, NULL, 0);
int i;
for (i = 0; !(bitmask & 1); i++)
bitmask >>= 1;
if (i >= MAX_STATE_BITS)
continue;
save_states[i] = sym->str[0];
}
return save_states;
}
static struct tep_print_arg_field *
find_arg_field(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_arg_field *field;
if (!arg)
return NULL;
if (arg->type == TEP_PRINT_FIELD)
return &arg->field;
if (arg->type == TEP_PRINT_OP) {
field = find_arg_field(prev_state_field, arg->op.left);
if (field && field->field == prev_state_field)
return field;
field = find_arg_field(prev_state_field, arg->op.right);
if (field && field->field == prev_state_field)
return field;
}
return NULL;
}
static struct tep_print_flag_sym *
test_flags(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_arg_field *field;
field = find_arg_field(prev_state_field, arg->flags.field);
if (!field)
return NULL;
return arg->flags.flags;
}
static struct tep_print_flag_sym *
search_op(struct tep_format_field *prev_state_field, struct tep_print_arg *arg)
{
struct tep_print_flag_sym *sym = NULL;
if (!arg)
return NULL;
if (arg->type == TEP_PRINT_OP) {
sym = search_op(prev_state_field, arg->op.left);
if (sym)
return sym;
sym = search_op(prev_state_field, arg->op.right);
if (sym)
return sym;
} else if (arg->type == TEP_PRINT_FLAGS) {
sym = test_flags(prev_state_field, arg);
}
return sym;
}
const char *parse_task_states(struct tep_format_field *state_field)
{
struct tep_print_flag_sym *sym;
struct tep_print_arg *arg;
struct tep_event *event;
event = state_field->event;
/*
* Look at the event format fields, and search for where
* the prev_state is parsed via the format flags.
*/
for (arg = event->print_fmt.args; arg; arg = arg->next) {
/*
* Currently, the __print_flags() for the prev_state
* is embedded in operations, so they too must be
* searched.
*/
sym = search_op(state_field, arg);
if (sym)
return convert_sym(sym);
}
return NULL;
}
void parse_ftrace_printk(struct tep_handle *pevent,
char *file, unsigned int size __maybe_unused)
{
......
......@@ -15,6 +15,7 @@ struct perf_tool;
struct thread;
struct tep_plugin_list;
struct evsel;
struct tep_format_field;
struct trace_event {
struct tep_handle *pevent;
......@@ -51,6 +52,8 @@ int parse_event_file(struct tep_handle *pevent,
unsigned long long
raw_field_value(struct tep_event *event, const char *name, void *data);
const char *parse_task_states(struct tep_format_field *state_field);
void parse_proc_kallsyms(struct tep_handle *pevent, char *file, unsigned int size);
void parse_ftrace_printk(struct tep_handle *pevent, char *file, unsigned int size);
void parse_saved_cmdline(struct tep_handle *pevent, char *file, unsigned int size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment