History

perf tools: Add Python 3 support

Added Python 3 support while keeping Python 2.7 compatibility. Committer notes: This doesn't make it to auto detect python 3, one has to explicitely ask it to build with python 3 devel files, here are the instructions provided by Jaroslav: --- $ cp -a tools/perf tools/python3-perf $ make V=1 prefix=/usr -C tools/perf PYTHON=/usr/bin/python2 all $ make V=1 prefix=/usr -C tools/python3-perf PYTHON=/usr/bin/python3 all $ make V=1 prefix=/usr -C tools/python3-perf PYTHON=/usr/bin/python3 DESTDIR=%{buildroot} install-python_ext $ make V=1 prefix=/usr -C tools/perf PYTHON=/usr/bin/python2 DESTDIR=%{buildroot} install-python_ext --- We need to make this automatic, just like the existing tests for checking if the python2 devel files are in place, allowing the build with python3 if available, fallbacking to python2 and then just disabling it if none are available. So, using the PYTHON variable to build it using O= we get: Before this patch: $ rpm -q python3 python3-devel python3-3.6.4-7.fc27.x86_64 python3-devel-3.6.4-7.fc27.x86_64 $ rm -rf /tmp/build/perf/ ; mkdir -p /tmp/build/perf ; make O=/tmp/build/perf PYTHON=/usr/bin/python3 -C tools/perf install-bin make: Entering directory '/home/acme/git/linux/tools/perf' <SNIP> Makefile.config:670: Python 3 is not yet supported; please set Makefile.config:671: PYTHON and/or PYTHON_CONFIG appropriately. Makefile.config:672: If you also have Python 2 installed, then Makefile.config:673: try something like: Makefile.config:674: Makefile.config:675: make PYTHON=python2 Makefile.config:676: Makefile.config:677: Otherwise, disable Python support entirely: Makefile.config:678: Makefile.config:679: make NO_LIBPYTHON=1 Makefile.config:680: Makefile.config:681: *** . Stop. make[1]: *** [Makefile.perf:212: sub-make] Error 2 make: *** [Makefile:110: install-bin] Error 2 make: Leaving directory '/home/acme/git/linux/tools/perf' $ After: $ make O=/tmp/build/perf PYTHON=python3 -C tools/perf install-bin $ ldd ~/bin/perf | grep python libpython3.6m.so.1.0 => /lib64/libpython3.6m.so.1.0 (0x00007f58a31e8000) $ rpm -qf /lib64/libpython3.6m.so.1.0 python3-libs-3.6.4-7.fc27.x86_64 $ Now verify that when using the binding the right ELF file is loaded, using perf trace: $ perf trace -e open* perf test python 0.051 ( 0.016 ms): perf/3927 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC ) = 3 <SNIP> 18: 'import perf' in python : 8.849 ( 0.013 ms): sh/3929 openat(dfd: CWD, filename: /etc/ld.so.cache, flags: CLOEXEC ) = 3 <SNIP> 25.572 ( 0.008 ms): python3/3931 openat(dfd: CWD, filename: /tmp/build/perf/python/perf.cpython-36m-x86_64-linux-gnu.so, flags: CLOEXEC) = 3 <SNIP> Ok <SNIP> $ And using tools/perf/python/twatch.py, to show PERF_RECORD_ metaevents: $ python3 tools/perf/python/twatch.py cpu: 3, pid: 16060, tid: 16060 { type: fork, pid: 5207, ppid: 16060, tid: 5207, ptid: 16060, time: 10798513015459} cpu: 3, pid: 16060, tid: 16060 { type: fork, pid: 5208, ppid: 16060, tid: 5208, ptid: 16060, time: 10798513562503} cpu: 0, pid: 5208, tid: 5208 { type: comm, pid: 5208, tid: 5208, comm: grep } cpu: 2, pid: 5207, tid: 5207 { type: comm, pid: 5207, tid: 5207, comm: ps } cpu: 2, pid: 5207, tid: 5207 { type: exit, pid: 5207, ppid: 5207, tid: 5207, ptid: 5207, time: 10798551337484} cpu: 3, pid: 5208, tid: 5208 { type: exit, pid: 5208, ppid: 5208, tid: 5208, ptid: 5208, time: 10798551292153} cpu: 3, pid: 601, tid: 601 { type: fork, pid: 5209, ppid: 601, tid: 5209, ptid: 601, time: 10801779977324} ^CTraceback (most recent call last): File "tools/perf/python/twatch.py", line 68, in <module> main() File "tools/perf/python/twatch.py", line 40, in main evlist.poll(timeout = -1) KeyboardInterrupt $ # ps ax|grep twatch 5197 pts/8 S+ 0:00 python3 tools/perf/python/twatch.py # ls -la /proc/5197/smaps -r--r--r--. 1 acme acme 0 Feb 19 13:14 /proc/5197/smaps # grep python /proc/5197/smaps 558111307000-558111309000 r-xp 00000000 fd:00 3151710 /usr/bin/python3.6 558111508000-558111509000 r--p 00001000 fd:00 3151710 /usr/bin/python3.6 558111509000-55811150a000 rw-p 00002000 fd:00 3151710 /usr/bin/python3.6 7ffad6fc1000-7ffad7008000 r-xp 00000000 00:2d 220196 /tmp/build/perf/python/perf.cpython-36m-x86_64-linux-gnu.so 7ffad7008000-7ffad7207000 ---p 00047000 00:2d 220196 /tmp/build/perf/python/perf.cpython-36m-x86_64-linux-gnu.so 7ffad7207000-7ffad7208000 r--p 00046000 00:2d 220196 /tmp/build/perf/python/perf.cpython-36m-x86_64-linux-gnu.so 7ffad7208000-7ffad7215000 rw-p 00047000 00:2d 220196 /tmp/build/perf/python/perf.cpython-36m-x86_64-linux-gnu.so 7ffadea77000-7ffaded3d000 r-xp 00000000 fd:00 3151795 /usr/lib64/libpython3.6m.so.1.0 7ffaded3d000-7ffadef3c000 ---p 002c6000 fd:00 3151795 /usr/lib64/libpython3.6m.so.1.0 7ffadef3c000-7ffadef42000 r--p 002c5000 fd:00 3151795 /usr/lib64/libpython3.6m.so.1.0 7ffadef42000-7ffadefa5000 rw-p 002cb000 fd:00 3151795 /usr/lib64/libpython3.6m.so.1.0 # And with this patch, but building normally, without specifying the PYTHON=python3 part, which will make it use python2 if its devel files are available, like in this test: $ make O=/tmp/build/perf -C tools/perf install-bin $ ldd ~/bin/perf | grep python libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0 (0x00007f6a44410000) $ ldd /tmp/build/perf/python_ext_build/lib/perf.so | grep python libpython2.7.so.1.0 => /lib64/libpython2.7.so.1.0 (0x00007fed28a2c000) $ [acme@jouet perf]$ tools/perf/python/twatch.py cpu: 0, pid: 2817, tid: 2817 { type: fork, pid: 2817, ppid: 2817, tid: 8910, ptid: 2817, time: 11126454335306} cpu: 0, pid: 2817, tid: 2817 { type: comm, pid: 2817, tid: 8910, comm: worker } $ ps ax | grep twatch.py 8909 pts/8 S+ 0:00 /usr/bin/python tools/perf/python/twatch.py $ grep python /proc/8909/smaps 5579de658000-5579de659000 r-xp 00000000 fd:00 3156044 /usr/bin/python2.7 5579de858000-5579de859000 r--p 00000000 fd:00 3156044 /usr/bin/python2.7 5579de859000-5579de85a000 rw-p 00001000 fd:00 3156044 /usr/bin/python2.7 7f0de01f7000-7f0de023e000 r-xp 00000000 00:2d 230695 /tmp/build/perf/python/perf.so 7f0de023e000-7f0de043d000 ---p 00047000 00:2d 230695 /tmp/build/perf/python/perf.so 7f0de043d000-7f0de043e000 r--p 00046000 00:2d 230695 /tmp/build/perf/python/perf.so 7f0de043e000-7f0de044b000 rw-p 00047000 00:2d 230695 /tmp/build/perf/python/perf.so 7f0de6f0f000-7f0de6f13000 r-xp 00000000 fd:00 134975 /usr/lib64/python2.7/lib-dynload/_localemodule.so 7f0de6f13000-7f0de7113000 ---p 00004000 fd:00 134975 /usr/lib64/python2.7/lib-dynload/_localemodule.so 7f0de7113000-7f0de7114000 r--p 00004000 fd:00 134975 /usr/lib64/python2.7/lib-dynload/_localemodule.so 7f0de7114000-7f0de7115000 rw-p 00005000 fd:00 134975 /usr/lib64/python2.7/lib-dynload/_localemodule.so 7f0de7e73000-7f0de8052000 r-xp 00000000 fd:00 3173292 /usr/lib64/libpython2.7.so.1.0 7f0de8052000-7f0de8251000 ---p 001df000 fd:00 3173292 /usr/lib64/libpython2.7.so.1.0 7f0de8251000-7f0de8255000 r--p 001de000 fd:00 3173292 /usr/lib64/libpython2.7.so.1.0 7f0de8255000-7f0de8291000 rw-p 001e2000 fd:00 3173292 /usr/lib64/libpython2.7.so.1.0 $

Jaroslav Škarvada committed 8 years ago

Commit 66dfdff1 parent d2ed5d26 files · +221 −88Browse files

Unified · Split

6 files
  1. tools/perf/Makefile.config +4 −19
  2. tools/perf/Makefile.perf +2 −2
  3. tools/perf/scripts/python/Perf-Trace-Util/Context.c +31 −3
  4. tools/perf/util/python.c +77 −18
  5. tools/perf/util/scripting-engines/trace-event-python.c +104 −43
  6. tools/perf/util/setup.py +3 −3
tools/perf/Makefile.config+4−19
@@ -668,25 +668,10 @@ else · 667 unmodified lines
668668 ifneq ($(feature-libpython), 1)
669669 $(call disable-python,No 'Python.h' (for Python 2.x support) was found: disables Python support - please install python-devel/python-dev)
670670 else
671− ifneq ($(feature-libpython-version), 1)
672− $(warning Python 3 is not yet supported; please set)
673− $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
674− $(warning If you also have Python 2 installed, then)
675− $(warning try something like:)
676− $(warning $(and ,))
677− $(warning $(and ,) make PYTHON=python2)
678− $(warning $(and ,))
679− $(warning Otherwise, disable Python support entirely:)
680− $(warning $(and ,))
681− $(warning $(and ,) make NO_LIBPYTHON=1)
682− $(warning $(and ,))
683− $(error $(and ,))
684− else
685− LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
686− EXTLIBS += $(PYTHON_EMBED_LIBADD)
687− LANG_BINDINGS += $(obj-perf)python/perf.so
688− $(call detected,CONFIG_LIBPYTHON)
689− endif
671+ LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
672+ EXTLIBS += $(PYTHON_EMBED_LIBADD)
673+ LANG_BINDINGS += $(obj-perf)python/perf.so
674+ $(call detected,CONFIG_LIBPYTHON)
690675 endif
691676 endif
692677 endif
tools/perf/Makefile.perf+2−2
@@ -302,7 +302,7 @@ PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/ · 301 unmodified lines
302302 PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
303303 export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
304304
305−python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
305+python-clean := $(call QUIET_CLEAN, python) $(RM) -r $(PYTHON_EXTBUILD) $(OUTPUT)python/perf*.so
306306
307307 PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
308308 PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBAPI)
@@ -479,7 +479,7 @@ $(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) $(LIBTRACEEVENT_D · 170 unmodified lines
479479 $(PYTHON_WORD) util/setup.py \
480480 --quiet build_ext; \
481481 mkdir -p $(OUTPUT)python && \
482− cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
482+ cp $(PYTHON_EXTBUILD_LIB)perf*.so $(OUTPUT)python/
483483
484484 please_set_SHELL_PATH_to_a_more_modern_shell:
485485 $(Q)$$(:)
tools/perf/scripts/python/Perf-Trace-Util/Context.c+31−3
@@ -23,7 +23,17 @@ · 22 unmodified lines
2323 #include "../../../perf.h"
2424 #include "../../../util/trace-event.h"
2525
26+#if PY_MAJOR_VERSION < 3
27+#define _PyCapsule_GetPointer(arg1, arg2) \
28+ PyCObject_AsVoidPtr(arg1)
29+
2630 PyMODINIT_FUNC initperf_trace_context(void);
31+#else
32+#define _PyCapsule_GetPointer(arg1, arg2) \
33+ PyCapsule_GetPointer((arg1), (arg2))
34+
35+PyMODINIT_FUNC PyInit_perf_trace_context(void);
36+#endif
2737
2838 static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args)
2939 {
@@ -34,7 +44,7 @@ static PyObject *perf_trace_context_common_pc(PyObject *obj, PyObject *args) · 4 unmodified lines
3444 if (!PyArg_ParseTuple(args, "O", &context))
3545 return NULL;
3646
37− scripting_context = PyCObject_AsVoidPtr(context);
47+ scripting_context = _PyCapsule_GetPointer(context, NULL);
3848 retval = common_pc(scripting_context);
3949
4050 return Py_BuildValue("i", retval);
@@ -50,7 +60,7 @@ static PyObject *perf_trace_context_common_flags(PyObject *obj, · 9 unmodified lines
5060 if (!PyArg_ParseTuple(args, "O", &context))
5161 return NULL;
5262
53− scripting_context = PyCObject_AsVoidPtr(context);
63+ scripting_context = _PyCapsule_GetPointer(context, NULL);
5464 retval = common_flags(scripting_context);
5565
5666 return Py_BuildValue("i", retval);
@@ -66,7 +76,7 @@ static PyObject *perf_trace_context_common_lock_depth(PyObject *obj, · 9 unmodified lines
6676 if (!PyArg_ParseTuple(args, "O", &context))
6777 return NULL;
6878
69− scripting_context = PyCObject_AsVoidPtr(context);
79+ scripting_context = _PyCapsule_GetPointer(context, NULL);
7080 retval = common_lock_depth(scripting_context);
7181
7282 return Py_BuildValue("i", retval);
@@ -82,7 +92,25 @@ static PyMethodDef ContextMethods[] = { · 9 unmodified lines
8292 { NULL, NULL, 0, NULL}
8393 };
8494
95+#if PY_MAJOR_VERSION < 3
8596 PyMODINIT_FUNC initperf_trace_context(void)
8697 {
8798 (void) Py_InitModule("perf_trace_context", ContextMethods);
8899 }
100+#else
101+PyMODINIT_FUNC PyInit_perf_trace_context(void)
102+{
103+ static struct PyModuleDef moduledef = {
104+ PyModuleDef_HEAD_INIT,
105+ "perf_trace_context", /* m_name */
106+ "", /* m_doc */
107+ -1, /* m_size */
108+ ContextMethods, /* m_methods */
109+ NULL, /* m_reload */
110+ NULL, /* m_traverse */
111+ NULL, /* m_clear */
112+ NULL, /* m_free */
113+ };
114+ return PyModule_Create(&moduledef);
115+}
116+#endif
tools/perf/util/python.c+77−18
@@ -12,6 +12,30 @@ · 11 unmodified lines
1212 #include "print_binary.h"
1313 #include "thread_map.h"
1414
15+#if PY_MAJOR_VERSION < 3
16+#define _PyUnicode_FromString(arg) \
17+ PyString_FromString(arg)
18+#define _PyUnicode_AsString(arg) \
19+ PyString_AsString(arg)
20+#define _PyUnicode_FromFormat(...) \
21+ PyString_FromFormat(__VA_ARGS__)
22+#define _PyLong_FromLong(arg) \
23+ PyInt_FromLong(arg)
24+
25+#else
26+
27+#define _PyUnicode_FromString(arg) \
28+ PyUnicode_FromString(arg)
29+#define _PyUnicode_FromFormat(...) \
30+ PyUnicode_FromFormat(__VA_ARGS__)
31+#define _PyLong_FromLong(arg) \
32+ PyLong_FromLong(arg)
33+#endif
34+
35+#ifndef Py_TYPE
36+#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
37+#endif
38+
1539 /*
1640 * Provide these two so that we don't have to link against callchain.c and
1741 * start dragging hist.c, etc.
@@ -49,7 +73,11 @@ int eprintf(int level, int var, const char *fmt, ...) · 31 unmodified lines
4973 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
5074 #endif
5175
76+#if PY_MAJOR_VERSION < 3
5277 PyMODINIT_FUNC initperf(void);
78+#else
79+PyMODINIT_FUNC PyInit_perf(void);
80+#endif
5381
5482 #define member_def(type, member, ptype, help) \
5583 { #member, ptype, \
@@ -107,7 +135,7 @@ static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) · 51 unmodified lines
107135 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
108136 ret = PyErr_NoMemory();
109137 } else {
110− ret = PyString_FromString(s);
138+ ret = _PyUnicode_FromString(s);
111139 free(s);
112140 }
113141 return ret;
@@ -138,7 +166,7 @@ static PyMemberDef pyrf_task_event__members[] = { · 24 unmodified lines
138166
139167 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
140168 {
141− return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
169+ return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
142170 "ptid: %u, time: %" PRIu64 "}",
143171 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
144172 pevent->event.fork.pid,
@@ -171,7 +199,7 @@ static PyMemberDef pyrf_comm_event__members[] = { · 26 unmodified lines
171199
172200 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
173201 {
174− return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
202+ return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
175203 pevent->event.comm.pid,
176204 pevent->event.comm.tid,
177205 pevent->event.comm.comm);
@@ -202,7 +230,7 @@ static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) · 24 unmodified lines
202230 {
203231 struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
204232
205− return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
233+ return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
206234 ", stream_id: %" PRIu64 " }",
207235 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
208236 te->time, te->id, te->stream_id);
@@ -237,7 +265,7 @@ static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) · 28 unmodified lines
237265 pevent->event.lost.id, pevent->event.lost.lost) < 0) {
238266 ret = PyErr_NoMemory();
239267 } else {
240− ret = PyString_FromString(s);
268+ ret = _PyUnicode_FromString(s);
241269 free(s);
242270 }
243271 return ret;
@@ -264,7 +292,7 @@ static PyMemberDef pyrf_read_event__members[] = { · 20 unmodified lines
264292
265293 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
266294 {
267− return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
295+ return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
268296 pevent->event.read.pid,
269297 pevent->event.read.tid);
270298 /*
@@ -299,7 +327,7 @@ static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) · 28 unmodified lines
299327 if (asprintf(&s, "{ type: sample }") < 0) {
300328 ret = PyErr_NoMemory();
301329 } else {
302− ret = PyString_FromString(s);
330+ ret = _PyUnicode_FromString(s);
303331 free(s);
304332 }
305333 return ret;
@@ -330,7 +358,7 @@ tracepoint_field(struct pyrf_event *pe, struct format_field *field) · 24 unmodified lines
330358 }
331359 if (field->flags & FIELD_IS_STRING &&
332360 is_printable_array(data + offset, len)) {
333− ret = PyString_FromString((char *)data + offset);
361+ ret = _PyUnicode_FromString((char *)data + offset);
334362 } else {
335363 ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
336364 field->flags &= ~FIELD_IS_STRING;
@@ -352,7 +380,7 @@ tracepoint_field(struct pyrf_event *pe, struct format_field *field) · 15 unmodified lines
352380 static PyObject*
353381 get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
354382 {
355− const char *str = PyString_AsString(PyObject_Str(attr_name));
383+ const char *str = _PyUnicode_AsString(PyObject_Str(attr_name));
356384 struct perf_evsel *evsel = pevent->evsel;
357385 struct format_field *field;
358386
@@ -416,7 +444,7 @@ static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent) · 57 unmodified lines
416444 !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
417445 ret = PyErr_NoMemory();
418446 } else {
419− ret = PyString_FromString(s);
447+ ret = _PyUnicode_FromString(s);
420448 free(s);
421449 }
422450 return ret;
@@ -528,7 +556,7 @@ static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, · 105 unmodified lines
528556 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
529557 {
530558 cpu_map__put(pcpus->cpus);
531− pcpus->ob_type->tp_free((PyObject*)pcpus);
559+ Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
532560 }
533561
534562 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
@@ -597,7 +625,7 @@ static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, · 62 unmodified lines
597625 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
598626 {
599627 thread_map__put(pthreads->threads);
600− pthreads->ob_type->tp_free((PyObject*)pthreads);
628+ Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
601629 }
602630
603631 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
@@ -759,7 +787,7 @@ static int pyrf_evsel__init(struct pyrf_evsel *pevsel, · 155 unmodified lines
759787 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
760788 {
761789 perf_evsel__exit(&pevsel->evsel);
762− pevsel->ob_type->tp_free((PyObject*)pevsel);
790+ Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
763791 }
764792
765793 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
@@ -850,7 +878,7 @@ static int pyrf_evlist__init(struct pyrf_evlist *pevlist, · 84 unmodified lines
850878 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
851879 {
852880 perf_evlist__exit(&pevlist->evlist);
853− pevlist->ob_type->tp_free((PyObject*)pevlist);
881+ Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
854882 }
855883
856884 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
@@ -902,12 +930,16 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, · 45 unmodified lines
902930
903931 for (i = 0; i < evlist->pollfd.nr; ++i) {
904932 PyObject *file;
933+#if PY_MAJOR_VERSION < 3
905934 FILE *fp = fdopen(evlist->pollfd.entries[i].fd, "r");
906935
907936 if (fp == NULL)
908937 goto free_list;
909938
910939 file = PyFile_FromFile(fp, "perf", "r", NULL);
940+#else
941+ file = PyFile_FromFd(evlist->pollfd.entries[i].fd, "perf", "r", -1, NULL, NULL, NULL, 1);
942+#endif
911943 if (file == NULL)
912944 goto free_list;
913945
@@ -1194,9 +1226,9 @@ static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, · 280 unmodified lines
11941226
11951227 tp_format = trace_event__tp_format(sys, name);
11961228 if (IS_ERR(tp_format))
1197− return PyInt_FromLong(-1);
1229+ return _PyLong_FromLong(-1);
11981230
1199− return PyInt_FromLong(tp_format->id);
1231+ return _PyLong_FromLong(tp_format->id);
12001232 }
12011233
12021234 static PyMethodDef perf__methods[] = {
@@ -1209,11 +1241,31 @@ static PyMethodDef perf__methods[] = { · 6 unmodified lines
12091241 { .ml_name = NULL, }
12101242 };
12111243
1244+#if PY_MAJOR_VERSION < 3
12121245 PyMODINIT_FUNC initperf(void)
1246+#else
1247+PyMODINIT_FUNC PyInit_perf(void)
1248+#endif
12131249 {
12141250 PyObject *obj;
12151251 int i;
1216− PyObject *dict, *module = Py_InitModule("perf", perf__methods);
1252+ PyObject *dict;
1253+#if PY_MAJOR_VERSION < 3
1254+ PyObject *module = Py_InitModule("perf", perf__methods);
1255+#else
1256+ static struct PyModuleDef moduledef = {
1257+ PyModuleDef_HEAD_INIT,
1258+ "perf", /* m_name */
1259+ "", /* m_doc */
1260+ -1, /* m_size */
1261+ perf__methods, /* m_methods */
1262+ NULL, /* m_reload */
1263+ NULL, /* m_traverse */
1264+ NULL, /* m_clear */
1265+ NULL, /* m_free */
1266+ };
1267+ PyObject *module = PyModule_Create(&moduledef);
1268+#endif
12171269
12181270 if (module == NULL ||
12191271 pyrf_event__setup_types() < 0 ||
@@ -1221,7 +1273,11 @@ PyMODINIT_FUNC initperf(void) · 1 unmodified line
12211273 pyrf_evsel__setup_types() < 0 ||
12221274 pyrf_thread_map__setup_types() < 0 ||
12231275 pyrf_cpu_map__setup_types() < 0)
1276+#if PY_MAJOR_VERSION < 3
12241277 return;
1278+#else
1279+ return module;
1280+#endif
12251281
12261282 /* The page_size is placed in util object. */
12271283 page_size = sysconf(_SC_PAGE_SIZE);
@@ -1270,7 +1326,7 @@ PyMODINIT_FUNC initperf(void) · 42 unmodified lines
12701326 goto error;
12711327
12721328 for (i = 0; perf__constants[i].name != NULL; i++) {
1273− obj = PyInt_FromLong(perf__constants[i].value);
1329+ obj = _PyLong_FromLong(perf__constants[i].value);
12741330 if (obj == NULL)
12751331 goto error;
12761332 PyDict_SetItemString(dict, perf__constants[i].name, obj);
@@ -1280,6 +1336,9 @@ PyMODINIT_FUNC initperf(void) · 3 unmodified lines
12801336 error:
12811337 if (PyErr_Occurred())
12821338 PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1339+#if PY_MAJOR_VERSION >= 3
1340+ return module;
1341+#endif
12831342 }
12841343
12851344 /*
tools/perf/util/scripting-engines/trace-event-python.c+104−43
@@ -49,7 +49,37 @@ · 48 unmodified lines
4949 #include "print_binary.h"
5050 #include "stat.h"
5151
52+#if PY_MAJOR_VERSION < 3
53+#define _PyUnicode_FromString(arg) \
54+ PyString_FromString(arg)
55+#define _PyUnicode_FromStringAndSize(arg1, arg2) \
56+ PyString_FromStringAndSize((arg1), (arg2))
57+#define _PyBytes_FromStringAndSize(arg1, arg2) \
58+ PyString_FromStringAndSize((arg1), (arg2))
59+#define _PyLong_FromLong(arg) \
60+ PyInt_FromLong(arg)
61+#define _PyLong_AsLong(arg) \
62+ PyInt_AsLong(arg)
63+#define _PyCapsule_New(arg1, arg2, arg3) \
64+ PyCObject_FromVoidPtr((arg1), (arg2))
65+
5266 PyMODINIT_FUNC initperf_trace_context(void);
67+#else
68+#define _PyUnicode_FromString(arg) \
69+ PyUnicode_FromString(arg)
70+#define _PyUnicode_FromStringAndSize(arg1, arg2) \
71+ PyUnicode_FromStringAndSize((arg1), (arg2))
72+#define _PyBytes_FromStringAndSize(arg1, arg2) \
73+ PyBytes_FromStringAndSize((arg1), (arg2))
74+#define _PyLong_FromLong(arg) \
75+ PyLong_FromLong(arg)
76+#define _PyLong_AsLong(arg) \
77+ PyLong_AsLong(arg)
78+#define _PyCapsule_New(arg1, arg2, arg3) \
79+ PyCapsule_New((arg1), (arg2), (arg3))
80+
81+PyMODINIT_FUNC PyInit_perf_trace_context(void);
82+#endif
5383
5484 #define TRACE_EVENT_TYPE_MAX \
5585 ((1 << (sizeof(unsigned short) * 8)) - 1)
@@ -135,7 +165,7 @@ static int get_argument_count(PyObject *handler) · 79 unmodified lines
135165 PyObject *arg_count_obj = PyObject_GetAttrString(code_obj,
136166 "co_argcount");
137167 if (arg_count_obj) {
138− arg_count = (int) PyInt_AsLong(arg_count_obj);
168+ arg_count = (int) _PyLong_AsLong(arg_count_obj);
139169 Py_DECREF(arg_count_obj);
140170 }
141171 Py_DECREF(code_obj);
@@ -182,10 +212,10 @@ static void define_value(enum print_arg_type field_type, · 40 unmodified lines
182212
183213 value = eval_flag(field_value);
184214
185− PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
186− PyTuple_SetItem(t, n++, PyString_FromString(field_name));
187− PyTuple_SetItem(t, n++, PyInt_FromLong(value));
188− PyTuple_SetItem(t, n++, PyString_FromString(field_str));
215+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name));
216+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name));
217+ PyTuple_SetItem(t, n++, _PyLong_FromLong(value));
218+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_str));
189219
190220 try_call_object(handler_name, t);
191221
@@ -223,10 +253,10 @@ static void define_field(enum print_arg_type field_type, · 31 unmodified lines
223253 if (!t)
224254 Py_FatalError("couldn't create Python tuple");
225255
226− PyTuple_SetItem(t, n++, PyString_FromString(ev_name));
227− PyTuple_SetItem(t, n++, PyString_FromString(field_name));
256+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(ev_name));
257+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(field_name));
228258 if (field_type == PRINT_FLAGS)
229− PyTuple_SetItem(t, n++, PyString_FromString(delim));
259+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(delim));
230260
231261 try_call_object(handler_name, t);
232262
@@ -325,12 +355,12 @@ static PyObject *get_field_numeric_entry(struct event_format *event, · 92 unmodified lines
325355 if (field->flags & FIELD_IS_SIGNED) {
326356 if ((long long)val >= LONG_MIN &&
327357 (long long)val <= LONG_MAX)
328− obj = PyInt_FromLong(val);
358+ obj = _PyLong_FromLong(val);
329359 else
330360 obj = PyLong_FromLongLong(val);
331361 } else {
332362 if (val <= LONG_MAX)
333− obj = PyInt_FromLong(val);
363+ obj = _PyLong_FromLong(val);
334364 else
335365 obj = PyLong_FromUnsignedLongLong(val);
336366 }
@@ -389,9 +419,9 @@ static PyObject *python_process_callchain(struct perf_sample *sample, · 52 unmodified lines
389419 pydict_set_item_string_decref(pysym, "end",
390420 PyLong_FromUnsignedLongLong(node->sym->end));
391421 pydict_set_item_string_decref(pysym, "binding",
392− PyInt_FromLong(node->sym->binding));
422+ _PyLong_FromLong(node->sym->binding));
393423 pydict_set_item_string_decref(pysym, "name",
394− PyString_FromStringAndSize(node->sym->name,
424+ _PyUnicode_FromStringAndSize(node->sym->name,
395425 node->sym->namelen));
396426 pydict_set_item_string_decref(pyelem, "sym", pysym);
397427 }
@@ -406,7 +436,7 @@ static PyObject *python_process_callchain(struct perf_sample *sample, · 8 unmodified lines
406436 dsoname = map->dso->name;
407437 }
408438 pydict_set_item_string_decref(pyelem, "dso",
409− PyString_FromString(dsoname));
439+ _PyUnicode_FromString(dsoname));
410440 }
411441
412442 callchain_cursor_advance(&callchain_cursor);
@@ -483,16 +513,16 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, · 70 unmodified lines
483513 if (!dict_sample)
484514 Py_FatalError("couldn't create Python dictionary");
485515
486− pydict_set_item_string_decref(dict, "ev_name", PyString_FromString(perf_evsel__name(evsel)));
487− pydict_set_item_string_decref(dict, "attr", PyString_FromStringAndSize(
516+ pydict_set_item_string_decref(dict, "ev_name", _PyUnicode_FromString(perf_evsel__name(evsel)));
517+ pydict_set_item_string_decref(dict, "attr", _PyUnicode_FromStringAndSize(
488518 (const char *)&evsel->attr, sizeof(evsel->attr)));
489519
490520 pydict_set_item_string_decref(dict_sample, "pid",
491− PyInt_FromLong(sample->pid));
521+ _PyLong_FromLong(sample->pid));
492522 pydict_set_item_string_decref(dict_sample, "tid",
493− PyInt_FromLong(sample->tid));
523+ _PyLong_FromLong(sample->tid));
494524 pydict_set_item_string_decref(dict_sample, "cpu",
495− PyInt_FromLong(sample->cpu));
525+ _PyLong_FromLong(sample->cpu));
496526 pydict_set_item_string_decref(dict_sample, "ip",
497527 PyLong_FromUnsignedLongLong(sample->ip));
498528 pydict_set_item_string_decref(dict_sample, "time",
@@ -504,17 +534,17 @@ static PyObject *get_perf_sample_dict(struct perf_sample *sample, · 5 unmodified lines
504534 set_sample_read_in_dict(dict_sample, sample, evsel);
505535 pydict_set_item_string_decref(dict, "sample", dict_sample);
506536
507− pydict_set_item_string_decref(dict, "raw_buf", PyString_FromStringAndSize(
537+ pydict_set_item_string_decref(dict, "raw_buf", _PyBytes_FromStringAndSize(
508538 (const char *)sample->raw_data, sample->raw_size));
509539 pydict_set_item_string_decref(dict, "comm",
510− PyString_FromString(thread__comm_str(al->thread)));
540+ _PyUnicode_FromString(thread__comm_str(al->thread)));
511541 if (al->map) {
512542 pydict_set_item_string_decref(dict, "dso",
513− PyString_FromString(al->map->dso->name));
543+ _PyUnicode_FromString(al->map->dso->name));
514544 }
515545 if (al->sym) {
516546 pydict_set_item_string_decref(dict, "symbol",
517− PyString_FromString(al->sym->name));
547+ _PyUnicode_FromString(al->sym->name));
518548 }
519549
520550 pydict_set_item_string_decref(dict, "callchain", callchain);
@@ -574,9 +604,9 @@ static void python_process_tracepoint(struct perf_sample *sample, · 53 unmodified lines
574604 scripting_context->event_data = data;
575605 scripting_context->pevent = evsel->tp_format->pevent;
576606
577− context = PyCObject_FromVoidPtr(scripting_context, NULL);
607+ context = _PyCapsule_New(scripting_context, NULL, NULL);
578608
579− PyTuple_SetItem(t, n++, PyString_FromString(handler_name));
609+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(handler_name));
580610 PyTuple_SetItem(t, n++, context);
581611
582612 /* ip unwinding */
@@ -585,18 +615,18 @@ static void python_process_tracepoint(struct perf_sample *sample, · 2 unmodified lines
585615 Py_INCREF(callchain);
586616
587617 if (!dict) {
588− PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
589− PyTuple_SetItem(t, n++, PyInt_FromLong(s));
590− PyTuple_SetItem(t, n++, PyInt_FromLong(ns));
591− PyTuple_SetItem(t, n++, PyInt_FromLong(pid));
592− PyTuple_SetItem(t, n++, PyString_FromString(comm));
618+ PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu));
619+ PyTuple_SetItem(t, n++, _PyLong_FromLong(s));
620+ PyTuple_SetItem(t, n++, _PyLong_FromLong(ns));
621+ PyTuple_SetItem(t, n++, _PyLong_FromLong(pid));
622+ PyTuple_SetItem(t, n++, _PyUnicode_FromString(comm));
593623 PyTuple_SetItem(t, n++, callchain);
594624 } else {
595− pydict_set_item_string_decref(dict, "common_cpu", PyInt_FromLong(cpu));
596− pydict_set_item_string_decref(dict, "common_s", PyInt_FromLong(s));
597− pydict_set_item_string_decref(dict, "common_ns", PyInt_FromLong(ns));
598− pydict_set_item_string_decref(dict, "common_pid", PyInt_FromLong(pid));
599− pydict_set_item_string_decref(dict, "common_comm", PyString_FromString(comm));
625+ pydict_set_item_string_decref(dict, "common_cpu", _PyLong_FromLong(cpu));
626+ pydict_set_item_string_decref(dict, "common_s", _PyLong_FromLong(s));
627+ pydict_set_item_string_decref(dict, "common_ns", _PyLong_FromLong(ns));
628+ pydict_set_item_string_decref(dict, "common_pid", _PyLong_FromLong(pid));
629+ pydict_set_item_string_decref(dict, "common_comm", _PyUnicode_FromString(comm));
600630 pydict_set_item_string_decref(dict, "common_callchain", callchain);
601631 }
602632 for (field = event->format.fields; field; field = field->next) {
@@ -615,7 +645,7 @@ static void python_process_tracepoint(struct perf_sample *sample, · 12 unmodified lines
615645 }
616646 if (field->flags & FIELD_IS_STRING &&
617647 is_printable_array(data + offset, len)) {
618− obj = PyString_FromString((char *) data + offset);
648+ obj = _PyUnicode_FromString((char *) data + offset);
619649 } else {
620650 obj = PyByteArray_FromStringAndSize((const char *) data + offset, len);
621651 field->flags &= ~FIELD_IS_STRING;
@@ -668,7 +698,7 @@ static PyObject *tuple_new(unsigned int sz) · 46 unmodified lines
668698 static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val)
669699 {
670700 #if BITS_PER_LONG == 64
671− return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
701+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
672702 #endif
673703 #if BITS_PER_LONG == 32
674704 return PyTuple_SetItem(t, pos, PyLong_FromLongLong(val));
@@ -677,12 +707,12 @@ static int tuple_set_u64(PyObject *t, unsigned int pos, u64 val) · 2 unmodified lines
677707
678708 static int tuple_set_s32(PyObject *t, unsigned int pos, s32 val)
679709 {
680− return PyTuple_SetItem(t, pos, PyInt_FromLong(val));
710+ return PyTuple_SetItem(t, pos, _PyLong_FromLong(val));
681711 }
682712
683713 static int tuple_set_string(PyObject *t, unsigned int pos, const char *s)
684714 {
685− return PyTuple_SetItem(t, pos, PyString_FromString(s));
715+ return PyTuple_SetItem(t, pos, _PyUnicode_FromString(s));
686716 }
687717
688718 static int python_export_evsel(struct db_export *dbe, struct perf_evsel *evsel)
@@ -1029,8 +1059,8 @@ process_stat(struct perf_evsel *counter, int cpu, int thread, u64 tstamp, · 340 unmodified lines
10291059 return;
10301060 }
10311061
1032− PyTuple_SetItem(t, n++, PyInt_FromLong(cpu));
1033− PyTuple_SetItem(t, n++, PyInt_FromLong(thread));
1062+ PyTuple_SetItem(t, n++, _PyLong_FromLong(cpu));
1063+ PyTuple_SetItem(t, n++, _PyLong_FromLong(thread));
10341064
10351065 tuple_set_u64(t, n++, tstamp);
10361066 tuple_set_u64(t, n++, count->val);
@@ -1212,27 +1242,58 @@ static void set_table_handlers(struct tables *tables) · 175 unmodified lines
12121242 SET_TABLE_HANDLER(call_return);
12131243 }
12141244
1245+#if PY_MAJOR_VERSION < 3
1246+static void _free_command_line(const char **command_line, int num)
1247+{
1248+ free(command_line);
1249+}
1250+#else
1251+static void _free_command_line(wchar_t **command_line, int num)
1252+{
1253+ int i;
1254+ for (i = 0; i < num; i++)
1255+ PyMem_RawFree(command_line[i]);
1256+ free(command_line);
1257+}
1258+#endif
1259+
1260+
12151261 /*
12161262 * Start trace script
12171263 */
12181264 static int python_start_script(const char *script, int argc, const char **argv)
12191265 {
12201266 struct tables *tables = &tables_global;
1267+#if PY_MAJOR_VERSION < 3
12211268 const char **command_line;
1269+#else
1270+ wchar_t **command_line;
1271+#endif
12221272 char buf[PATH_MAX];
12231273 int i, err = 0;
12241274 FILE *fp;
12251275
1276+#if PY_MAJOR_VERSION < 3
12261277 command_line = malloc((argc + 1) * sizeof(const char *));
12271278 command_line[0] = script;
12281279 for (i = 1; i < argc + 1; i++)
12291280 command_line[i] = argv[i - 1];
1281+#else
1282+ command_line = malloc((argc + 1) * sizeof(wchar_t *));
1283+ command_line[0] = Py_DecodeLocale(script, NULL);
1284+ for (i = 1; i < argc + 1; i++)
1285+ command_line[i] = Py_DecodeLocale(argv[i - 1], NULL);
1286+#endif
12301287
12311288 Py_Initialize();
12321289
1290+#if PY_MAJOR_VERSION < 3
12331291 initperf_trace_context();
1234−
12351292 PySys_SetArgv(argc + 1, (char **)command_line);
1293+#else
1294+ PyInit_perf_trace_context();
1295+ PySys_SetArgv(argc + 1, command_line);
1296+#endif
12361297
12371298 fp = fopen(script, "r");
12381299 if (!fp) {
@@ -1262,12 +1323,12 @@ static int python_start_script(const char *script, int argc, const char **argv) · 23 unmodified lines
12621323 goto error;
12631324 }
12641325
1265− free(command_line);
1326+ _free_command_line(command_line, argc + 1);
12661327
12671328 return err;
12681329 error:
12691330 Py_Finalize();
1270− free(command_line);
1331+ _free_command_line(command_line, argc + 1);
12711332
12721333 return err;
12731334 }
tools/perf/util/setup.py+3−3
@@ -1,4 +1,4 @@
1−#!/usr/bin/python2
1+#!/usr/bin/python
22
33 from os import getenv
44
@@ -35,11 +35,11 @@ build_tmp = getenv('PYTHON_EXTBUILD_TMP') · 30 unmodified lines
3535 libtraceevent = getenv('LIBTRACEEVENT')
3636 libapikfs = getenv('LIBAPI')
3737
38−ext_sources = [f.strip() for f in file('util/python-ext-sources')
38+ext_sources = [f.strip() for f in open('util/python-ext-sources')
3939 if len(f.strip()) > 0 and f[0] != '#']
4040
4141 # use full paths with source files
42−ext_sources = map(lambda x: '%s/%s' % (src_perf, x) , ext_sources)
42+ext_sources = list(map(lambda x: '%s/%s' % (src_perf, x) , ext_sources))
4343
4444 perf = Extension('perf',
4545 sources = ext_sources,