diff options
Diffstat (limited to 'tools/perf/util/scripting-engines/trace-event-python.c')
| -rw-r--r-- | tools/perf/util/scripting-engines/trace-event-python.c | 115 | 
1 files changed, 109 insertions, 6 deletions
| diff --git a/tools/perf/util/scripting-engines/trace-event-python.c b/tools/perf/util/scripting-engines/trace-event-python.c index a8e825fca42a..d72fafc1c800 100644 --- a/tools/perf/util/scripting-engines/trace-event-python.c +++ b/tools/perf/util/scripting-engines/trace-event-python.c @@ -41,6 +41,9 @@  #include "../thread-stack.h"  #include "../trace-event.h"  #include "../machine.h" +#include "thread_map.h" +#include "cpumap.h" +#include "stat.h"  PyMODINIT_FUNC initperf_trace_context(void); @@ -859,6 +862,104 @@ static void python_process_event(union perf_event *event,  	}  } +static void get_handler_name(char *str, size_t size, +			     struct perf_evsel *evsel) +{ +	char *p = str; + +	scnprintf(str, size, "stat__%s", perf_evsel__name(evsel)); + +	while ((p = strchr(p, ':'))) { +		*p = '_'; +		p++; +	} +} + +static void +process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, +	     struct perf_counts_values *count) +{ +	PyObject *handler, *t; +	static char handler_name[256]; +	int n = 0; + +	t = PyTuple_New(MAX_FIELDS); +	if (!t) +		Py_FatalError("couldn't create Python tuple"); + +	get_handler_name(handler_name, sizeof(handler_name), +			 counter); + +	handler = get_handler(handler_name); +	if (!handler) { +		pr_debug("can't find python handler %s\n", handler_name); +		return; +	} + +	PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); +	PyTuple_SetItem(t, n++, PyInt_FromLong(thread)); + +	tuple_set_u64(t, n++, tstamp); +	tuple_set_u64(t, n++, count->val); +	tuple_set_u64(t, n++, count->ena); +	tuple_set_u64(t, n++, count->run); + +	if (_PyTuple_Resize(&t, n) == -1) +		Py_FatalError("error resizing Python tuple"); + +	call_object(handler, t, handler_name); + +	Py_DECREF(t); +} + +static void python_process_stat(struct perf_stat_config *config, +				struct perf_evsel *counter, u64 tstamp) +{ +	struct thread_map *threads = counter->threads; +	struct cpu_map *cpus = counter->cpus; +	int cpu, thread; + +	if (config->aggr_mode == AGGR_GLOBAL) { +		process_stat(counter, -1, -1, tstamp, +			     &counter->counts->aggr); +		return; +	} + +	for (thread = 0; thread < threads->nr; thread++) { +		for (cpu = 0; cpu < cpus->nr; cpu++) { +			process_stat(counter, cpus->map[cpu], +				     thread_map__pid(threads, thread), tstamp, +				     perf_counts(counter->counts, cpu, thread)); +		} +	} +} + +static void python_process_stat_interval(u64 tstamp) +{ +	PyObject *handler, *t; +	static const char handler_name[] = "stat__interval"; +	int n = 0; + +	t = PyTuple_New(MAX_FIELDS); +	if (!t) +		Py_FatalError("couldn't create Python tuple"); + +	handler = get_handler(handler_name); +	if (!handler) { +		pr_debug("can't find python handler %s\n", handler_name); +		return; +	} + +	tuple_set_u64(t, n++, tstamp); + +	if (_PyTuple_Resize(&t, n) == -1) +		Py_FatalError("error resizing Python tuple"); + +	call_object(handler, t, handler_name); + +	Py_DECREF(t); +} +  static int run_start_sub(void)  {  	main_module = PyImport_AddModule("__main__"); @@ -1201,10 +1302,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile)  }  struct scripting_ops python_scripting_ops = { -	.name = "Python", -	.start_script = python_start_script, -	.flush_script = python_flush_script, -	.stop_script = python_stop_script, -	.process_event = python_process_event, -	.generate_script = python_generate_script, +	.name			= "Python", +	.start_script		= python_start_script, +	.flush_script		= python_flush_script, +	.stop_script		= python_stop_script, +	.process_event		= python_process_event, +	.process_stat		= python_process_stat, +	.process_stat_interval	= python_process_stat_interval, +	.generate_script	= python_generate_script,  }; | 
