Add support to get stat events data in perf python scripts.

Link: http://lkml.kernel.org/n/[email protected]
Signed-off-by: Jiri Olsa <[email protected]>
---
 .../util/scripting-engines/trace-event-python.c    | 113 +++++++++++++++++++--
 1 file changed, 107 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 ace2484985cb..2e771ede9428 100644
--- a/tools/perf/util/scripting-engines/trace-event-python.c
+++ b/tools/perf/util/scripting-engines/trace-event-python.c
@@ -41,6 +41,8 @@
 #include "../thread-stack.h"
 #include "../trace-event.h"
 #include "../machine.h"
+#include "thread_map.h"
+#include "cpumap.h"
 
 PyMODINIT_FUNC initperf_trace_context(void);
 
@@ -858,6 +860,103 @@ 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 time,
+            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));
+       PyTuple_SetItem(t, n++, PyLong_FromLong(time));
+       PyTuple_SetItem(t, n++, PyLong_FromLong(count->val));
+       PyTuple_SetItem(t, n++, PyLong_FromLong(count->ena));
+       PyTuple_SetItem(t, n++, PyLong_FromLong(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 time)
+{
+       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, time,
+                            &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), time,
+                                    perf_counts(counter->counts, cpu, thread));
+               }
+       }
+}
+
+static void python_process_stat_interval(u64 time)
+{
+       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;
+       }
+
+       PyTuple_SetItem(t, n++, PyLong_FromLong(time));
+
+       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__");
@@ -1200,10 +1299,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,
 };
-- 
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to