2 #include <structmember.h>
9 #include "thread_map.h"
12 * Support debug printing even though util/debug.c is not linked. That means
13 * implementing 'verbose' and 'eprintf'.
17 int eprintf(int level
, int var
, const char *fmt
, ...)
24 ret
= vfprintf(stderr
, fmt
, args
);
31 /* Define PyVarObject_HEAD_INIT for python 2.5 */
32 #ifndef PyVarObject_HEAD_INIT
33 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
36 PyMODINIT_FUNC
initperf(void);
38 #define member_def(type, member, ptype, help) \
40 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
43 #define sample_member_def(name, member, ptype, help) \
45 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
50 struct perf_sample sample
;
51 union perf_event event
;
54 #define sample_members \
55 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
56 sample_member_def(sample_pid, pid, T_INT, "event pid"), \
57 sample_member_def(sample_tid, tid, T_INT, "event tid"), \
58 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
59 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
60 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
61 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
62 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
63 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
65 static char pyrf_mmap_event__doc
[] = PyDoc_STR("perf mmap event object.");
67 static PyMemberDef pyrf_mmap_event__members
[] = {
69 member_def(perf_event_header
, type
, T_UINT
, "event type"),
70 member_def(perf_event_header
, misc
, T_UINT
, "event misc"),
71 member_def(mmap_event
, pid
, T_UINT
, "event pid"),
72 member_def(mmap_event
, tid
, T_UINT
, "event tid"),
73 member_def(mmap_event
, start
, T_ULONGLONG
, "start of the map"),
74 member_def(mmap_event
, len
, T_ULONGLONG
, "map length"),
75 member_def(mmap_event
, pgoff
, T_ULONGLONG
, "page offset"),
76 member_def(mmap_event
, filename
, T_STRING_INPLACE
, "backing store"),
80 static PyObject
*pyrf_mmap_event__repr(struct pyrf_event
*pevent
)
85 if (asprintf(&s
, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64
", "
86 "length: %#" PRIx64
", offset: %#" PRIx64
", "
88 pevent
->event
.mmap
.pid
, pevent
->event
.mmap
.tid
,
89 pevent
->event
.mmap
.start
, pevent
->event
.mmap
.len
,
90 pevent
->event
.mmap
.pgoff
, pevent
->event
.mmap
.filename
) < 0) {
91 ret
= PyErr_NoMemory();
93 ret
= PyString_FromString(s
);
99 static PyTypeObject pyrf_mmap_event__type
= {
100 PyVarObject_HEAD_INIT(NULL
, 0)
101 .tp_name
= "perf.mmap_event",
102 .tp_basicsize
= sizeof(struct pyrf_event
),
103 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
104 .tp_doc
= pyrf_mmap_event__doc
,
105 .tp_members
= pyrf_mmap_event__members
,
106 .tp_repr
= (reprfunc
)pyrf_mmap_event__repr
,
109 static char pyrf_task_event__doc
[] = PyDoc_STR("perf task (fork/exit) event object.");
111 static PyMemberDef pyrf_task_event__members
[] = {
113 member_def(perf_event_header
, type
, T_UINT
, "event type"),
114 member_def(fork_event
, pid
, T_UINT
, "event pid"),
115 member_def(fork_event
, ppid
, T_UINT
, "event ppid"),
116 member_def(fork_event
, tid
, T_UINT
, "event tid"),
117 member_def(fork_event
, ptid
, T_UINT
, "event ptid"),
118 member_def(fork_event
, time
, T_ULONGLONG
, "timestamp"),
122 static PyObject
*pyrf_task_event__repr(struct pyrf_event
*pevent
)
124 return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
125 "ptid: %u, time: %" PRIu64
"}",
126 pevent
->event
.header
.type
== PERF_RECORD_FORK
? "fork" : "exit",
127 pevent
->event
.fork
.pid
,
128 pevent
->event
.fork
.ppid
,
129 pevent
->event
.fork
.tid
,
130 pevent
->event
.fork
.ptid
,
131 pevent
->event
.fork
.time
);
134 static PyTypeObject pyrf_task_event__type
= {
135 PyVarObject_HEAD_INIT(NULL
, 0)
136 .tp_name
= "perf.task_event",
137 .tp_basicsize
= sizeof(struct pyrf_event
),
138 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
139 .tp_doc
= pyrf_task_event__doc
,
140 .tp_members
= pyrf_task_event__members
,
141 .tp_repr
= (reprfunc
)pyrf_task_event__repr
,
144 static char pyrf_comm_event__doc
[] = PyDoc_STR("perf comm event object.");
146 static PyMemberDef pyrf_comm_event__members
[] = {
148 member_def(perf_event_header
, type
, T_UINT
, "event type"),
149 member_def(comm_event
, pid
, T_UINT
, "event pid"),
150 member_def(comm_event
, tid
, T_UINT
, "event tid"),
151 member_def(comm_event
, comm
, T_STRING_INPLACE
, "process name"),
155 static PyObject
*pyrf_comm_event__repr(struct pyrf_event
*pevent
)
157 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
158 pevent
->event
.comm
.pid
,
159 pevent
->event
.comm
.tid
,
160 pevent
->event
.comm
.comm
);
163 static PyTypeObject pyrf_comm_event__type
= {
164 PyVarObject_HEAD_INIT(NULL
, 0)
165 .tp_name
= "perf.comm_event",
166 .tp_basicsize
= sizeof(struct pyrf_event
),
167 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
168 .tp_doc
= pyrf_comm_event__doc
,
169 .tp_members
= pyrf_comm_event__members
,
170 .tp_repr
= (reprfunc
)pyrf_comm_event__repr
,
173 static char pyrf_throttle_event__doc
[] = PyDoc_STR("perf throttle event object.");
175 static PyMemberDef pyrf_throttle_event__members
[] = {
177 member_def(perf_event_header
, type
, T_UINT
, "event type"),
178 member_def(throttle_event
, time
, T_ULONGLONG
, "timestamp"),
179 member_def(throttle_event
, id
, T_ULONGLONG
, "event id"),
180 member_def(throttle_event
, stream_id
, T_ULONGLONG
, "event stream id"),
184 static PyObject
*pyrf_throttle_event__repr(struct pyrf_event
*pevent
)
186 struct throttle_event
*te
= (struct throttle_event
*)(&pevent
->event
.header
+ 1);
188 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64
", id: %" PRIu64
189 ", stream_id: %" PRIu64
" }",
190 pevent
->event
.header
.type
== PERF_RECORD_THROTTLE
? "" : "un",
191 te
->time
, te
->id
, te
->stream_id
);
194 static PyTypeObject pyrf_throttle_event__type
= {
195 PyVarObject_HEAD_INIT(NULL
, 0)
196 .tp_name
= "perf.throttle_event",
197 .tp_basicsize
= sizeof(struct pyrf_event
),
198 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
199 .tp_doc
= pyrf_throttle_event__doc
,
200 .tp_members
= pyrf_throttle_event__members
,
201 .tp_repr
= (reprfunc
)pyrf_throttle_event__repr
,
204 static char pyrf_lost_event__doc
[] = PyDoc_STR("perf lost event object.");
206 static PyMemberDef pyrf_lost_event__members
[] = {
208 member_def(lost_event
, id
, T_ULONGLONG
, "event id"),
209 member_def(lost_event
, lost
, T_ULONGLONG
, "number of lost events"),
213 static PyObject
*pyrf_lost_event__repr(struct pyrf_event
*pevent
)
218 if (asprintf(&s
, "{ type: lost, id: %#" PRIx64
", "
219 "lost: %#" PRIx64
" }",
220 pevent
->event
.lost
.id
, pevent
->event
.lost
.lost
) < 0) {
221 ret
= PyErr_NoMemory();
223 ret
= PyString_FromString(s
);
229 static PyTypeObject pyrf_lost_event__type
= {
230 PyVarObject_HEAD_INIT(NULL
, 0)
231 .tp_name
= "perf.lost_event",
232 .tp_basicsize
= sizeof(struct pyrf_event
),
233 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
234 .tp_doc
= pyrf_lost_event__doc
,
235 .tp_members
= pyrf_lost_event__members
,
236 .tp_repr
= (reprfunc
)pyrf_lost_event__repr
,
239 static char pyrf_read_event__doc
[] = PyDoc_STR("perf read event object.");
241 static PyMemberDef pyrf_read_event__members
[] = {
243 member_def(read_event
, pid
, T_UINT
, "event pid"),
244 member_def(read_event
, tid
, T_UINT
, "event tid"),
248 static PyObject
*pyrf_read_event__repr(struct pyrf_event
*pevent
)
250 return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
251 pevent
->event
.read
.pid
,
252 pevent
->event
.read
.tid
);
254 * FIXME: return the array of read values,
255 * making this method useful ;-)
259 static PyTypeObject pyrf_read_event__type
= {
260 PyVarObject_HEAD_INIT(NULL
, 0)
261 .tp_name
= "perf.read_event",
262 .tp_basicsize
= sizeof(struct pyrf_event
),
263 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
264 .tp_doc
= pyrf_read_event__doc
,
265 .tp_members
= pyrf_read_event__members
,
266 .tp_repr
= (reprfunc
)pyrf_read_event__repr
,
269 static char pyrf_sample_event__doc
[] = PyDoc_STR("perf sample event object.");
271 static PyMemberDef pyrf_sample_event__members
[] = {
273 member_def(perf_event_header
, type
, T_UINT
, "event type"),
277 static PyObject
*pyrf_sample_event__repr(struct pyrf_event
*pevent
)
282 if (asprintf(&s
, "{ type: sample }") < 0) {
283 ret
= PyErr_NoMemory();
285 ret
= PyString_FromString(s
);
291 static PyTypeObject pyrf_sample_event__type
= {
292 PyVarObject_HEAD_INIT(NULL
, 0)
293 .tp_name
= "perf.sample_event",
294 .tp_basicsize
= sizeof(struct pyrf_event
),
295 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
296 .tp_doc
= pyrf_sample_event__doc
,
297 .tp_members
= pyrf_sample_event__members
,
298 .tp_repr
= (reprfunc
)pyrf_sample_event__repr
,
301 static char pyrf_context_switch_event__doc
[] = PyDoc_STR("perf context_switch event object.");
303 static PyMemberDef pyrf_context_switch_event__members
[] = {
305 member_def(perf_event_header
, type
, T_UINT
, "event type"),
306 member_def(context_switch_event
, next_prev_pid
, T_UINT
, "next/prev pid"),
307 member_def(context_switch_event
, next_prev_tid
, T_UINT
, "next/prev tid"),
311 static PyObject
*pyrf_context_switch_event__repr(struct pyrf_event
*pevent
)
316 if (asprintf(&s
, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
317 pevent
->event
.context_switch
.next_prev_pid
,
318 pevent
->event
.context_switch
.next_prev_tid
,
319 !!(pevent
->event
.header
.misc
& PERF_RECORD_MISC_SWITCH_OUT
)) < 0) {
320 ret
= PyErr_NoMemory();
322 ret
= PyString_FromString(s
);
328 static PyTypeObject pyrf_context_switch_event__type
= {
329 PyVarObject_HEAD_INIT(NULL
, 0)
330 .tp_name
= "perf.context_switch_event",
331 .tp_basicsize
= sizeof(struct pyrf_event
),
332 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
333 .tp_doc
= pyrf_context_switch_event__doc
,
334 .tp_members
= pyrf_context_switch_event__members
,
335 .tp_repr
= (reprfunc
)pyrf_context_switch_event__repr
,
338 static int pyrf_event__setup_types(void)
341 pyrf_mmap_event__type
.tp_new
=
342 pyrf_task_event__type
.tp_new
=
343 pyrf_comm_event__type
.tp_new
=
344 pyrf_lost_event__type
.tp_new
=
345 pyrf_read_event__type
.tp_new
=
346 pyrf_sample_event__type
.tp_new
=
347 pyrf_context_switch_event__type
.tp_new
=
348 pyrf_throttle_event__type
.tp_new
= PyType_GenericNew
;
349 err
= PyType_Ready(&pyrf_mmap_event__type
);
352 err
= PyType_Ready(&pyrf_lost_event__type
);
355 err
= PyType_Ready(&pyrf_task_event__type
);
358 err
= PyType_Ready(&pyrf_comm_event__type
);
361 err
= PyType_Ready(&pyrf_throttle_event__type
);
364 err
= PyType_Ready(&pyrf_read_event__type
);
367 err
= PyType_Ready(&pyrf_sample_event__type
);
370 err
= PyType_Ready(&pyrf_context_switch_event__type
);
377 static PyTypeObject
*pyrf_event__type
[] = {
378 [PERF_RECORD_MMAP
] = &pyrf_mmap_event__type
,
379 [PERF_RECORD_LOST
] = &pyrf_lost_event__type
,
380 [PERF_RECORD_COMM
] = &pyrf_comm_event__type
,
381 [PERF_RECORD_EXIT
] = &pyrf_task_event__type
,
382 [PERF_RECORD_THROTTLE
] = &pyrf_throttle_event__type
,
383 [PERF_RECORD_UNTHROTTLE
] = &pyrf_throttle_event__type
,
384 [PERF_RECORD_FORK
] = &pyrf_task_event__type
,
385 [PERF_RECORD_READ
] = &pyrf_read_event__type
,
386 [PERF_RECORD_SAMPLE
] = &pyrf_sample_event__type
,
387 [PERF_RECORD_SWITCH
] = &pyrf_context_switch_event__type
,
388 [PERF_RECORD_SWITCH_CPU_WIDE
] = &pyrf_context_switch_event__type
,
391 static PyObject
*pyrf_event__new(union perf_event
*event
)
393 struct pyrf_event
*pevent
;
396 if ((event
->header
.type
< PERF_RECORD_MMAP
||
397 event
->header
.type
> PERF_RECORD_SAMPLE
) &&
398 !(event
->header
.type
== PERF_RECORD_SWITCH
||
399 event
->header
.type
== PERF_RECORD_SWITCH_CPU_WIDE
))
402 ptype
= pyrf_event__type
[event
->header
.type
];
403 pevent
= PyObject_New(struct pyrf_event
, ptype
);
405 memcpy(&pevent
->event
, event
, event
->header
.size
);
406 return (PyObject
*)pevent
;
409 struct pyrf_cpu_map
{
412 struct cpu_map
*cpus
;
415 static int pyrf_cpu_map__init(struct pyrf_cpu_map
*pcpus
,
416 PyObject
*args
, PyObject
*kwargs
)
418 static char *kwlist
[] = { "cpustr", NULL
};
421 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s",
425 pcpus
->cpus
= cpu_map__new(cpustr
);
426 if (pcpus
->cpus
== NULL
)
431 static void pyrf_cpu_map__delete(struct pyrf_cpu_map
*pcpus
)
433 cpu_map__put(pcpus
->cpus
);
434 pcpus
->ob_type
->tp_free((PyObject
*)pcpus
);
437 static Py_ssize_t
pyrf_cpu_map__length(PyObject
*obj
)
439 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
441 return pcpus
->cpus
->nr
;
444 static PyObject
*pyrf_cpu_map__item(PyObject
*obj
, Py_ssize_t i
)
446 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
448 if (i
>= pcpus
->cpus
->nr
)
451 return Py_BuildValue("i", pcpus
->cpus
->map
[i
]);
454 static PySequenceMethods pyrf_cpu_map__sequence_methods
= {
455 .sq_length
= pyrf_cpu_map__length
,
456 .sq_item
= pyrf_cpu_map__item
,
459 static char pyrf_cpu_map__doc
[] = PyDoc_STR("cpu map object.");
461 static PyTypeObject pyrf_cpu_map__type
= {
462 PyVarObject_HEAD_INIT(NULL
, 0)
463 .tp_name
= "perf.cpu_map",
464 .tp_basicsize
= sizeof(struct pyrf_cpu_map
),
465 .tp_dealloc
= (destructor
)pyrf_cpu_map__delete
,
466 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
467 .tp_doc
= pyrf_cpu_map__doc
,
468 .tp_as_sequence
= &pyrf_cpu_map__sequence_methods
,
469 .tp_init
= (initproc
)pyrf_cpu_map__init
,
472 static int pyrf_cpu_map__setup_types(void)
474 pyrf_cpu_map__type
.tp_new
= PyType_GenericNew
;
475 return PyType_Ready(&pyrf_cpu_map__type
);
478 struct pyrf_thread_map
{
481 struct thread_map
*threads
;
484 static int pyrf_thread_map__init(struct pyrf_thread_map
*pthreads
,
485 PyObject
*args
, PyObject
*kwargs
)
487 static char *kwlist
[] = { "pid", "tid", "uid", NULL
};
488 int pid
= -1, tid
= -1, uid
= UINT_MAX
;
490 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iii",
491 kwlist
, &pid
, &tid
, &uid
))
494 pthreads
->threads
= thread_map__new(pid
, tid
, uid
);
495 if (pthreads
->threads
== NULL
)
500 static void pyrf_thread_map__delete(struct pyrf_thread_map
*pthreads
)
502 thread_map__put(pthreads
->threads
);
503 pthreads
->ob_type
->tp_free((PyObject
*)pthreads
);
506 static Py_ssize_t
pyrf_thread_map__length(PyObject
*obj
)
508 struct pyrf_thread_map
*pthreads
= (void *)obj
;
510 return pthreads
->threads
->nr
;
513 static PyObject
*pyrf_thread_map__item(PyObject
*obj
, Py_ssize_t i
)
515 struct pyrf_thread_map
*pthreads
= (void *)obj
;
517 if (i
>= pthreads
->threads
->nr
)
520 return Py_BuildValue("i", pthreads
->threads
->map
[i
]);
523 static PySequenceMethods pyrf_thread_map__sequence_methods
= {
524 .sq_length
= pyrf_thread_map__length
,
525 .sq_item
= pyrf_thread_map__item
,
528 static char pyrf_thread_map__doc
[] = PyDoc_STR("thread map object.");
530 static PyTypeObject pyrf_thread_map__type
= {
531 PyVarObject_HEAD_INIT(NULL
, 0)
532 .tp_name
= "perf.thread_map",
533 .tp_basicsize
= sizeof(struct pyrf_thread_map
),
534 .tp_dealloc
= (destructor
)pyrf_thread_map__delete
,
535 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
536 .tp_doc
= pyrf_thread_map__doc
,
537 .tp_as_sequence
= &pyrf_thread_map__sequence_methods
,
538 .tp_init
= (initproc
)pyrf_thread_map__init
,
541 static int pyrf_thread_map__setup_types(void)
543 pyrf_thread_map__type
.tp_new
= PyType_GenericNew
;
544 return PyType_Ready(&pyrf_thread_map__type
);
550 struct perf_evsel evsel
;
553 static int pyrf_evsel__init(struct pyrf_evsel
*pevsel
,
554 PyObject
*args
, PyObject
*kwargs
)
556 struct perf_event_attr attr
= {
557 .type
= PERF_TYPE_HARDWARE
,
558 .config
= PERF_COUNT_HW_CPU_CYCLES
,
559 .sample_type
= PERF_SAMPLE_PERIOD
| PERF_SAMPLE_TID
,
561 static char *kwlist
[] = {
593 u64 sample_period
= 0;
615 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
616 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist
,
617 &attr
.type
, &attr
.config
, &attr
.sample_freq
,
618 &sample_period
, &attr
.sample_type
,
619 &attr
.read_format
, &disabled
, &inherit
,
620 &pinned
, &exclusive
, &exclude_user
,
621 &exclude_kernel
, &exclude_hv
, &exclude_idle
,
622 &mmap
, &context_switch
, &comm
, &freq
, &inherit_stat
,
623 &enable_on_exec
, &task
, &watermark
,
624 &precise_ip
, &mmap_data
, &sample_id_all
,
625 &attr
.wakeup_events
, &attr
.bp_type
,
626 &attr
.bp_addr
, &attr
.bp_len
, &idx
))
630 if (sample_period
!= 0) {
631 if (attr
.sample_freq
!= 0)
632 return -1; /* FIXME: throw right exception */
633 attr
.sample_period
= sample_period
;
637 attr
.disabled
= disabled
;
638 attr
.inherit
= inherit
;
639 attr
.pinned
= pinned
;
640 attr
.exclusive
= exclusive
;
641 attr
.exclude_user
= exclude_user
;
642 attr
.exclude_kernel
= exclude_kernel
;
643 attr
.exclude_hv
= exclude_hv
;
644 attr
.exclude_idle
= exclude_idle
;
646 attr
.context_switch
= context_switch
;
649 attr
.inherit_stat
= inherit_stat
;
650 attr
.enable_on_exec
= enable_on_exec
;
652 attr
.watermark
= watermark
;
653 attr
.precise_ip
= precise_ip
;
654 attr
.mmap_data
= mmap_data
;
655 attr
.sample_id_all
= sample_id_all
;
657 perf_evsel__init(&pevsel
->evsel
, &attr
, idx
);
661 static void pyrf_evsel__delete(struct pyrf_evsel
*pevsel
)
663 perf_evsel__exit(&pevsel
->evsel
);
664 pevsel
->ob_type
->tp_free((PyObject
*)pevsel
);
667 static PyObject
*pyrf_evsel__open(struct pyrf_evsel
*pevsel
,
668 PyObject
*args
, PyObject
*kwargs
)
670 struct perf_evsel
*evsel
= &pevsel
->evsel
;
671 struct cpu_map
*cpus
= NULL
;
672 struct thread_map
*threads
= NULL
;
673 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
674 int group
= 0, inherit
= 0;
675 static char *kwlist
[] = { "cpus", "threads", "group", "inherit", NULL
};
677 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOii", kwlist
,
678 &pcpus
, &pthreads
, &group
, &inherit
))
681 if (pthreads
!= NULL
)
682 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
685 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
687 evsel
->attr
.inherit
= inherit
;
689 * This will group just the fds for this single evsel, to group
690 * multiple events, use evlist.open().
692 if (perf_evsel__open(evsel
, cpus
, threads
) < 0) {
693 PyErr_SetFromErrno(PyExc_OSError
);
701 static PyMethodDef pyrf_evsel__methods
[] = {
704 .ml_meth
= (PyCFunction
)pyrf_evsel__open
,
705 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
706 .ml_doc
= PyDoc_STR("open the event selector file descriptor table.")
711 static char pyrf_evsel__doc
[] = PyDoc_STR("perf event selector list object.");
713 static PyTypeObject pyrf_evsel__type
= {
714 PyVarObject_HEAD_INIT(NULL
, 0)
715 .tp_name
= "perf.evsel",
716 .tp_basicsize
= sizeof(struct pyrf_evsel
),
717 .tp_dealloc
= (destructor
)pyrf_evsel__delete
,
718 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
719 .tp_doc
= pyrf_evsel__doc
,
720 .tp_methods
= pyrf_evsel__methods
,
721 .tp_init
= (initproc
)pyrf_evsel__init
,
724 static int pyrf_evsel__setup_types(void)
726 pyrf_evsel__type
.tp_new
= PyType_GenericNew
;
727 return PyType_Ready(&pyrf_evsel__type
);
733 struct perf_evlist evlist
;
736 static int pyrf_evlist__init(struct pyrf_evlist
*pevlist
,
737 PyObject
*args
, PyObject
*kwargs __maybe_unused
)
739 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
740 struct cpu_map
*cpus
;
741 struct thread_map
*threads
;
743 if (!PyArg_ParseTuple(args
, "OO", &pcpus
, &pthreads
))
746 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
747 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
748 perf_evlist__init(&pevlist
->evlist
, cpus
, threads
);
752 static void pyrf_evlist__delete(struct pyrf_evlist
*pevlist
)
754 perf_evlist__exit(&pevlist
->evlist
);
755 pevlist
->ob_type
->tp_free((PyObject
*)pevlist
);
758 static PyObject
*pyrf_evlist__mmap(struct pyrf_evlist
*pevlist
,
759 PyObject
*args
, PyObject
*kwargs
)
761 struct perf_evlist
*evlist
= &pevlist
->evlist
;
762 static char *kwlist
[] = { "pages", "overwrite", NULL
};
763 int pages
= 128, overwrite
= false;
765 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ii", kwlist
,
769 if (perf_evlist__mmap(evlist
, pages
, overwrite
) < 0) {
770 PyErr_SetFromErrno(PyExc_OSError
);
778 static PyObject
*pyrf_evlist__poll(struct pyrf_evlist
*pevlist
,
779 PyObject
*args
, PyObject
*kwargs
)
781 struct perf_evlist
*evlist
= &pevlist
->evlist
;
782 static char *kwlist
[] = { "timeout", NULL
};
785 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i", kwlist
, &timeout
))
788 n
= perf_evlist__poll(evlist
, timeout
);
790 PyErr_SetFromErrno(PyExc_OSError
);
794 return Py_BuildValue("i", n
);
797 static PyObject
*pyrf_evlist__get_pollfd(struct pyrf_evlist
*pevlist
,
798 PyObject
*args __maybe_unused
,
799 PyObject
*kwargs __maybe_unused
)
801 struct perf_evlist
*evlist
= &pevlist
->evlist
;
802 PyObject
*list
= PyList_New(0);
805 for (i
= 0; i
< evlist
->pollfd
.nr
; ++i
) {
807 FILE *fp
= fdopen(evlist
->pollfd
.entries
[i
].fd
, "r");
812 file
= PyFile_FromFile(fp
, "perf", "r", NULL
);
816 if (PyList_Append(list
, file
) != 0) {
826 return PyErr_NoMemory();
830 static PyObject
*pyrf_evlist__add(struct pyrf_evlist
*pevlist
,
832 PyObject
*kwargs __maybe_unused
)
834 struct perf_evlist
*evlist
= &pevlist
->evlist
;
836 struct perf_evsel
*evsel
;
838 if (!PyArg_ParseTuple(args
, "O", &pevsel
))
842 evsel
= &((struct pyrf_evsel
*)pevsel
)->evsel
;
843 evsel
->idx
= evlist
->nr_entries
;
844 perf_evlist__add(evlist
, evsel
);
846 return Py_BuildValue("i", evlist
->nr_entries
);
849 static PyObject
*pyrf_evlist__read_on_cpu(struct pyrf_evlist
*pevlist
,
850 PyObject
*args
, PyObject
*kwargs
)
852 struct perf_evlist
*evlist
= &pevlist
->evlist
;
853 union perf_event
*event
;
854 int sample_id_all
= 1, cpu
;
855 static char *kwlist
[] = { "cpu", "sample_id_all", NULL
};
858 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|i", kwlist
,
859 &cpu
, &sample_id_all
))
862 event
= perf_evlist__mmap_read(evlist
, cpu
);
864 PyObject
*pyevent
= pyrf_event__new(event
);
865 struct pyrf_event
*pevent
= (struct pyrf_event
*)pyevent
;
867 perf_evlist__mmap_consume(evlist
, cpu
);
870 return PyErr_NoMemory();
872 err
= perf_evlist__parse_sample(evlist
, event
, &pevent
->sample
);
874 return PyErr_Format(PyExc_OSError
,
875 "perf: can't parse sample, err=%d", err
);
883 static PyObject
*pyrf_evlist__open(struct pyrf_evlist
*pevlist
,
884 PyObject
*args
, PyObject
*kwargs
)
886 struct perf_evlist
*evlist
= &pevlist
->evlist
;
888 static char *kwlist
[] = { "group", NULL
};
890 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOii", kwlist
, &group
))
894 perf_evlist__set_leader(evlist
);
896 if (perf_evlist__open(evlist
) < 0) {
897 PyErr_SetFromErrno(PyExc_OSError
);
905 static PyMethodDef pyrf_evlist__methods
[] = {
908 .ml_meth
= (PyCFunction
)pyrf_evlist__mmap
,
909 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
910 .ml_doc
= PyDoc_STR("mmap the file descriptor table.")
914 .ml_meth
= (PyCFunction
)pyrf_evlist__open
,
915 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
916 .ml_doc
= PyDoc_STR("open the file descriptors.")
920 .ml_meth
= (PyCFunction
)pyrf_evlist__poll
,
921 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
922 .ml_doc
= PyDoc_STR("poll the file descriptor table.")
925 .ml_name
= "get_pollfd",
926 .ml_meth
= (PyCFunction
)pyrf_evlist__get_pollfd
,
927 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
928 .ml_doc
= PyDoc_STR("get the poll file descriptor table.")
932 .ml_meth
= (PyCFunction
)pyrf_evlist__add
,
933 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
934 .ml_doc
= PyDoc_STR("adds an event selector to the list.")
937 .ml_name
= "read_on_cpu",
938 .ml_meth
= (PyCFunction
)pyrf_evlist__read_on_cpu
,
939 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
940 .ml_doc
= PyDoc_STR("reads an event.")
945 static Py_ssize_t
pyrf_evlist__length(PyObject
*obj
)
947 struct pyrf_evlist
*pevlist
= (void *)obj
;
949 return pevlist
->evlist
.nr_entries
;
952 static PyObject
*pyrf_evlist__item(PyObject
*obj
, Py_ssize_t i
)
954 struct pyrf_evlist
*pevlist
= (void *)obj
;
955 struct perf_evsel
*pos
;
957 if (i
>= pevlist
->evlist
.nr_entries
)
960 evlist__for_each(&pevlist
->evlist
, pos
) {
965 return Py_BuildValue("O", container_of(pos
, struct pyrf_evsel
, evsel
));
968 static PySequenceMethods pyrf_evlist__sequence_methods
= {
969 .sq_length
= pyrf_evlist__length
,
970 .sq_item
= pyrf_evlist__item
,
973 static char pyrf_evlist__doc
[] = PyDoc_STR("perf event selector list object.");
975 static PyTypeObject pyrf_evlist__type
= {
976 PyVarObject_HEAD_INIT(NULL
, 0)
977 .tp_name
= "perf.evlist",
978 .tp_basicsize
= sizeof(struct pyrf_evlist
),
979 .tp_dealloc
= (destructor
)pyrf_evlist__delete
,
980 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
981 .tp_as_sequence
= &pyrf_evlist__sequence_methods
,
982 .tp_doc
= pyrf_evlist__doc
,
983 .tp_methods
= pyrf_evlist__methods
,
984 .tp_init
= (initproc
)pyrf_evlist__init
,
987 static int pyrf_evlist__setup_types(void)
989 pyrf_evlist__type
.tp_new
= PyType_GenericNew
;
990 return PyType_Ready(&pyrf_evlist__type
);
993 #define PERF_CONST(name) { #name, PERF_##name }
998 } perf__constants
[] = {
999 PERF_CONST(TYPE_HARDWARE
),
1000 PERF_CONST(TYPE_SOFTWARE
),
1001 PERF_CONST(TYPE_TRACEPOINT
),
1002 PERF_CONST(TYPE_HW_CACHE
),
1003 PERF_CONST(TYPE_RAW
),
1004 PERF_CONST(TYPE_BREAKPOINT
),
1006 PERF_CONST(COUNT_HW_CPU_CYCLES
),
1007 PERF_CONST(COUNT_HW_INSTRUCTIONS
),
1008 PERF_CONST(COUNT_HW_CACHE_REFERENCES
),
1009 PERF_CONST(COUNT_HW_CACHE_MISSES
),
1010 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS
),
1011 PERF_CONST(COUNT_HW_BRANCH_MISSES
),
1012 PERF_CONST(COUNT_HW_BUS_CYCLES
),
1013 PERF_CONST(COUNT_HW_CACHE_L1D
),
1014 PERF_CONST(COUNT_HW_CACHE_L1I
),
1015 PERF_CONST(COUNT_HW_CACHE_LL
),
1016 PERF_CONST(COUNT_HW_CACHE_DTLB
),
1017 PERF_CONST(COUNT_HW_CACHE_ITLB
),
1018 PERF_CONST(COUNT_HW_CACHE_BPU
),
1019 PERF_CONST(COUNT_HW_CACHE_OP_READ
),
1020 PERF_CONST(COUNT_HW_CACHE_OP_WRITE
),
1021 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH
),
1022 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS
),
1023 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS
),
1025 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND
),
1026 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND
),
1028 PERF_CONST(COUNT_SW_CPU_CLOCK
),
1029 PERF_CONST(COUNT_SW_TASK_CLOCK
),
1030 PERF_CONST(COUNT_SW_PAGE_FAULTS
),
1031 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES
),
1032 PERF_CONST(COUNT_SW_CPU_MIGRATIONS
),
1033 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN
),
1034 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ
),
1035 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS
),
1036 PERF_CONST(COUNT_SW_EMULATION_FAULTS
),
1037 PERF_CONST(COUNT_SW_DUMMY
),
1039 PERF_CONST(SAMPLE_IP
),
1040 PERF_CONST(SAMPLE_TID
),
1041 PERF_CONST(SAMPLE_TIME
),
1042 PERF_CONST(SAMPLE_ADDR
),
1043 PERF_CONST(SAMPLE_READ
),
1044 PERF_CONST(SAMPLE_CALLCHAIN
),
1045 PERF_CONST(SAMPLE_ID
),
1046 PERF_CONST(SAMPLE_CPU
),
1047 PERF_CONST(SAMPLE_PERIOD
),
1048 PERF_CONST(SAMPLE_STREAM_ID
),
1049 PERF_CONST(SAMPLE_RAW
),
1051 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED
),
1052 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING
),
1053 PERF_CONST(FORMAT_ID
),
1054 PERF_CONST(FORMAT_GROUP
),
1056 PERF_CONST(RECORD_MMAP
),
1057 PERF_CONST(RECORD_LOST
),
1058 PERF_CONST(RECORD_COMM
),
1059 PERF_CONST(RECORD_EXIT
),
1060 PERF_CONST(RECORD_THROTTLE
),
1061 PERF_CONST(RECORD_UNTHROTTLE
),
1062 PERF_CONST(RECORD_FORK
),
1063 PERF_CONST(RECORD_READ
),
1064 PERF_CONST(RECORD_SAMPLE
),
1065 PERF_CONST(RECORD_MMAP2
),
1066 PERF_CONST(RECORD_AUX
),
1067 PERF_CONST(RECORD_ITRACE_START
),
1068 PERF_CONST(RECORD_LOST_SAMPLES
),
1069 PERF_CONST(RECORD_SWITCH
),
1070 PERF_CONST(RECORD_SWITCH_CPU_WIDE
),
1072 PERF_CONST(RECORD_MISC_SWITCH_OUT
),
1076 static PyMethodDef perf__methods
[] = {
1077 { .ml_name
= NULL
, }
1080 PyMODINIT_FUNC
initperf(void)
1084 PyObject
*dict
, *module
= Py_InitModule("perf", perf__methods
);
1086 if (module
== NULL
||
1087 pyrf_event__setup_types() < 0 ||
1088 pyrf_evlist__setup_types() < 0 ||
1089 pyrf_evsel__setup_types() < 0 ||
1090 pyrf_thread_map__setup_types() < 0 ||
1091 pyrf_cpu_map__setup_types() < 0)
1094 /* The page_size is placed in util object. */
1095 page_size
= sysconf(_SC_PAGE_SIZE
);
1097 Py_INCREF(&pyrf_evlist__type
);
1098 PyModule_AddObject(module
, "evlist", (PyObject
*)&pyrf_evlist__type
);
1100 Py_INCREF(&pyrf_evsel__type
);
1101 PyModule_AddObject(module
, "evsel", (PyObject
*)&pyrf_evsel__type
);
1103 Py_INCREF(&pyrf_thread_map__type
);
1104 PyModule_AddObject(module
, "thread_map", (PyObject
*)&pyrf_thread_map__type
);
1106 Py_INCREF(&pyrf_cpu_map__type
);
1107 PyModule_AddObject(module
, "cpu_map", (PyObject
*)&pyrf_cpu_map__type
);
1109 dict
= PyModule_GetDict(module
);
1113 for (i
= 0; perf__constants
[i
].name
!= NULL
; i
++) {
1114 obj
= PyInt_FromLong(perf__constants
[i
].value
);
1117 PyDict_SetItemString(dict
, perf__constants
[i
].name
, obj
);
1122 if (PyErr_Occurred())
1123 PyErr_SetString(PyExc_ImportError
, "perf: Init failed!");
1127 * Dummy, to avoid dragging all the test_attr infrastructure in the python
1130 void test_attr__open(struct perf_event_attr
*attr
, pid_t pid
, int cpu
,
1131 int fd
, int group_fd
, unsigned long flags
)