2 #include <structmember.h>
12 #ifndef PyVarObject_HEAD_INIT
13 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
25 #define member_def(type, member, ptype, help) \
27 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
30 #define sample_member_def(name, member, ptype, help) \
32 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
41 #define sample_members \
42 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
43 sample_member_def(sample_pid, pid, T_INT, "event pid"), \
44 sample_member_def(sample_tid, tid, T_INT, "event tid"), \
45 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
46 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
47 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
48 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
49 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
50 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
52 static char pyrf_mmap_event__doc[] = PyDoc_STR(
"perf mmap event object.");
54 static PyMemberDef pyrf_mmap_event__members[] = {
71 if (asprintf(&s,
"{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
77 ret = PyErr_NoMemory();
79 ret = PyString_FromString(s);
85 static PyTypeObject pyrf_mmap_event__type = {
87 .tp_name =
"perf.mmap_event",
89 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
90 .tp_doc = pyrf_mmap_event__doc,
91 .tp_members = pyrf_mmap_event__members,
92 .tp_repr = (reprfunc)pyrf_mmap_event__repr,
95 static char pyrf_task_event__doc[] = PyDoc_STR(
"perf task (fork/exit) event object.");
97 static PyMemberDef pyrf_task_event__members[] = {
108 static PyObject *pyrf_task_event__repr(
struct pyrf_event *pevent)
110 return PyString_FromFormat(
"{ type: %s, pid: %u, ppid: %u, tid: %u, "
111 "ptid: %u, time: %" PRIu64 "}",
120 static PyTypeObject pyrf_task_event__type = {
122 .tp_name =
"perf.task_event",
124 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
125 .tp_doc = pyrf_task_event__doc,
126 .tp_members = pyrf_task_event__members,
127 .tp_repr = (reprfunc)pyrf_task_event__repr,
130 static char pyrf_comm_event__doc[] = PyDoc_STR(
"perf comm event object.");
132 static PyMemberDef pyrf_comm_event__members[] = {
141 static PyObject *pyrf_comm_event__repr(
struct pyrf_event *pevent)
143 return PyString_FromFormat(
"{ type: comm, pid: %u, tid: %u, comm: %s }",
149 static PyTypeObject pyrf_comm_event__type = {
151 .tp_name =
"perf.comm_event",
153 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
154 .tp_doc = pyrf_comm_event__doc,
155 .tp_members = pyrf_comm_event__members,
156 .tp_repr = (reprfunc)pyrf_comm_event__repr,
159 static char pyrf_throttle_event__doc[] = PyDoc_STR(
"perf throttle event object.");
161 static PyMemberDef pyrf_throttle_event__members[] = {
170 static PyObject *pyrf_throttle_event__repr(
struct pyrf_event *pevent)
174 return PyString_FromFormat(
"{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
175 ", stream_id: %" PRIu64 " }",
180 static PyTypeObject pyrf_throttle_event__type = {
182 .tp_name =
"perf.throttle_event",
184 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
185 .tp_doc = pyrf_throttle_event__doc,
186 .tp_members = pyrf_throttle_event__members,
187 .tp_repr = (reprfunc)pyrf_throttle_event__repr,
190 static char pyrf_lost_event__doc[] = PyDoc_STR(
"perf lost event object.");
192 static PyMemberDef pyrf_lost_event__members[] = {
199 static PyObject *pyrf_lost_event__repr(
struct pyrf_event *pevent)
204 if (asprintf(&s,
"{ type: lost, id: %#" PRIx64 ", "
207 ret = PyErr_NoMemory();
209 ret = PyString_FromString(s);
215 static PyTypeObject pyrf_lost_event__type = {
217 .tp_name =
"perf.lost_event",
219 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
220 .tp_doc = pyrf_lost_event__doc,
221 .tp_members = pyrf_lost_event__members,
222 .tp_repr = (reprfunc)pyrf_lost_event__repr,
225 static char pyrf_read_event__doc[] = PyDoc_STR(
"perf read event object.");
227 static PyMemberDef pyrf_read_event__members[] = {
234 static PyObject *pyrf_read_event__repr(
struct pyrf_event *pevent)
236 return PyString_FromFormat(
"{ type: read, pid: %u, tid: %u }",
245 static PyTypeObject pyrf_read_event__type = {
247 .tp_name =
"perf.read_event",
249 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
250 .tp_doc = pyrf_read_event__doc,
251 .tp_members = pyrf_read_event__members,
252 .tp_repr = (reprfunc)pyrf_read_event__repr,
255 static char pyrf_sample_event__doc[] = PyDoc_STR(
"perf sample event object.");
257 static PyMemberDef pyrf_sample_event__members[] = {
263 static PyObject *pyrf_sample_event__repr(
struct pyrf_event *pevent)
268 if (asprintf(&s,
"{ type: sample }") < 0) {
269 ret = PyErr_NoMemory();
271 ret = PyString_FromString(s);
277 static PyTypeObject pyrf_sample_event__type = {
279 .tp_name =
"perf.sample_event",
281 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
282 .tp_doc = pyrf_sample_event__doc,
283 .tp_members = pyrf_sample_event__members,
284 .tp_repr = (reprfunc)pyrf_sample_event__repr,
287 static int pyrf_event__setup_types(
void)
290 pyrf_mmap_event__type.tp_new =
291 pyrf_task_event__type.tp_new =
292 pyrf_comm_event__type.tp_new =
293 pyrf_lost_event__type.tp_new =
294 pyrf_read_event__type.tp_new =
295 pyrf_sample_event__type.tp_new =
296 pyrf_throttle_event__type.tp_new = PyType_GenericNew;
297 err = PyType_Ready(&pyrf_mmap_event__type);
300 err = PyType_Ready(&pyrf_lost_event__type);
303 err = PyType_Ready(&pyrf_task_event__type);
306 err = PyType_Ready(&pyrf_comm_event__type);
309 err = PyType_Ready(&pyrf_throttle_event__type);
312 err = PyType_Ready(&pyrf_read_event__type);
315 err = PyType_Ready(&pyrf_sample_event__type);
322 static PyTypeObject *pyrf_event__type[] = {
343 ptype = pyrf_event__type[
event->header.type];
344 pevent = PyObject_New(
struct pyrf_event, ptype);
347 return (PyObject *)pevent;
356 static int pyrf_cpu_map__init(
struct pyrf_cpu_map *pcpus,
357 PyObject *args, PyObject *kwargs)
359 static char *kwlist[] = {
"cpustr",
NULL };
362 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|s",
372 static void pyrf_cpu_map__delete(
struct pyrf_cpu_map *pcpus)
375 pcpus->ob_type->tp_free((PyObject*)pcpus);
378 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
382 return pcpus->
cpus->nr;
385 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t
i)
389 if (i >= pcpus->
cpus->nr)
392 return Py_BuildValue(
"i", pcpus->
cpus->map[i]);
395 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
396 .sq_length = pyrf_cpu_map__length,
397 .sq_item = pyrf_cpu_map__item,
400 static char pyrf_cpu_map__doc[] = PyDoc_STR(
"cpu map object.");
402 static PyTypeObject pyrf_cpu_map__type = {
404 .tp_name =
"perf.cpu_map",
406 .tp_dealloc = (destructor)pyrf_cpu_map__delete,
407 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
408 .tp_doc = pyrf_cpu_map__doc,
409 .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
410 .tp_init = (initproc)pyrf_cpu_map__init,
413 static int pyrf_cpu_map__setup_types(
void)
415 pyrf_cpu_map__type.tp_new = PyType_GenericNew;
416 return PyType_Ready(&pyrf_cpu_map__type);
426 PyObject *args, PyObject *kwargs)
428 static char *kwlist[] = {
"pid",
"tid",
"uid",
NULL };
431 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|iii",
432 kwlist, &pid, &tid, &
uid))
444 pthreads->ob_type->tp_free((PyObject*)pthreads);
447 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
454 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
458 if (i >= pthreads->
threads->nr)
461 return Py_BuildValue(
"i", pthreads->
threads->map[i]);
464 static PySequenceMethods pyrf_thread_map__sequence_methods = {
465 .sq_length = pyrf_thread_map__length,
466 .sq_item = pyrf_thread_map__item,
469 static char pyrf_thread_map__doc[] = PyDoc_STR(
"thread map object.");
471 static PyTypeObject pyrf_thread_map__type = {
473 .tp_name =
"perf.thread_map",
475 .tp_dealloc = (destructor)pyrf_thread_map__delete,
476 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
477 .tp_doc = pyrf_thread_map__doc,
478 .tp_as_sequence = &pyrf_thread_map__sequence_methods,
479 .tp_init = (initproc)pyrf_thread_map__init,
482 static int pyrf_thread_map__setup_types(
void)
484 pyrf_thread_map__type.tp_new = PyType_GenericNew;
485 return PyType_Ready(&pyrf_thread_map__type);
494 static int pyrf_evsel__init(
struct pyrf_evsel *pevsel,
495 PyObject *args, PyObject *kwargs)
502 static char *kwlist[] = {
554 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
555 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
569 if (sample_period != 0) {
599 static void pyrf_evsel__delete(
struct pyrf_evsel *pevsel)
602 pevsel->ob_type->tp_free((PyObject*)pevsel);
605 static PyObject *pyrf_evsel__open(
struct pyrf_evsel *pevsel,
606 PyObject *args, PyObject *kwargs)
611 PyObject *pcpus =
NULL, *pthreads =
NULL;
612 int group = 0, inherit = 0;
613 static char *kwlist[] = {
"cpus",
"threads",
"group",
"inherit",
NULL };
615 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|OOii", kwlist,
616 &pcpus, &pthreads, &group, &inherit))
619 if (pthreads !=
NULL)
625 evsel->
attr.inherit = inherit;
631 PyErr_SetFromErrno(PyExc_OSError);
639 static PyMethodDef pyrf_evsel__methods[] = {
642 .ml_meth = (PyCFunction)pyrf_evsel__open,
643 .ml_flags = METH_VARARGS | METH_KEYWORDS,
644 .ml_doc = PyDoc_STR(
"open the event selector file descriptor table.")
649 static char pyrf_evsel__doc[] = PyDoc_STR(
"perf event selector list object.");
651 static PyTypeObject pyrf_evsel__type = {
653 .tp_name =
"perf.evsel",
655 .tp_dealloc = (destructor)pyrf_evsel__delete,
656 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
657 .tp_doc = pyrf_evsel__doc,
658 .tp_methods = pyrf_evsel__methods,
659 .tp_init = (initproc)pyrf_evsel__init,
662 static int pyrf_evsel__setup_types(
void)
664 pyrf_evsel__type.tp_new = PyType_GenericNew;
665 return PyType_Ready(&pyrf_evsel__type);
674 static int pyrf_evlist__init(
struct pyrf_evlist *pevlist,
677 PyObject *pcpus =
NULL, *pthreads =
NULL;
681 if (!PyArg_ParseTuple(args,
"OO", &pcpus, &pthreads))
690 static void pyrf_evlist__delete(
struct pyrf_evlist *pevlist)
693 pevlist->ob_type->tp_free((PyObject*)pevlist);
696 static PyObject *pyrf_evlist__mmap(
struct pyrf_evlist *pevlist,
697 PyObject *args, PyObject *kwargs)
700 static char *kwlist[] = {
"pages",
"overwrite",
NULL };
703 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|ii", kwlist,
708 PyErr_SetFromErrno(PyExc_OSError);
716 static PyObject *pyrf_evlist__poll(
struct pyrf_evlist *pevlist,
717 PyObject *args, PyObject *kwargs)
720 static char *kwlist[] = {
"timeout",
NULL };
723 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|i", kwlist, &timeout))
728 PyErr_SetFromErrno(PyExc_OSError);
732 return Py_BuildValue(
"i",
n);
735 static PyObject *pyrf_evlist__get_pollfd(
struct pyrf_evlist *pevlist,
736 PyObject *args __maybe_unused,
737 PyObject *kwargs __maybe_unused)
740 PyObject *
list = PyList_New(0);
743 for (i = 0; i < evlist->
nr_fds; ++
i) {
745 FILE *
fp = fdopen(evlist->
pollfd[i].fd,
"r");
750 file = PyFile_FromFile(fp,
"perf",
"r",
NULL);
754 if (PyList_Append(list, file) != 0) {
764 return PyErr_NoMemory();
768 static PyObject *pyrf_evlist__add(
struct pyrf_evlist *pevlist,
770 PyObject *kwargs __maybe_unused)
776 if (!PyArg_ParseTuple(args,
"O", &pevsel))
780 evsel = &((
struct pyrf_evsel *)pevsel)->evsel;
784 return Py_BuildValue(
"i", evlist->
nr_entries);
787 static PyObject *pyrf_evlist__read_on_cpu(
struct pyrf_evlist *pevlist,
788 PyObject *args, PyObject *kwargs)
792 int sample_id_all = 1,
cpu;
793 static char *kwlist[] = {
"cpu",
"sample_id_all",
NULL };
796 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"i|i", kwlist,
797 &
cpu, &sample_id_all))
802 PyObject *pyevent = pyrf_event__new(event);
806 return PyErr_NoMemory();
810 return PyErr_Format(PyExc_OSError,
811 "perf: can't parse sample, err=%d", err);
819 static PyObject *pyrf_evlist__open(
struct pyrf_evlist *pevlist,
820 PyObject *args, PyObject *kwargs)
824 static char *kwlist[] = {
"group",
NULL };
826 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|OOii", kwlist, &group))
833 PyErr_SetFromErrno(PyExc_OSError);
841 static PyMethodDef pyrf_evlist__methods[] = {
844 .ml_meth = (PyCFunction)pyrf_evlist__mmap,
845 .ml_flags = METH_VARARGS | METH_KEYWORDS,
846 .ml_doc = PyDoc_STR(
"mmap the file descriptor table.")
850 .ml_meth = (PyCFunction)pyrf_evlist__open,
851 .ml_flags = METH_VARARGS | METH_KEYWORDS,
852 .ml_doc = PyDoc_STR(
"open the file descriptors.")
856 .ml_meth = (PyCFunction)pyrf_evlist__poll,
857 .ml_flags = METH_VARARGS | METH_KEYWORDS,
858 .ml_doc = PyDoc_STR(
"poll the file descriptor table.")
861 .ml_name =
"get_pollfd",
862 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
863 .ml_flags = METH_VARARGS | METH_KEYWORDS,
864 .ml_doc = PyDoc_STR(
"get the poll file descriptor table.")
868 .ml_meth = (PyCFunction)pyrf_evlist__add,
869 .ml_flags = METH_VARARGS | METH_KEYWORDS,
870 .ml_doc = PyDoc_STR(
"adds an event selector to the list.")
873 .ml_name =
"read_on_cpu",
874 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
875 .ml_flags = METH_VARARGS | METH_KEYWORDS,
876 .ml_doc = PyDoc_STR(
"reads an event.")
881 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
885 return pevlist->
evlist.nr_entries;
888 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
893 if (i >= pevlist->
evlist.nr_entries)
903 static PySequenceMethods pyrf_evlist__sequence_methods = {
904 .sq_length = pyrf_evlist__length,
905 .sq_item = pyrf_evlist__item,
908 static char pyrf_evlist__doc[] = PyDoc_STR(
"perf event selector list object.");
910 static PyTypeObject pyrf_evlist__type = {
912 .tp_name =
"perf.evlist",
914 .tp_dealloc = (destructor)pyrf_evlist__delete,
915 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
916 .tp_as_sequence = &pyrf_evlist__sequence_methods,
917 .tp_doc = pyrf_evlist__doc,
918 .tp_methods = pyrf_evlist__methods,
919 .tp_init = (initproc)pyrf_evlist__init,
922 static int pyrf_evlist__setup_types(
void)
924 pyrf_evlist__type.tp_new = PyType_GenericNew;
925 return PyType_Ready(&pyrf_evlist__type);
931 } perf__constants[] = {
1000 static PyMethodDef perf__methods[] = {
1001 { .ml_name =
NULL, }
1008 PyObject *dict, *
module = Py_InitModule(
"perf", perf__methods);
1010 if (module ==
NULL ||
1011 pyrf_event__setup_types() < 0 ||
1012 pyrf_evlist__setup_types() < 0 ||
1013 pyrf_evsel__setup_types() < 0 ||
1014 pyrf_thread_map__setup_types() < 0 ||
1015 pyrf_cpu_map__setup_types() < 0)
1018 Py_INCREF(&pyrf_evlist__type);
1019 PyModule_AddObject(module,
"evlist", (PyObject*)&pyrf_evlist__type);
1021 Py_INCREF(&pyrf_evsel__type);
1022 PyModule_AddObject(module,
"evsel", (PyObject*)&pyrf_evsel__type);
1024 Py_INCREF(&pyrf_thread_map__type);
1025 PyModule_AddObject(module,
"thread_map", (PyObject*)&pyrf_thread_map__type);
1027 Py_INCREF(&pyrf_cpu_map__type);
1028 PyModule_AddObject(module,
"cpu_map", (PyObject*)&pyrf_cpu_map__type);
1030 dict = PyModule_GetDict(module);
1034 for (i = 0; perf__constants[
i].name !=
NULL; i++) {
1035 obj = PyInt_FromLong(perf__constants[i].
value);
1038 PyDict_SetItemString(dict, perf__constants[i].
name, obj);
1043 if (PyErr_Occurred())
1044 PyErr_SetString(PyExc_ImportError,
"perf: Init failed!");