|
@@ -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,
|
|
|
};
|