diff options
-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 @@ | |||
41 | #include "../thread-stack.h" | 41 | #include "../thread-stack.h" |
42 | #include "../trace-event.h" | 42 | #include "../trace-event.h" |
43 | #include "../machine.h" | 43 | #include "../machine.h" |
44 | #include "thread_map.h" | ||
45 | #include "cpumap.h" | ||
46 | #include "stat.h" | ||
44 | 47 | ||
45 | PyMODINIT_FUNC initperf_trace_context(void); | 48 | PyMODINIT_FUNC initperf_trace_context(void); |
46 | 49 | ||
@@ -859,6 +862,104 @@ static void python_process_event(union perf_event *event, | |||
859 | } | 862 | } |
860 | } | 863 | } |
861 | 864 | ||
865 | static void get_handler_name(char *str, size_t size, | ||
866 | struct perf_evsel *evsel) | ||
867 | { | ||
868 | char *p = str; | ||
869 | |||
870 | scnprintf(str, size, "stat__%s", perf_evsel__name(evsel)); | ||
871 | |||
872 | while ((p = strchr(p, ':'))) { | ||
873 | *p = '_'; | ||
874 | p++; | ||
875 | } | ||
876 | } | ||
877 | |||
878 | static void | ||
879 | process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, | ||
880 | struct perf_counts_values *count) | ||
881 | { | ||
882 | PyObject *handler, *t; | ||
883 | static char handler_name[256]; | ||
884 | int n = 0; | ||
885 | |||
886 | t = PyTuple_New(MAX_FIELDS); | ||
887 | if (!t) | ||
888 | Py_FatalError("couldn't create Python tuple"); | ||
889 | |||
890 | get_handler_name(handler_name, sizeof(handler_name), | ||
891 | counter); | ||
892 | |||
893 | handler = get_handler(handler_name); | ||
894 | if (!handler) { | ||
895 | pr_debug("can't find python handler %s\n", handler_name); | ||
896 | return; | ||
897 | } | ||
898 | |||
899 | PyTuple_SetItem(t, n++, PyInt_FromLong(cpu)); | ||
900 | PyTuple_SetItem(t, n++, PyInt_FromLong(thread)); | ||
901 | |||
902 | tuple_set_u64(t, n++, tstamp); | ||
903 | tuple_set_u64(t, n++, count->val); | ||
904 | tuple_set_u64(t, n++, count->ena); | ||
905 | tuple_set_u64(t, n++, count->run); | ||
906 | |||
907 | if (_PyTuple_Resize(&t, n) == -1) | ||
908 | Py_FatalError("error resizing Python tuple"); | ||
909 | |||
910 | call_object(handler, t, handler_name); | ||
911 | |||
912 | Py_DECREF(t); | ||
913 | } | ||
914 | |||
915 | static void python_process_stat(struct perf_stat_config *config, | ||
916 | struct perf_evsel *counter, u64 tstamp) | ||
917 | { | ||
918 | struct thread_map *threads = counter->threads; | ||
919 | struct cpu_map *cpus = counter->cpus; | ||
920 | int cpu, thread; | ||
921 | |||
922 | if (config->aggr_mode == AGGR_GLOBAL) { | ||
923 | process_stat(counter, -1, -1, tstamp, | ||
924 | &counter->counts->aggr); | ||
925 | return; | ||
926 | } | ||
927 | |||
928 | for (thread = 0; thread < threads->nr; thread++) { | ||
929 | for (cpu = 0; cpu < cpus->nr; cpu++) { | ||
930 | process_stat(counter, cpus->map[cpu], | ||
931 | thread_map__pid(threads, thread), tstamp, | ||
932 | perf_counts(counter->counts, cpu, thread)); | ||
933 | } | ||
934 | } | ||
935 | } | ||
936 | |||
937 | static void python_process_stat_interval(u64 tstamp) | ||
938 | { | ||
939 | PyObject *handler, *t; | ||
940 | static const char handler_name[] = "stat__interval"; | ||
941 | int n = 0; | ||
942 | |||
943 | t = PyTuple_New(MAX_FIELDS); | ||
944 | if (!t) | ||
945 | Py_FatalError("couldn't create Python tuple"); | ||
946 | |||
947 | handler = get_handler(handler_name); | ||
948 | if (!handler) { | ||
949 | pr_debug("can't find python handler %s\n", handler_name); | ||
950 | return; | ||
951 | } | ||
952 | |||
953 | tuple_set_u64(t, n++, tstamp); | ||
954 | |||
955 | if (_PyTuple_Resize(&t, n) == -1) | ||
956 | Py_FatalError("error resizing Python tuple"); | ||
957 | |||
958 | call_object(handler, t, handler_name); | ||
959 | |||
960 | Py_DECREF(t); | ||
961 | } | ||
962 | |||
862 | static int run_start_sub(void) | 963 | static int run_start_sub(void) |
863 | { | 964 | { |
864 | main_module = PyImport_AddModule("__main__"); | 965 | main_module = PyImport_AddModule("__main__"); |
@@ -1201,10 +1302,12 @@ static int python_generate_script(struct pevent *pevent, const char *outfile) | |||
1201 | } | 1302 | } |
1202 | 1303 | ||
1203 | struct scripting_ops python_scripting_ops = { | 1304 | struct scripting_ops python_scripting_ops = { |
1204 | .name = "Python", | 1305 | .name = "Python", |
1205 | .start_script = python_start_script, | 1306 | .start_script = python_start_script, |
1206 | .flush_script = python_flush_script, | 1307 | .flush_script = python_flush_script, |
1207 | .stop_script = python_stop_script, | 1308 | .stop_script = python_stop_script, |
1208 | .process_event = python_process_event, | 1309 | .process_event = python_process_event, |
1209 | .generate_script = python_generate_script, | 1310 | .process_stat = python_process_stat, |
1311 | .process_stat_interval = python_process_stat_interval, | ||
1312 | .generate_script = python_generate_script, | ||
1210 | }; | 1313 | }; |