2 #include <structmember.h>
9 #include "thread_map.h"
11 /* Define PyVarObject_HEAD_INIT for python 2.5 */
12 #ifndef PyVarObject_HEAD_INIT
13 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
16 struct throttle_event
{
17 struct perf_event_header header
;
23 PyMODINIT_FUNC
initperf(void);
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), \
37 struct perf_sample sample
;
38 union perf_event event
;
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
[] = {
56 member_def(perf_event_header
, type
, T_UINT
, "event type"),
57 member_def(mmap_event
, pid
, T_UINT
, "event pid"),
58 member_def(mmap_event
, tid
, T_UINT
, "event tid"),
59 member_def(mmap_event
, start
, T_ULONGLONG
, "start of the map"),
60 member_def(mmap_event
, len
, T_ULONGLONG
, "map length"),
61 member_def(mmap_event
, pgoff
, T_ULONGLONG
, "page offset"),
62 member_def(mmap_event
, filename
, T_STRING_INPLACE
, "backing store"),
66 static PyObject
*pyrf_mmap_event__repr(struct pyrf_event
*pevent
)
71 if (asprintf(&s
, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64
", "
72 "length: %#" PRIx64
", offset: %#" PRIx64
", "
74 pevent
->event
.mmap
.pid
, pevent
->event
.mmap
.tid
,
75 pevent
->event
.mmap
.start
, pevent
->event
.mmap
.len
,
76 pevent
->event
.mmap
.pgoff
, pevent
->event
.mmap
.filename
) < 0) {
77 ret
= PyErr_NoMemory();
79 ret
= PyString_FromString(s
);
85 static PyTypeObject pyrf_mmap_event__type
= {
86 PyVarObject_HEAD_INIT(NULL
, 0)
87 .tp_name
= "perf.mmap_event",
88 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
99 member_def(perf_event_header
, type
, T_UINT
, "event type"),
100 member_def(fork_event
, pid
, T_UINT
, "event pid"),
101 member_def(fork_event
, ppid
, T_UINT
, "event ppid"),
102 member_def(fork_event
, tid
, T_UINT
, "event tid"),
103 member_def(fork_event
, ptid
, T_UINT
, "event ptid"),
104 member_def(fork_event
, time
, T_ULONGLONG
, "timestamp"),
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
"}",
112 pevent
->event
.header
.type
== PERF_RECORD_FORK
? "fork" : "exit",
113 pevent
->event
.fork
.pid
,
114 pevent
->event
.fork
.ppid
,
115 pevent
->event
.fork
.tid
,
116 pevent
->event
.fork
.ptid
,
117 pevent
->event
.fork
.time
);
120 static PyTypeObject pyrf_task_event__type
= {
121 PyVarObject_HEAD_INIT(NULL
, 0)
122 .tp_name
= "perf.task_event",
123 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
134 member_def(perf_event_header
, type
, T_UINT
, "event type"),
135 member_def(comm_event
, pid
, T_UINT
, "event pid"),
136 member_def(comm_event
, tid
, T_UINT
, "event tid"),
137 member_def(comm_event
, comm
, T_STRING_INPLACE
, "process name"),
141 static PyObject
*pyrf_comm_event__repr(struct pyrf_event
*pevent
)
143 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
144 pevent
->event
.comm
.pid
,
145 pevent
->event
.comm
.tid
,
146 pevent
->event
.comm
.comm
);
149 static PyTypeObject pyrf_comm_event__type
= {
150 PyVarObject_HEAD_INIT(NULL
, 0)
151 .tp_name
= "perf.comm_event",
152 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
163 member_def(perf_event_header
, type
, T_UINT
, "event type"),
164 member_def(throttle_event
, time
, T_ULONGLONG
, "timestamp"),
165 member_def(throttle_event
, id
, T_ULONGLONG
, "event id"),
166 member_def(throttle_event
, stream_id
, T_ULONGLONG
, "event stream id"),
170 static PyObject
*pyrf_throttle_event__repr(struct pyrf_event
*pevent
)
172 struct throttle_event
*te
= (struct throttle_event
*)(&pevent
->event
.header
+ 1);
174 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64
", id: %" PRIu64
175 ", stream_id: %" PRIu64
" }",
176 pevent
->event
.header
.type
== PERF_RECORD_THROTTLE
? "" : "un",
177 te
->time
, te
->id
, te
->stream_id
);
180 static PyTypeObject pyrf_throttle_event__type
= {
181 PyVarObject_HEAD_INIT(NULL
, 0)
182 .tp_name
= "perf.throttle_event",
183 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
194 member_def(lost_event
, id
, T_ULONGLONG
, "event id"),
195 member_def(lost_event
, lost
, T_ULONGLONG
, "number of lost events"),
199 static PyObject
*pyrf_lost_event__repr(struct pyrf_event
*pevent
)
204 if (asprintf(&s
, "{ type: lost, id: %#" PRIx64
", "
205 "lost: %#" PRIx64
" }",
206 pevent
->event
.lost
.id
, pevent
->event
.lost
.lost
) < 0) {
207 ret
= PyErr_NoMemory();
209 ret
= PyString_FromString(s
);
215 static PyTypeObject pyrf_lost_event__type
= {
216 PyVarObject_HEAD_INIT(NULL
, 0)
217 .tp_name
= "perf.lost_event",
218 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
229 member_def(read_event
, pid
, T_UINT
, "event pid"),
230 member_def(read_event
, tid
, T_UINT
, "event tid"),
234 static PyObject
*pyrf_read_event__repr(struct pyrf_event
*pevent
)
236 return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
237 pevent
->event
.read
.pid
,
238 pevent
->event
.read
.tid
);
240 * FIXME: return the array of read values,
241 * making this method useful ;-)
245 static PyTypeObject pyrf_read_event__type
= {
246 PyVarObject_HEAD_INIT(NULL
, 0)
247 .tp_name
= "perf.read_event",
248 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
259 member_def(perf_event_header
, type
, T_UINT
, "event type"),
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
= {
278 PyVarObject_HEAD_INIT(NULL
, 0)
279 .tp_name
= "perf.sample_event",
280 .tp_basicsize
= sizeof(struct pyrf_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
[] = {
323 [PERF_RECORD_MMAP
] = &pyrf_mmap_event__type
,
324 [PERF_RECORD_LOST
] = &pyrf_lost_event__type
,
325 [PERF_RECORD_COMM
] = &pyrf_comm_event__type
,
326 [PERF_RECORD_EXIT
] = &pyrf_task_event__type
,
327 [PERF_RECORD_THROTTLE
] = &pyrf_throttle_event__type
,
328 [PERF_RECORD_UNTHROTTLE
] = &pyrf_throttle_event__type
,
329 [PERF_RECORD_FORK
] = &pyrf_task_event__type
,
330 [PERF_RECORD_READ
] = &pyrf_read_event__type
,
331 [PERF_RECORD_SAMPLE
] = &pyrf_sample_event__type
,
334 static PyObject
*pyrf_event__new(union perf_event
*event
)
336 struct pyrf_event
*pevent
;
339 if (event
->header
.type
< PERF_RECORD_MMAP
||
340 event
->header
.type
> PERF_RECORD_SAMPLE
)
343 ptype
= pyrf_event__type
[event
->header
.type
];
344 pevent
= PyObject_New(struct pyrf_event
, ptype
);
346 memcpy(&pevent
->event
, event
, event
->header
.size
);
347 return (PyObject
*)pevent
;
350 struct pyrf_cpu_map
{
353 struct cpu_map
*cpus
;
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",
366 pcpus
->cpus
= cpu_map__new(cpustr
);
367 if (pcpus
->cpus
== NULL
)
372 static void pyrf_cpu_map__delete(struct pyrf_cpu_map
*pcpus
)
374 cpu_map__delete(pcpus
->cpus
);
375 pcpus
->ob_type
->tp_free((PyObject
*)pcpus
);
378 static Py_ssize_t
pyrf_cpu_map__length(PyObject
*obj
)
380 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
382 return pcpus
->cpus
->nr
;
385 static PyObject
*pyrf_cpu_map__item(PyObject
*obj
, Py_ssize_t i
)
387 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
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
= {
403 PyVarObject_HEAD_INIT(NULL
, 0)
404 .tp_name
= "perf.cpu_map",
405 .tp_basicsize
= sizeof(struct pyrf_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
);
419 struct pyrf_thread_map
{
422 struct thread_map
*threads
;
425 static int pyrf_thread_map__init(struct pyrf_thread_map
*pthreads
,
426 PyObject
*args
, PyObject
*kwargs
)
428 static char *kwlist
[] = { "pid", "tid", NULL
};
429 int pid
= -1, tid
= -1;
431 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ii",
435 pthreads
->threads
= thread_map__new(pid
, tid
);
436 if (pthreads
->threads
== NULL
)
441 static void pyrf_thread_map__delete(struct pyrf_thread_map
*pthreads
)
443 thread_map__delete(pthreads
->threads
);
444 pthreads
->ob_type
->tp_free((PyObject
*)pthreads
);
447 static Py_ssize_t
pyrf_thread_map__length(PyObject
*obj
)
449 struct pyrf_thread_map
*pthreads
= (void *)obj
;
451 return pthreads
->threads
->nr
;
454 static PyObject
*pyrf_thread_map__item(PyObject
*obj
, Py_ssize_t i
)
456 struct pyrf_thread_map
*pthreads
= (void *)obj
;
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
= {
472 PyVarObject_HEAD_INIT(NULL
, 0)
473 .tp_name
= "perf.thread_map",
474 .tp_basicsize
= sizeof(struct pyrf_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
);
491 struct perf_evsel evsel
;
494 static int pyrf_evsel__init(struct pyrf_evsel
*pevsel
,
495 PyObject
*args
, PyObject
*kwargs
)
497 struct perf_event_attr attr
= {
498 .type
= PERF_TYPE_HARDWARE
,
499 .config
= PERF_COUNT_HW_CPU_CYCLES
,
500 .sample_type
= PERF_SAMPLE_PERIOD
| PERF_SAMPLE_TID
,
502 static char *kwlist
[] = {
533 u64 sample_period
= 0;
554 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
555 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist
,
556 &attr
.type
, &attr
.config
, &attr
.sample_freq
,
557 &sample_period
, &attr
.sample_type
,
558 &attr
.read_format
, &disabled
, &inherit
,
559 &pinned
, &exclusive
, &exclude_user
,
560 &exclude_kernel
, &exclude_hv
, &exclude_idle
,
561 &mmap
, &comm
, &freq
, &inherit_stat
,
562 &enable_on_exec
, &task
, &watermark
,
563 &precise_ip
, &mmap_data
, &sample_id_all
,
564 &attr
.wakeup_events
, &attr
.bp_type
,
565 &attr
.bp_addr
, &attr
.bp_len
, &idx
))
569 if (sample_period
!= 0) {
570 if (attr
.sample_freq
!= 0)
571 return -1; /* FIXME: throw right exception */
572 attr
.sample_period
= sample_period
;
576 attr
.disabled
= disabled
;
577 attr
.inherit
= inherit
;
578 attr
.pinned
= pinned
;
579 attr
.exclusive
= exclusive
;
580 attr
.exclude_user
= exclude_user
;
581 attr
.exclude_kernel
= exclude_kernel
;
582 attr
.exclude_hv
= exclude_hv
;
583 attr
.exclude_idle
= exclude_idle
;
587 attr
.inherit_stat
= inherit_stat
;
588 attr
.enable_on_exec
= enable_on_exec
;
590 attr
.watermark
= watermark
;
591 attr
.precise_ip
= precise_ip
;
592 attr
.mmap_data
= mmap_data
;
593 attr
.sample_id_all
= sample_id_all
;
595 perf_evsel__init(&pevsel
->evsel
, &attr
, idx
);
599 static void pyrf_evsel__delete(struct pyrf_evsel
*pevsel
)
601 perf_evsel__exit(&pevsel
->evsel
);
602 pevsel
->ob_type
->tp_free((PyObject
*)pevsel
);
605 static PyObject
*pyrf_evsel__open(struct pyrf_evsel
*pevsel
,
606 PyObject
*args
, PyObject
*kwargs
)
608 struct perf_evsel
*evsel
= &pevsel
->evsel
;
609 struct cpu_map
*cpus
= NULL
;
610 struct thread_map
*threads
= NULL
;
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
)
620 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
623 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
625 evsel
->attr
.inherit
= inherit
;
626 if (perf_evsel__open(evsel
, cpus
, threads
, group
) < 0) {
627 PyErr_SetFromErrno(PyExc_OSError
);
635 static PyMethodDef pyrf_evsel__methods
[] = {
638 .ml_meth
= (PyCFunction
)pyrf_evsel__open
,
639 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
640 .ml_doc
= PyDoc_STR("open the event selector file descriptor table.")
645 static char pyrf_evsel__doc
[] = PyDoc_STR("perf event selector list object.");
647 static PyTypeObject pyrf_evsel__type
= {
648 PyVarObject_HEAD_INIT(NULL
, 0)
649 .tp_name
= "perf.evsel",
650 .tp_basicsize
= sizeof(struct pyrf_evsel
),
651 .tp_dealloc
= (destructor
)pyrf_evsel__delete
,
652 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
653 .tp_doc
= pyrf_evsel__doc
,
654 .tp_methods
= pyrf_evsel__methods
,
655 .tp_init
= (initproc
)pyrf_evsel__init
,
658 static int pyrf_evsel__setup_types(void)
660 pyrf_evsel__type
.tp_new
= PyType_GenericNew
;
661 return PyType_Ready(&pyrf_evsel__type
);
667 struct perf_evlist evlist
;
670 static int pyrf_evlist__init(struct pyrf_evlist
*pevlist
,
671 PyObject
*args
, PyObject
*kwargs __used
)
673 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
674 struct cpu_map
*cpus
;
675 struct thread_map
*threads
;
677 if (!PyArg_ParseTuple(args
, "OO", &pcpus
, &pthreads
))
680 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
681 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
682 perf_evlist__init(&pevlist
->evlist
, cpus
, threads
);
686 static void pyrf_evlist__delete(struct pyrf_evlist
*pevlist
)
688 perf_evlist__exit(&pevlist
->evlist
);
689 pevlist
->ob_type
->tp_free((PyObject
*)pevlist
);
692 static PyObject
*pyrf_evlist__mmap(struct pyrf_evlist
*pevlist
,
693 PyObject
*args
, PyObject
*kwargs
)
695 struct perf_evlist
*evlist
= &pevlist
->evlist
;
696 static char *kwlist
[] = { "pages", "overwrite", NULL
};
697 int pages
= 128, overwrite
= false;
699 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ii", kwlist
,
703 if (perf_evlist__mmap(evlist
, pages
, overwrite
) < 0) {
704 PyErr_SetFromErrno(PyExc_OSError
);
712 static PyObject
*pyrf_evlist__poll(struct pyrf_evlist
*pevlist
,
713 PyObject
*args
, PyObject
*kwargs
)
715 struct perf_evlist
*evlist
= &pevlist
->evlist
;
716 static char *kwlist
[] = { "timeout", NULL
};
719 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i", kwlist
, &timeout
))
722 n
= poll(evlist
->pollfd
, evlist
->nr_fds
, timeout
);
724 PyErr_SetFromErrno(PyExc_OSError
);
728 return Py_BuildValue("i", n
);
731 static PyObject
*pyrf_evlist__get_pollfd(struct pyrf_evlist
*pevlist
,
732 PyObject
*args __used
, PyObject
*kwargs __used
)
734 struct perf_evlist
*evlist
= &pevlist
->evlist
;
735 PyObject
*list
= PyList_New(0);
738 for (i
= 0; i
< evlist
->nr_fds
; ++i
) {
740 FILE *fp
= fdopen(evlist
->pollfd
[i
].fd
, "r");
745 file
= PyFile_FromFile(fp
, "perf", "r", NULL
);
749 if (PyList_Append(list
, file
) != 0) {
759 return PyErr_NoMemory();
763 static PyObject
*pyrf_evlist__add(struct pyrf_evlist
*pevlist
,
764 PyObject
*args
, PyObject
*kwargs __used
)
766 struct perf_evlist
*evlist
= &pevlist
->evlist
;
768 struct perf_evsel
*evsel
;
770 if (!PyArg_ParseTuple(args
, "O", &pevsel
))
774 evsel
= &((struct pyrf_evsel
*)pevsel
)->evsel
;
775 evsel
->idx
= evlist
->nr_entries
;
776 perf_evlist__add(evlist
, evsel
);
778 return Py_BuildValue("i", evlist
->nr_entries
);
781 static PyObject
*pyrf_evlist__read_on_cpu(struct pyrf_evlist
*pevlist
,
782 PyObject
*args
, PyObject
*kwargs
)
784 struct perf_evlist
*evlist
= &pevlist
->evlist
;
785 union perf_event
*event
;
786 int sample_id_all
= 1, cpu
;
787 static char *kwlist
[] = { "cpu", "sample_id_all", NULL
};
790 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|i", kwlist
,
791 &cpu
, &sample_id_all
))
794 event
= perf_evlist__mmap_read(evlist
, cpu
);
796 struct perf_evsel
*first
;
797 PyObject
*pyevent
= pyrf_event__new(event
);
798 struct pyrf_event
*pevent
= (struct pyrf_event
*)pyevent
;
801 return PyErr_NoMemory();
803 first
= list_entry(evlist
->entries
.next
, struct perf_evsel
, node
);
804 err
= perf_event__parse_sample(event
, first
->attr
.sample_type
,
805 perf_evsel__sample_size(first
),
806 sample_id_all
, &pevent
->sample
);
808 return PyErr_Format(PyExc_OSError
,
809 "perf: can't parse sample, err=%d", err
);
817 static PyMethodDef pyrf_evlist__methods
[] = {
820 .ml_meth
= (PyCFunction
)pyrf_evlist__mmap
,
821 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
822 .ml_doc
= PyDoc_STR("mmap the file descriptor table.")
826 .ml_meth
= (PyCFunction
)pyrf_evlist__poll
,
827 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
828 .ml_doc
= PyDoc_STR("poll the file descriptor table.")
831 .ml_name
= "get_pollfd",
832 .ml_meth
= (PyCFunction
)pyrf_evlist__get_pollfd
,
833 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
834 .ml_doc
= PyDoc_STR("get the poll file descriptor table.")
838 .ml_meth
= (PyCFunction
)pyrf_evlist__add
,
839 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
840 .ml_doc
= PyDoc_STR("adds an event selector to the list.")
843 .ml_name
= "read_on_cpu",
844 .ml_meth
= (PyCFunction
)pyrf_evlist__read_on_cpu
,
845 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
846 .ml_doc
= PyDoc_STR("reads an event.")
851 static Py_ssize_t
pyrf_evlist__length(PyObject
*obj
)
853 struct pyrf_evlist
*pevlist
= (void *)obj
;
855 return pevlist
->evlist
.nr_entries
;
858 static PyObject
*pyrf_evlist__item(PyObject
*obj
, Py_ssize_t i
)
860 struct pyrf_evlist
*pevlist
= (void *)obj
;
861 struct perf_evsel
*pos
;
863 if (i
>= pevlist
->evlist
.nr_entries
)
866 list_for_each_entry(pos
, &pevlist
->evlist
.entries
, node
)
870 return Py_BuildValue("O", container_of(pos
, struct pyrf_evsel
, evsel
));
873 static PySequenceMethods pyrf_evlist__sequence_methods
= {
874 .sq_length
= pyrf_evlist__length
,
875 .sq_item
= pyrf_evlist__item
,
878 static char pyrf_evlist__doc
[] = PyDoc_STR("perf event selector list object.");
880 static PyTypeObject pyrf_evlist__type
= {
881 PyVarObject_HEAD_INIT(NULL
, 0)
882 .tp_name
= "perf.evlist",
883 .tp_basicsize
= sizeof(struct pyrf_evlist
),
884 .tp_dealloc
= (destructor
)pyrf_evlist__delete
,
885 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
886 .tp_as_sequence
= &pyrf_evlist__sequence_methods
,
887 .tp_doc
= pyrf_evlist__doc
,
888 .tp_methods
= pyrf_evlist__methods
,
889 .tp_init
= (initproc
)pyrf_evlist__init
,
892 static int pyrf_evlist__setup_types(void)
894 pyrf_evlist__type
.tp_new
= PyType_GenericNew
;
895 return PyType_Ready(&pyrf_evlist__type
);
901 } perf__constants
[] = {
902 { "TYPE_HARDWARE", PERF_TYPE_HARDWARE
},
903 { "TYPE_SOFTWARE", PERF_TYPE_SOFTWARE
},
904 { "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT
},
905 { "TYPE_HW_CACHE", PERF_TYPE_HW_CACHE
},
906 { "TYPE_RAW", PERF_TYPE_RAW
},
907 { "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT
},
909 { "COUNT_HW_CPU_CYCLES", PERF_COUNT_HW_CPU_CYCLES
},
910 { "COUNT_HW_INSTRUCTIONS", PERF_COUNT_HW_INSTRUCTIONS
},
911 { "COUNT_HW_CACHE_REFERENCES", PERF_COUNT_HW_CACHE_REFERENCES
},
912 { "COUNT_HW_CACHE_MISSES", PERF_COUNT_HW_CACHE_MISSES
},
913 { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS
},
914 { "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES
},
915 { "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES
},
916 { "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D
},
917 { "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I
},
918 { "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL
},
919 { "COUNT_HW_CACHE_DTLB", PERF_COUNT_HW_CACHE_DTLB
},
920 { "COUNT_HW_CACHE_ITLB", PERF_COUNT_HW_CACHE_ITLB
},
921 { "COUNT_HW_CACHE_BPU", PERF_COUNT_HW_CACHE_BPU
},
922 { "COUNT_HW_CACHE_OP_READ", PERF_COUNT_HW_CACHE_OP_READ
},
923 { "COUNT_HW_CACHE_OP_WRITE", PERF_COUNT_HW_CACHE_OP_WRITE
},
924 { "COUNT_HW_CACHE_OP_PREFETCH", PERF_COUNT_HW_CACHE_OP_PREFETCH
},
925 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS
},
926 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS
},
928 { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND
},
929 { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND
},
931 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK
},
932 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK
},
933 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS
},
934 { "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES
},
935 { "COUNT_SW_CPU_MIGRATIONS", PERF_COUNT_SW_CPU_MIGRATIONS
},
936 { "COUNT_SW_PAGE_FAULTS_MIN", PERF_COUNT_SW_PAGE_FAULTS_MIN
},
937 { "COUNT_SW_PAGE_FAULTS_MAJ", PERF_COUNT_SW_PAGE_FAULTS_MAJ
},
938 { "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS
},
939 { "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS
},
941 { "SAMPLE_IP", PERF_SAMPLE_IP
},
942 { "SAMPLE_TID", PERF_SAMPLE_TID
},
943 { "SAMPLE_TIME", PERF_SAMPLE_TIME
},
944 { "SAMPLE_ADDR", PERF_SAMPLE_ADDR
},
945 { "SAMPLE_READ", PERF_SAMPLE_READ
},
946 { "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN
},
947 { "SAMPLE_ID", PERF_SAMPLE_ID
},
948 { "SAMPLE_CPU", PERF_SAMPLE_CPU
},
949 { "SAMPLE_PERIOD", PERF_SAMPLE_PERIOD
},
950 { "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID
},
951 { "SAMPLE_RAW", PERF_SAMPLE_RAW
},
953 { "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED
},
954 { "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING
},
955 { "FORMAT_ID", PERF_FORMAT_ID
},
956 { "FORMAT_GROUP", PERF_FORMAT_GROUP
},
958 { "RECORD_MMAP", PERF_RECORD_MMAP
},
959 { "RECORD_LOST", PERF_RECORD_LOST
},
960 { "RECORD_COMM", PERF_RECORD_COMM
},
961 { "RECORD_EXIT", PERF_RECORD_EXIT
},
962 { "RECORD_THROTTLE", PERF_RECORD_THROTTLE
},
963 { "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE
},
964 { "RECORD_FORK", PERF_RECORD_FORK
},
965 { "RECORD_READ", PERF_RECORD_READ
},
966 { "RECORD_SAMPLE", PERF_RECORD_SAMPLE
},
970 static PyMethodDef perf__methods
[] = {
974 PyMODINIT_FUNC
initperf(void)
978 PyObject
*dict
, *module
= Py_InitModule("perf", perf__methods
);
980 if (module
== NULL
||
981 pyrf_event__setup_types() < 0 ||
982 pyrf_evlist__setup_types() < 0 ||
983 pyrf_evsel__setup_types() < 0 ||
984 pyrf_thread_map__setup_types() < 0 ||
985 pyrf_cpu_map__setup_types() < 0)
988 Py_INCREF(&pyrf_evlist__type
);
989 PyModule_AddObject(module
, "evlist", (PyObject
*)&pyrf_evlist__type
);
991 Py_INCREF(&pyrf_evsel__type
);
992 PyModule_AddObject(module
, "evsel", (PyObject
*)&pyrf_evsel__type
);
994 Py_INCREF(&pyrf_thread_map__type
);
995 PyModule_AddObject(module
, "thread_map", (PyObject
*)&pyrf_thread_map__type
);
997 Py_INCREF(&pyrf_cpu_map__type
);
998 PyModule_AddObject(module
, "cpu_map", (PyObject
*)&pyrf_cpu_map__type
);
1000 dict
= PyModule_GetDict(module
);
1004 for (i
= 0; perf__constants
[i
].name
!= NULL
; i
++) {
1005 obj
= PyInt_FromLong(perf__constants
[i
].value
);
1008 PyDict_SetItemString(dict
, perf__constants
[i
].name
, obj
);
1013 if (PyErr_Occurred())
1014 PyErr_SetString(PyExc_ImportError
, "perf: Init failed!");