2 #include <structmember.h>
10 #include "thread_map.h"
13 * Support debug printing even though util/debug.c is not linked. That means
14 * implementing 'verbose' and 'eprintf'.
18 int eprintf(int level, int var, const char *fmt, ...)
25 ret = vfprintf(stderr, fmt, args);
32 /* Define PyVarObject_HEAD_INIT for python 2.5 */
33 #ifndef PyVarObject_HEAD_INIT
34 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
37 PyMODINIT_FUNC initperf(void);
39 #define member_def(type, member, ptype, help) \
41 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
44 #define sample_member_def(name, member, ptype, help) \
46 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
51 struct perf_evsel *evsel;
52 struct perf_sample sample;
53 union perf_event event;
56 #define sample_members \
57 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
58 sample_member_def(sample_pid, pid, T_INT, "event pid"), \
59 sample_member_def(sample_tid, tid, T_INT, "event tid"), \
60 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
61 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
62 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
63 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
64 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
65 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
67 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
69 static PyMemberDef pyrf_mmap_event__members[] = {
71 member_def(perf_event_header, type, T_UINT, "event type"),
72 member_def(perf_event_header, misc, T_UINT, "event misc"),
73 member_def(mmap_event, pid, T_UINT, "event pid"),
74 member_def(mmap_event, tid, T_UINT, "event tid"),
75 member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
76 member_def(mmap_event, len, T_ULONGLONG, "map length"),
77 member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
78 member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
82 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
87 if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
88 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
90 pevent->event.mmap.pid, pevent->event.mmap.tid,
91 pevent->event.mmap.start, pevent->event.mmap.len,
92 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
93 ret = PyErr_NoMemory();
95 ret = PyString_FromString(s);
101 static PyTypeObject pyrf_mmap_event__type = {
102 PyVarObject_HEAD_INIT(NULL, 0)
103 .tp_name = "perf.mmap_event",
104 .tp_basicsize = sizeof(struct pyrf_event),
105 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
106 .tp_doc = pyrf_mmap_event__doc,
107 .tp_members = pyrf_mmap_event__members,
108 .tp_repr = (reprfunc)pyrf_mmap_event__repr,
111 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
113 static PyMemberDef pyrf_task_event__members[] = {
115 member_def(perf_event_header, type, T_UINT, "event type"),
116 member_def(fork_event, pid, T_UINT, "event pid"),
117 member_def(fork_event, ppid, T_UINT, "event ppid"),
118 member_def(fork_event, tid, T_UINT, "event tid"),
119 member_def(fork_event, ptid, T_UINT, "event ptid"),
120 member_def(fork_event, time, T_ULONGLONG, "timestamp"),
124 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
126 return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
127 "ptid: %u, time: %" PRIu64 "}",
128 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
129 pevent->event.fork.pid,
130 pevent->event.fork.ppid,
131 pevent->event.fork.tid,
132 pevent->event.fork.ptid,
133 pevent->event.fork.time);
136 static PyTypeObject pyrf_task_event__type = {
137 PyVarObject_HEAD_INIT(NULL, 0)
138 .tp_name = "perf.task_event",
139 .tp_basicsize = sizeof(struct pyrf_event),
140 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
141 .tp_doc = pyrf_task_event__doc,
142 .tp_members = pyrf_task_event__members,
143 .tp_repr = (reprfunc)pyrf_task_event__repr,
146 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
148 static PyMemberDef pyrf_comm_event__members[] = {
150 member_def(perf_event_header, type, T_UINT, "event type"),
151 member_def(comm_event, pid, T_UINT, "event pid"),
152 member_def(comm_event, tid, T_UINT, "event tid"),
153 member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
157 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
159 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
160 pevent->event.comm.pid,
161 pevent->event.comm.tid,
162 pevent->event.comm.comm);
165 static PyTypeObject pyrf_comm_event__type = {
166 PyVarObject_HEAD_INIT(NULL, 0)
167 .tp_name = "perf.comm_event",
168 .tp_basicsize = sizeof(struct pyrf_event),
169 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
170 .tp_doc = pyrf_comm_event__doc,
171 .tp_members = pyrf_comm_event__members,
172 .tp_repr = (reprfunc)pyrf_comm_event__repr,
175 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
177 static PyMemberDef pyrf_throttle_event__members[] = {
179 member_def(perf_event_header, type, T_UINT, "event type"),
180 member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
181 member_def(throttle_event, id, T_ULONGLONG, "event id"),
182 member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
186 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
188 struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
190 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
191 ", stream_id: %" PRIu64 " }",
192 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
193 te->time, te->id, te->stream_id);
196 static PyTypeObject pyrf_throttle_event__type = {
197 PyVarObject_HEAD_INIT(NULL, 0)
198 .tp_name = "perf.throttle_event",
199 .tp_basicsize = sizeof(struct pyrf_event),
200 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
201 .tp_doc = pyrf_throttle_event__doc,
202 .tp_members = pyrf_throttle_event__members,
203 .tp_repr = (reprfunc)pyrf_throttle_event__repr,
206 static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
208 static PyMemberDef pyrf_lost_event__members[] = {
210 member_def(lost_event, id, T_ULONGLONG, "event id"),
211 member_def(lost_event, lost, T_ULONGLONG, "number of lost events"),
215 static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
220 if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", "
221 "lost: %#" PRIx64 " }",
222 pevent->event.lost.id, pevent->event.lost.lost) < 0) {
223 ret = PyErr_NoMemory();
225 ret = PyString_FromString(s);
231 static PyTypeObject pyrf_lost_event__type = {
232 PyVarObject_HEAD_INIT(NULL, 0)
233 .tp_name = "perf.lost_event",
234 .tp_basicsize = sizeof(struct pyrf_event),
235 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
236 .tp_doc = pyrf_lost_event__doc,
237 .tp_members = pyrf_lost_event__members,
238 .tp_repr = (reprfunc)pyrf_lost_event__repr,
241 static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
243 static PyMemberDef pyrf_read_event__members[] = {
245 member_def(read_event, pid, T_UINT, "event pid"),
246 member_def(read_event, tid, T_UINT, "event tid"),
250 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
252 return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
253 pevent->event.read.pid,
254 pevent->event.read.tid);
256 * FIXME: return the array of read values,
257 * making this method useful ;-)
261 static PyTypeObject pyrf_read_event__type = {
262 PyVarObject_HEAD_INIT(NULL, 0)
263 .tp_name = "perf.read_event",
264 .tp_basicsize = sizeof(struct pyrf_event),
265 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
266 .tp_doc = pyrf_read_event__doc,
267 .tp_members = pyrf_read_event__members,
268 .tp_repr = (reprfunc)pyrf_read_event__repr,
271 static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
273 static PyMemberDef pyrf_sample_event__members[] = {
275 member_def(perf_event_header, type, T_UINT, "event type"),
279 static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
284 if (asprintf(&s, "{ type: sample }") < 0) {
285 ret = PyErr_NoMemory();
287 ret = PyString_FromString(s);
293 static bool is_tracepoint(struct pyrf_event *pevent)
295 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT;
298 static int is_printable_array(char *p, unsigned int len)
302 for (i = 0; i < len; i++) {
303 if (!isprint(p[i]) && !isspace(p[i]))
311 tracepoint_field(struct pyrf_event *pe, struct format_field *field)
313 struct pevent *pevent = field->event->pevent;
314 void *data = pe->sample.raw_data;
315 PyObject *ret = NULL;
316 unsigned long long val;
317 unsigned int offset, len;
319 if (field->flags & FIELD_IS_ARRAY) {
320 offset = field->offset;
322 if (field->flags & FIELD_IS_DYNAMIC) {
323 val = pevent_read_number(pevent, data + offset, len);
328 if (field->flags & FIELD_IS_STRING &&
329 is_printable_array(data + offset, len)) {
330 ret = PyString_FromString((char *)data + offset);
332 ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
333 field->flags &= ~FIELD_IS_STRING;
336 val = pevent_read_number(pevent, data + field->offset,
338 if (field->flags & FIELD_IS_POINTER)
339 ret = PyLong_FromUnsignedLong((unsigned long) val);
340 else if (field->flags & FIELD_IS_SIGNED)
341 ret = PyLong_FromLong((long) val);
343 ret = PyLong_FromUnsignedLong((unsigned long) val);
350 get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
352 const char *str = PyString_AsString(PyObject_Str(attr_name));
353 struct perf_evsel *evsel = pevent->evsel;
354 struct format_field *field;
356 if (!evsel->tp_format) {
357 struct event_format *tp_format;
359 tp_format = trace_event__tp_format_id(evsel->attr.config);
363 evsel->tp_format = tp_format;
366 field = pevent_find_any_field(evsel->tp_format, str);
370 return tracepoint_field(pevent, field);
374 pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
376 PyObject *obj = NULL;
378 if (is_tracepoint(pevent))
379 obj = get_tracepoint_field(pevent, attr_name);
381 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
384 static PyTypeObject pyrf_sample_event__type = {
385 PyVarObject_HEAD_INIT(NULL, 0)
386 .tp_name = "perf.sample_event",
387 .tp_basicsize = sizeof(struct pyrf_event),
388 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
389 .tp_doc = pyrf_sample_event__doc,
390 .tp_members = pyrf_sample_event__members,
391 .tp_repr = (reprfunc)pyrf_sample_event__repr,
392 .tp_getattro = (getattrofunc) pyrf_sample_event__getattro,
395 static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
397 static PyMemberDef pyrf_context_switch_event__members[] = {
399 member_def(perf_event_header, type, T_UINT, "event type"),
400 member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"),
401 member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"),
405 static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
410 if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
411 pevent->event.context_switch.next_prev_pid,
412 pevent->event.context_switch.next_prev_tid,
413 !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
414 ret = PyErr_NoMemory();
416 ret = PyString_FromString(s);
422 static PyTypeObject pyrf_context_switch_event__type = {
423 PyVarObject_HEAD_INIT(NULL, 0)
424 .tp_name = "perf.context_switch_event",
425 .tp_basicsize = sizeof(struct pyrf_event),
426 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
427 .tp_doc = pyrf_context_switch_event__doc,
428 .tp_members = pyrf_context_switch_event__members,
429 .tp_repr = (reprfunc)pyrf_context_switch_event__repr,
432 static int pyrf_event__setup_types(void)
435 pyrf_mmap_event__type.tp_new =
436 pyrf_task_event__type.tp_new =
437 pyrf_comm_event__type.tp_new =
438 pyrf_lost_event__type.tp_new =
439 pyrf_read_event__type.tp_new =
440 pyrf_sample_event__type.tp_new =
441 pyrf_context_switch_event__type.tp_new =
442 pyrf_throttle_event__type.tp_new = PyType_GenericNew;
443 err = PyType_Ready(&pyrf_mmap_event__type);
446 err = PyType_Ready(&pyrf_lost_event__type);
449 err = PyType_Ready(&pyrf_task_event__type);
452 err = PyType_Ready(&pyrf_comm_event__type);
455 err = PyType_Ready(&pyrf_throttle_event__type);
458 err = PyType_Ready(&pyrf_read_event__type);
461 err = PyType_Ready(&pyrf_sample_event__type);
464 err = PyType_Ready(&pyrf_context_switch_event__type);
471 static PyTypeObject *pyrf_event__type[] = {
472 [PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
473 [PERF_RECORD_LOST] = &pyrf_lost_event__type,
474 [PERF_RECORD_COMM] = &pyrf_comm_event__type,
475 [PERF_RECORD_EXIT] = &pyrf_task_event__type,
476 [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
477 [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
478 [PERF_RECORD_FORK] = &pyrf_task_event__type,
479 [PERF_RECORD_READ] = &pyrf_read_event__type,
480 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
481 [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type,
482 [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type,
485 static PyObject *pyrf_event__new(union perf_event *event)
487 struct pyrf_event *pevent;
490 if ((event->header.type < PERF_RECORD_MMAP ||
491 event->header.type > PERF_RECORD_SAMPLE) &&
492 !(event->header.type == PERF_RECORD_SWITCH ||
493 event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
496 ptype = pyrf_event__type[event->header.type];
497 pevent = PyObject_New(struct pyrf_event, ptype);
499 memcpy(&pevent->event, event, event->header.size);
500 return (PyObject *)pevent;
503 struct pyrf_cpu_map {
506 struct cpu_map *cpus;
509 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
510 PyObject *args, PyObject *kwargs)
512 static char *kwlist[] = { "cpustr", NULL };
515 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
519 pcpus->cpus = cpu_map__new(cpustr);
520 if (pcpus->cpus == NULL)
525 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
527 cpu_map__put(pcpus->cpus);
528 pcpus->ob_type->tp_free((PyObject*)pcpus);
531 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
533 struct pyrf_cpu_map *pcpus = (void *)obj;
535 return pcpus->cpus->nr;
538 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
540 struct pyrf_cpu_map *pcpus = (void *)obj;
542 if (i >= pcpus->cpus->nr)
545 return Py_BuildValue("i", pcpus->cpus->map[i]);
548 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
549 .sq_length = pyrf_cpu_map__length,
550 .sq_item = pyrf_cpu_map__item,
553 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
555 static PyTypeObject pyrf_cpu_map__type = {
556 PyVarObject_HEAD_INIT(NULL, 0)
557 .tp_name = "perf.cpu_map",
558 .tp_basicsize = sizeof(struct pyrf_cpu_map),
559 .tp_dealloc = (destructor)pyrf_cpu_map__delete,
560 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
561 .tp_doc = pyrf_cpu_map__doc,
562 .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
563 .tp_init = (initproc)pyrf_cpu_map__init,
566 static int pyrf_cpu_map__setup_types(void)
568 pyrf_cpu_map__type.tp_new = PyType_GenericNew;
569 return PyType_Ready(&pyrf_cpu_map__type);
572 struct pyrf_thread_map {
575 struct thread_map *threads;
578 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
579 PyObject *args, PyObject *kwargs)
581 static char *kwlist[] = { "pid", "tid", "uid", NULL };
582 int pid = -1, tid = -1, uid = UINT_MAX;
584 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
585 kwlist, &pid, &tid, &uid))
588 pthreads->threads = thread_map__new(pid, tid, uid);
589 if (pthreads->threads == NULL)
594 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
596 thread_map__put(pthreads->threads);
597 pthreads->ob_type->tp_free((PyObject*)pthreads);
600 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
602 struct pyrf_thread_map *pthreads = (void *)obj;
604 return pthreads->threads->nr;
607 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
609 struct pyrf_thread_map *pthreads = (void *)obj;
611 if (i >= pthreads->threads->nr)
614 return Py_BuildValue("i", pthreads->threads->map[i]);
617 static PySequenceMethods pyrf_thread_map__sequence_methods = {
618 .sq_length = pyrf_thread_map__length,
619 .sq_item = pyrf_thread_map__item,
622 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
624 static PyTypeObject pyrf_thread_map__type = {
625 PyVarObject_HEAD_INIT(NULL, 0)
626 .tp_name = "perf.thread_map",
627 .tp_basicsize = sizeof(struct pyrf_thread_map),
628 .tp_dealloc = (destructor)pyrf_thread_map__delete,
629 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
630 .tp_doc = pyrf_thread_map__doc,
631 .tp_as_sequence = &pyrf_thread_map__sequence_methods,
632 .tp_init = (initproc)pyrf_thread_map__init,
635 static int pyrf_thread_map__setup_types(void)
637 pyrf_thread_map__type.tp_new = PyType_GenericNew;
638 return PyType_Ready(&pyrf_thread_map__type);
644 struct perf_evsel evsel;
647 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
648 PyObject *args, PyObject *kwargs)
650 struct perf_event_attr attr = {
651 .type = PERF_TYPE_HARDWARE,
652 .config = PERF_COUNT_HW_CPU_CYCLES,
653 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
655 static char *kwlist[] = {
687 u64 sample_period = 0;
709 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
710 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
711 &attr.type, &attr.config, &attr.sample_freq,
712 &sample_period, &attr.sample_type,
713 &attr.read_format, &disabled, &inherit,
714 &pinned, &exclusive, &exclude_user,
715 &exclude_kernel, &exclude_hv, &exclude_idle,
716 &mmap, &context_switch, &comm, &freq, &inherit_stat,
717 &enable_on_exec, &task, &watermark,
718 &precise_ip, &mmap_data, &sample_id_all,
719 &attr.wakeup_events, &attr.bp_type,
720 &attr.bp_addr, &attr.bp_len, &idx))
724 if (sample_period != 0) {
725 if (attr.sample_freq != 0)
726 return -1; /* FIXME: throw right exception */
727 attr.sample_period = sample_period;
731 attr.disabled = disabled;
732 attr.inherit = inherit;
733 attr.pinned = pinned;
734 attr.exclusive = exclusive;
735 attr.exclude_user = exclude_user;
736 attr.exclude_kernel = exclude_kernel;
737 attr.exclude_hv = exclude_hv;
738 attr.exclude_idle = exclude_idle;
740 attr.context_switch = context_switch;
743 attr.inherit_stat = inherit_stat;
744 attr.enable_on_exec = enable_on_exec;
746 attr.watermark = watermark;
747 attr.precise_ip = precise_ip;
748 attr.mmap_data = mmap_data;
749 attr.sample_id_all = sample_id_all;
750 attr.size = sizeof(attr);
752 perf_evsel__init(&pevsel->evsel, &attr, idx);
756 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
758 perf_evsel__exit(&pevsel->evsel);
759 pevsel->ob_type->tp_free((PyObject*)pevsel);
762 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
763 PyObject *args, PyObject *kwargs)
765 struct perf_evsel *evsel = &pevsel->evsel;
766 struct cpu_map *cpus = NULL;
767 struct thread_map *threads = NULL;
768 PyObject *pcpus = NULL, *pthreads = NULL;
769 int group = 0, inherit = 0;
770 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
772 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
773 &pcpus, &pthreads, &group, &inherit))
776 if (pthreads != NULL)
777 threads = ((struct pyrf_thread_map *)pthreads)->threads;
780 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
782 evsel->attr.inherit = inherit;
784 * This will group just the fds for this single evsel, to group
785 * multiple events, use evlist.open().
787 if (perf_evsel__open(evsel, cpus, threads) < 0) {
788 PyErr_SetFromErrno(PyExc_OSError);
796 static PyMethodDef pyrf_evsel__methods[] = {
799 .ml_meth = (PyCFunction)pyrf_evsel__open,
800 .ml_flags = METH_VARARGS | METH_KEYWORDS,
801 .ml_doc = PyDoc_STR("open the event selector file descriptor table.")
806 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
808 static PyTypeObject pyrf_evsel__type = {
809 PyVarObject_HEAD_INIT(NULL, 0)
810 .tp_name = "perf.evsel",
811 .tp_basicsize = sizeof(struct pyrf_evsel),
812 .tp_dealloc = (destructor)pyrf_evsel__delete,
813 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
814 .tp_doc = pyrf_evsel__doc,
815 .tp_methods = pyrf_evsel__methods,
816 .tp_init = (initproc)pyrf_evsel__init,
819 static int pyrf_evsel__setup_types(void)
821 pyrf_evsel__type.tp_new = PyType_GenericNew;
822 return PyType_Ready(&pyrf_evsel__type);
828 struct perf_evlist evlist;
831 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
832 PyObject *args, PyObject *kwargs __maybe_unused)
834 PyObject *pcpus = NULL, *pthreads = NULL;
835 struct cpu_map *cpus;
836 struct thread_map *threads;
838 if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
841 threads = ((struct pyrf_thread_map *)pthreads)->threads;
842 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
843 perf_evlist__init(&pevlist->evlist, cpus, threads);
847 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
849 perf_evlist__exit(&pevlist->evlist);
850 pevlist->ob_type->tp_free((PyObject*)pevlist);
853 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
854 PyObject *args, PyObject *kwargs)
856 struct perf_evlist *evlist = &pevlist->evlist;
857 static char *kwlist[] = { "pages", "overwrite", NULL };
858 int pages = 128, overwrite = false;
860 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
864 if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
865 PyErr_SetFromErrno(PyExc_OSError);
873 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
874 PyObject *args, PyObject *kwargs)
876 struct perf_evlist *evlist = &pevlist->evlist;
877 static char *kwlist[] = { "timeout", NULL };
880 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
883 n = perf_evlist__poll(evlist, timeout);
885 PyErr_SetFromErrno(PyExc_OSError);
889 return Py_BuildValue("i", n);
892 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
893 PyObject *args __maybe_unused,
894 PyObject *kwargs __maybe_unused)
896 struct perf_evlist *evlist = &pevlist->evlist;
897 PyObject *list = PyList_New(0);
900 for (i = 0; i < evlist->pollfd.nr; ++i) {
902 FILE *fp = fdopen(evlist->pollfd.entries[i].fd, "r");
907 file = PyFile_FromFile(fp, "perf", "r", NULL);
911 if (PyList_Append(list, file) != 0) {
921 return PyErr_NoMemory();
925 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
927 PyObject *kwargs __maybe_unused)
929 struct perf_evlist *evlist = &pevlist->evlist;
931 struct perf_evsel *evsel;
933 if (!PyArg_ParseTuple(args, "O", &pevsel))
937 evsel = &((struct pyrf_evsel *)pevsel)->evsel;
938 evsel->idx = evlist->nr_entries;
939 perf_evlist__add(evlist, evsel);
941 return Py_BuildValue("i", evlist->nr_entries);
944 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
945 PyObject *args, PyObject *kwargs)
947 struct perf_evlist *evlist = &pevlist->evlist;
948 union perf_event *event;
949 int sample_id_all = 1, cpu;
950 static char *kwlist[] = { "cpu", "sample_id_all", NULL };
953 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
954 &cpu, &sample_id_all))
957 event = perf_evlist__mmap_read(evlist, cpu);
959 PyObject *pyevent = pyrf_event__new(event);
960 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
961 struct perf_evsel *evsel;
964 return PyErr_NoMemory();
966 evsel = perf_evlist__event2evsel(evlist, event);
970 pevent->evsel = evsel;
972 err = perf_evsel__parse_sample(evsel, event, &pevent->sample);
974 /* Consume the even only after we parsed it out. */
975 perf_evlist__mmap_consume(evlist, cpu);
978 return PyErr_Format(PyExc_OSError,
979 "perf: can't parse sample, err=%d", err);
987 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
988 PyObject *args, PyObject *kwargs)
990 struct perf_evlist *evlist = &pevlist->evlist;
992 static char *kwlist[] = { "group", NULL };
994 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
998 perf_evlist__set_leader(evlist);
1000 if (perf_evlist__open(evlist) < 0) {
1001 PyErr_SetFromErrno(PyExc_OSError);
1009 static PyMethodDef pyrf_evlist__methods[] = {
1012 .ml_meth = (PyCFunction)pyrf_evlist__mmap,
1013 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1014 .ml_doc = PyDoc_STR("mmap the file descriptor table.")
1018 .ml_meth = (PyCFunction)pyrf_evlist__open,
1019 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1020 .ml_doc = PyDoc_STR("open the file descriptors.")
1024 .ml_meth = (PyCFunction)pyrf_evlist__poll,
1025 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1026 .ml_doc = PyDoc_STR("poll the file descriptor table.")
1029 .ml_name = "get_pollfd",
1030 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
1031 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1032 .ml_doc = PyDoc_STR("get the poll file descriptor table.")
1036 .ml_meth = (PyCFunction)pyrf_evlist__add,
1037 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1038 .ml_doc = PyDoc_STR("adds an event selector to the list.")
1041 .ml_name = "read_on_cpu",
1042 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
1043 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1044 .ml_doc = PyDoc_STR("reads an event.")
1046 { .ml_name = NULL, }
1049 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
1051 struct pyrf_evlist *pevlist = (void *)obj;
1053 return pevlist->evlist.nr_entries;
1056 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
1058 struct pyrf_evlist *pevlist = (void *)obj;
1059 struct perf_evsel *pos;
1061 if (i >= pevlist->evlist.nr_entries)
1064 evlist__for_each_entry(&pevlist->evlist, pos) {
1069 return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
1072 static PySequenceMethods pyrf_evlist__sequence_methods = {
1073 .sq_length = pyrf_evlist__length,
1074 .sq_item = pyrf_evlist__item,
1077 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
1079 static PyTypeObject pyrf_evlist__type = {
1080 PyVarObject_HEAD_INIT(NULL, 0)
1081 .tp_name = "perf.evlist",
1082 .tp_basicsize = sizeof(struct pyrf_evlist),
1083 .tp_dealloc = (destructor)pyrf_evlist__delete,
1084 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1085 .tp_as_sequence = &pyrf_evlist__sequence_methods,
1086 .tp_doc = pyrf_evlist__doc,
1087 .tp_methods = pyrf_evlist__methods,
1088 .tp_init = (initproc)pyrf_evlist__init,
1091 static int pyrf_evlist__setup_types(void)
1093 pyrf_evlist__type.tp_new = PyType_GenericNew;
1094 return PyType_Ready(&pyrf_evlist__type);
1097 #define PERF_CONST(name) { #name, PERF_##name }
1102 } perf__constants[] = {
1103 PERF_CONST(TYPE_HARDWARE),
1104 PERF_CONST(TYPE_SOFTWARE),
1105 PERF_CONST(TYPE_TRACEPOINT),
1106 PERF_CONST(TYPE_HW_CACHE),
1107 PERF_CONST(TYPE_RAW),
1108 PERF_CONST(TYPE_BREAKPOINT),
1110 PERF_CONST(COUNT_HW_CPU_CYCLES),
1111 PERF_CONST(COUNT_HW_INSTRUCTIONS),
1112 PERF_CONST(COUNT_HW_CACHE_REFERENCES),
1113 PERF_CONST(COUNT_HW_CACHE_MISSES),
1114 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
1115 PERF_CONST(COUNT_HW_BRANCH_MISSES),
1116 PERF_CONST(COUNT_HW_BUS_CYCLES),
1117 PERF_CONST(COUNT_HW_CACHE_L1D),
1118 PERF_CONST(COUNT_HW_CACHE_L1I),
1119 PERF_CONST(COUNT_HW_CACHE_LL),
1120 PERF_CONST(COUNT_HW_CACHE_DTLB),
1121 PERF_CONST(COUNT_HW_CACHE_ITLB),
1122 PERF_CONST(COUNT_HW_CACHE_BPU),
1123 PERF_CONST(COUNT_HW_CACHE_OP_READ),
1124 PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
1125 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
1126 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
1127 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
1129 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
1130 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
1132 PERF_CONST(COUNT_SW_CPU_CLOCK),
1133 PERF_CONST(COUNT_SW_TASK_CLOCK),
1134 PERF_CONST(COUNT_SW_PAGE_FAULTS),
1135 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
1136 PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
1137 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
1138 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
1139 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
1140 PERF_CONST(COUNT_SW_EMULATION_FAULTS),
1141 PERF_CONST(COUNT_SW_DUMMY),
1143 PERF_CONST(SAMPLE_IP),
1144 PERF_CONST(SAMPLE_TID),
1145 PERF_CONST(SAMPLE_TIME),
1146 PERF_CONST(SAMPLE_ADDR),
1147 PERF_CONST(SAMPLE_READ),
1148 PERF_CONST(SAMPLE_CALLCHAIN),
1149 PERF_CONST(SAMPLE_ID),
1150 PERF_CONST(SAMPLE_CPU),
1151 PERF_CONST(SAMPLE_PERIOD),
1152 PERF_CONST(SAMPLE_STREAM_ID),
1153 PERF_CONST(SAMPLE_RAW),
1155 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
1156 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
1157 PERF_CONST(FORMAT_ID),
1158 PERF_CONST(FORMAT_GROUP),
1160 PERF_CONST(RECORD_MMAP),
1161 PERF_CONST(RECORD_LOST),
1162 PERF_CONST(RECORD_COMM),
1163 PERF_CONST(RECORD_EXIT),
1164 PERF_CONST(RECORD_THROTTLE),
1165 PERF_CONST(RECORD_UNTHROTTLE),
1166 PERF_CONST(RECORD_FORK),
1167 PERF_CONST(RECORD_READ),
1168 PERF_CONST(RECORD_SAMPLE),
1169 PERF_CONST(RECORD_MMAP2),
1170 PERF_CONST(RECORD_AUX),
1171 PERF_CONST(RECORD_ITRACE_START),
1172 PERF_CONST(RECORD_LOST_SAMPLES),
1173 PERF_CONST(RECORD_SWITCH),
1174 PERF_CONST(RECORD_SWITCH_CPU_WIDE),
1176 PERF_CONST(RECORD_MISC_SWITCH_OUT),
1180 static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
1181 PyObject *args, PyObject *kwargs)
1183 struct event_format *tp_format;
1184 static char *kwlist[] = { "sys", "name", NULL };
1188 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
1192 tp_format = trace_event__tp_format(sys, name);
1193 if (IS_ERR(tp_format))
1194 return PyInt_FromLong(-1);
1196 return PyInt_FromLong(tp_format->id);
1199 static PyMethodDef perf__methods[] = {
1201 .ml_name = "tracepoint",
1202 .ml_meth = (PyCFunction) pyrf__tracepoint,
1203 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1204 .ml_doc = PyDoc_STR("Get tracepoint config.")
1206 { .ml_name = NULL, }
1209 PyMODINIT_FUNC initperf(void)
1213 PyObject *dict, *module = Py_InitModule("perf", perf__methods);
1215 if (module == NULL ||
1216 pyrf_event__setup_types() < 0 ||
1217 pyrf_evlist__setup_types() < 0 ||
1218 pyrf_evsel__setup_types() < 0 ||
1219 pyrf_thread_map__setup_types() < 0 ||
1220 pyrf_cpu_map__setup_types() < 0)
1223 /* The page_size is placed in util object. */
1224 page_size = sysconf(_SC_PAGE_SIZE);
1226 Py_INCREF(&pyrf_evlist__type);
1227 PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
1229 Py_INCREF(&pyrf_evsel__type);
1230 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1232 Py_INCREF(&pyrf_mmap_event__type);
1233 PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
1235 Py_INCREF(&pyrf_lost_event__type);
1236 PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
1238 Py_INCREF(&pyrf_comm_event__type);
1239 PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
1241 Py_INCREF(&pyrf_task_event__type);
1242 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1244 Py_INCREF(&pyrf_throttle_event__type);
1245 PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
1247 Py_INCREF(&pyrf_task_event__type);
1248 PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1250 Py_INCREF(&pyrf_read_event__type);
1251 PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
1253 Py_INCREF(&pyrf_sample_event__type);
1254 PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
1256 Py_INCREF(&pyrf_context_switch_event__type);
1257 PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
1259 Py_INCREF(&pyrf_thread_map__type);
1260 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1262 Py_INCREF(&pyrf_cpu_map__type);
1263 PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
1265 dict = PyModule_GetDict(module);
1269 for (i = 0; perf__constants[i].name != NULL; i++) {
1270 obj = PyInt_FromLong(perf__constants[i].value);
1273 PyDict_SetItemString(dict, perf__constants[i].name, obj);
1278 if (PyErr_Occurred())
1279 PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1283 * Dummy, to avoid dragging all the test_attr infrastructure in the python
1286 void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
1287 int fd, int group_fd, unsigned long flags)