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
;
299 tracepoint_field(struct pyrf_event
*pe
, struct format_field
*field
)
301 struct pevent
*pevent
= field
->event
->pevent
;
302 void *data
= pe
->sample
.raw_data
;
303 PyObject
*ret
= NULL
;
304 unsigned long long val
;
305 unsigned int offset
, len
;
307 if (field
->flags
& FIELD_IS_ARRAY
) {
308 offset
= field
->offset
;
310 if (field
->flags
& FIELD_IS_DYNAMIC
) {
311 val
= pevent_read_number(pevent
, data
+ offset
, len
);
316 if (field
->flags
& FIELD_IS_STRING
&&
317 is_printable_array(data
+ offset
, len
)) {
318 ret
= PyString_FromString((char *)data
+ offset
);
320 ret
= PyByteArray_FromStringAndSize((const char *) data
+ offset
, len
);
321 field
->flags
&= ~FIELD_IS_STRING
;
324 val
= pevent_read_number(pevent
, data
+ field
->offset
,
326 if (field
->flags
& FIELD_IS_POINTER
)
327 ret
= PyLong_FromUnsignedLong((unsigned long) val
);
328 else if (field
->flags
& FIELD_IS_SIGNED
)
329 ret
= PyLong_FromLong((long) val
);
331 ret
= PyLong_FromUnsignedLong((unsigned long) val
);
338 get_tracepoint_field(struct pyrf_event
*pevent
, PyObject
*attr_name
)
340 const char *str
= PyString_AsString(PyObject_Str(attr_name
));
341 struct perf_evsel
*evsel
= pevent
->evsel
;
342 struct format_field
*field
;
344 if (!evsel
->tp_format
) {
345 struct event_format
*tp_format
;
347 tp_format
= trace_event__tp_format_id(evsel
->attr
.config
);
351 evsel
->tp_format
= tp_format
;
354 field
= pevent_find_any_field(evsel
->tp_format
, str
);
358 return tracepoint_field(pevent
, field
);
362 pyrf_sample_event__getattro(struct pyrf_event
*pevent
, PyObject
*attr_name
)
364 PyObject
*obj
= NULL
;
366 if (is_tracepoint(pevent
))
367 obj
= get_tracepoint_field(pevent
, attr_name
);
369 return obj
?: PyObject_GenericGetAttr((PyObject
*) pevent
, attr_name
);
372 static PyTypeObject pyrf_sample_event__type
= {
373 PyVarObject_HEAD_INIT(NULL
, 0)
374 .tp_name
= "perf.sample_event",
375 .tp_basicsize
= sizeof(struct pyrf_event
),
376 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
377 .tp_doc
= pyrf_sample_event__doc
,
378 .tp_members
= pyrf_sample_event__members
,
379 .tp_repr
= (reprfunc
)pyrf_sample_event__repr
,
380 .tp_getattro
= (getattrofunc
) pyrf_sample_event__getattro
,
383 static char pyrf_context_switch_event__doc
[] = PyDoc_STR("perf context_switch event object.");
385 static PyMemberDef pyrf_context_switch_event__members
[] = {
387 member_def(perf_event_header
, type
, T_UINT
, "event type"),
388 member_def(context_switch_event
, next_prev_pid
, T_UINT
, "next/prev pid"),
389 member_def(context_switch_event
, next_prev_tid
, T_UINT
, "next/prev tid"),
393 static PyObject
*pyrf_context_switch_event__repr(struct pyrf_event
*pevent
)
398 if (asprintf(&s
, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
399 pevent
->event
.context_switch
.next_prev_pid
,
400 pevent
->event
.context_switch
.next_prev_tid
,
401 !!(pevent
->event
.header
.misc
& PERF_RECORD_MISC_SWITCH_OUT
)) < 0) {
402 ret
= PyErr_NoMemory();
404 ret
= PyString_FromString(s
);
410 static PyTypeObject pyrf_context_switch_event__type
= {
411 PyVarObject_HEAD_INIT(NULL
, 0)
412 .tp_name
= "perf.context_switch_event",
413 .tp_basicsize
= sizeof(struct pyrf_event
),
414 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
415 .tp_doc
= pyrf_context_switch_event__doc
,
416 .tp_members
= pyrf_context_switch_event__members
,
417 .tp_repr
= (reprfunc
)pyrf_context_switch_event__repr
,
420 static int pyrf_event__setup_types(void)
423 pyrf_mmap_event__type
.tp_new
=
424 pyrf_task_event__type
.tp_new
=
425 pyrf_comm_event__type
.tp_new
=
426 pyrf_lost_event__type
.tp_new
=
427 pyrf_read_event__type
.tp_new
=
428 pyrf_sample_event__type
.tp_new
=
429 pyrf_context_switch_event__type
.tp_new
=
430 pyrf_throttle_event__type
.tp_new
= PyType_GenericNew
;
431 err
= PyType_Ready(&pyrf_mmap_event__type
);
434 err
= PyType_Ready(&pyrf_lost_event__type
);
437 err
= PyType_Ready(&pyrf_task_event__type
);
440 err
= PyType_Ready(&pyrf_comm_event__type
);
443 err
= PyType_Ready(&pyrf_throttle_event__type
);
446 err
= PyType_Ready(&pyrf_read_event__type
);
449 err
= PyType_Ready(&pyrf_sample_event__type
);
452 err
= PyType_Ready(&pyrf_context_switch_event__type
);
459 static PyTypeObject
*pyrf_event__type
[] = {
460 [PERF_RECORD_MMAP
] = &pyrf_mmap_event__type
,
461 [PERF_RECORD_LOST
] = &pyrf_lost_event__type
,
462 [PERF_RECORD_COMM
] = &pyrf_comm_event__type
,
463 [PERF_RECORD_EXIT
] = &pyrf_task_event__type
,
464 [PERF_RECORD_THROTTLE
] = &pyrf_throttle_event__type
,
465 [PERF_RECORD_UNTHROTTLE
] = &pyrf_throttle_event__type
,
466 [PERF_RECORD_FORK
] = &pyrf_task_event__type
,
467 [PERF_RECORD_READ
] = &pyrf_read_event__type
,
468 [PERF_RECORD_SAMPLE
] = &pyrf_sample_event__type
,
469 [PERF_RECORD_SWITCH
] = &pyrf_context_switch_event__type
,
470 [PERF_RECORD_SWITCH_CPU_WIDE
] = &pyrf_context_switch_event__type
,
473 static PyObject
*pyrf_event__new(union perf_event
*event
)
475 struct pyrf_event
*pevent
;
478 if ((event
->header
.type
< PERF_RECORD_MMAP
||
479 event
->header
.type
> PERF_RECORD_SAMPLE
) &&
480 !(event
->header
.type
== PERF_RECORD_SWITCH
||
481 event
->header
.type
== PERF_RECORD_SWITCH_CPU_WIDE
))
484 ptype
= pyrf_event__type
[event
->header
.type
];
485 pevent
= PyObject_New(struct pyrf_event
, ptype
);
487 memcpy(&pevent
->event
, event
, event
->header
.size
);
488 return (PyObject
*)pevent
;
491 struct pyrf_cpu_map
{
494 struct cpu_map
*cpus
;
497 static int pyrf_cpu_map__init(struct pyrf_cpu_map
*pcpus
,
498 PyObject
*args
, PyObject
*kwargs
)
500 static char *kwlist
[] = { "cpustr", NULL
};
503 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s",
507 pcpus
->cpus
= cpu_map__new(cpustr
);
508 if (pcpus
->cpus
== NULL
)
513 static void pyrf_cpu_map__delete(struct pyrf_cpu_map
*pcpus
)
515 cpu_map__put(pcpus
->cpus
);
516 pcpus
->ob_type
->tp_free((PyObject
*)pcpus
);
519 static Py_ssize_t
pyrf_cpu_map__length(PyObject
*obj
)
521 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
523 return pcpus
->cpus
->nr
;
526 static PyObject
*pyrf_cpu_map__item(PyObject
*obj
, Py_ssize_t i
)
528 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
530 if (i
>= pcpus
->cpus
->nr
)
533 return Py_BuildValue("i", pcpus
->cpus
->map
[i
]);
536 static PySequenceMethods pyrf_cpu_map__sequence_methods
= {
537 .sq_length
= pyrf_cpu_map__length
,
538 .sq_item
= pyrf_cpu_map__item
,
541 static char pyrf_cpu_map__doc
[] = PyDoc_STR("cpu map object.");
543 static PyTypeObject pyrf_cpu_map__type
= {
544 PyVarObject_HEAD_INIT(NULL
, 0)
545 .tp_name
= "perf.cpu_map",
546 .tp_basicsize
= sizeof(struct pyrf_cpu_map
),
547 .tp_dealloc
= (destructor
)pyrf_cpu_map__delete
,
548 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
549 .tp_doc
= pyrf_cpu_map__doc
,
550 .tp_as_sequence
= &pyrf_cpu_map__sequence_methods
,
551 .tp_init
= (initproc
)pyrf_cpu_map__init
,
554 static int pyrf_cpu_map__setup_types(void)
556 pyrf_cpu_map__type
.tp_new
= PyType_GenericNew
;
557 return PyType_Ready(&pyrf_cpu_map__type
);
560 struct pyrf_thread_map
{
563 struct thread_map
*threads
;
566 static int pyrf_thread_map__init(struct pyrf_thread_map
*pthreads
,
567 PyObject
*args
, PyObject
*kwargs
)
569 static char *kwlist
[] = { "pid", "tid", "uid", NULL
};
570 int pid
= -1, tid
= -1, uid
= UINT_MAX
;
572 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iii",
573 kwlist
, &pid
, &tid
, &uid
))
576 pthreads
->threads
= thread_map__new(pid
, tid
, uid
);
577 if (pthreads
->threads
== NULL
)
582 static void pyrf_thread_map__delete(struct pyrf_thread_map
*pthreads
)
584 thread_map__put(pthreads
->threads
);
585 pthreads
->ob_type
->tp_free((PyObject
*)pthreads
);
588 static Py_ssize_t
pyrf_thread_map__length(PyObject
*obj
)
590 struct pyrf_thread_map
*pthreads
= (void *)obj
;
592 return pthreads
->threads
->nr
;
595 static PyObject
*pyrf_thread_map__item(PyObject
*obj
, Py_ssize_t i
)
597 struct pyrf_thread_map
*pthreads
= (void *)obj
;
599 if (i
>= pthreads
->threads
->nr
)
602 return Py_BuildValue("i", pthreads
->threads
->map
[i
]);
605 static PySequenceMethods pyrf_thread_map__sequence_methods
= {
606 .sq_length
= pyrf_thread_map__length
,
607 .sq_item
= pyrf_thread_map__item
,
610 static char pyrf_thread_map__doc
[] = PyDoc_STR("thread map object.");
612 static PyTypeObject pyrf_thread_map__type
= {
613 PyVarObject_HEAD_INIT(NULL
, 0)
614 .tp_name
= "perf.thread_map",
615 .tp_basicsize
= sizeof(struct pyrf_thread_map
),
616 .tp_dealloc
= (destructor
)pyrf_thread_map__delete
,
617 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
618 .tp_doc
= pyrf_thread_map__doc
,
619 .tp_as_sequence
= &pyrf_thread_map__sequence_methods
,
620 .tp_init
= (initproc
)pyrf_thread_map__init
,
623 static int pyrf_thread_map__setup_types(void)
625 pyrf_thread_map__type
.tp_new
= PyType_GenericNew
;
626 return PyType_Ready(&pyrf_thread_map__type
);
632 struct perf_evsel evsel
;
635 static int pyrf_evsel__init(struct pyrf_evsel
*pevsel
,
636 PyObject
*args
, PyObject
*kwargs
)
638 struct perf_event_attr attr
= {
639 .type
= PERF_TYPE_HARDWARE
,
640 .config
= PERF_COUNT_HW_CPU_CYCLES
,
641 .sample_type
= PERF_SAMPLE_PERIOD
| PERF_SAMPLE_TID
,
643 static char *kwlist
[] = {
675 u64 sample_period
= 0;
697 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
698 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist
,
699 &attr
.type
, &attr
.config
, &attr
.sample_freq
,
700 &sample_period
, &attr
.sample_type
,
701 &attr
.read_format
, &disabled
, &inherit
,
702 &pinned
, &exclusive
, &exclude_user
,
703 &exclude_kernel
, &exclude_hv
, &exclude_idle
,
704 &mmap
, &context_switch
, &comm
, &freq
, &inherit_stat
,
705 &enable_on_exec
, &task
, &watermark
,
706 &precise_ip
, &mmap_data
, &sample_id_all
,
707 &attr
.wakeup_events
, &attr
.bp_type
,
708 &attr
.bp_addr
, &attr
.bp_len
, &idx
))
712 if (sample_period
!= 0) {
713 if (attr
.sample_freq
!= 0)
714 return -1; /* FIXME: throw right exception */
715 attr
.sample_period
= sample_period
;
719 attr
.disabled
= disabled
;
720 attr
.inherit
= inherit
;
721 attr
.pinned
= pinned
;
722 attr
.exclusive
= exclusive
;
723 attr
.exclude_user
= exclude_user
;
724 attr
.exclude_kernel
= exclude_kernel
;
725 attr
.exclude_hv
= exclude_hv
;
726 attr
.exclude_idle
= exclude_idle
;
728 attr
.context_switch
= context_switch
;
731 attr
.inherit_stat
= inherit_stat
;
732 attr
.enable_on_exec
= enable_on_exec
;
734 attr
.watermark
= watermark
;
735 attr
.precise_ip
= precise_ip
;
736 attr
.mmap_data
= mmap_data
;
737 attr
.sample_id_all
= sample_id_all
;
738 attr
.size
= sizeof(attr
);
740 perf_evsel__init(&pevsel
->evsel
, &attr
, idx
);
744 static void pyrf_evsel__delete(struct pyrf_evsel
*pevsel
)
746 perf_evsel__exit(&pevsel
->evsel
);
747 pevsel
->ob_type
->tp_free((PyObject
*)pevsel
);
750 static PyObject
*pyrf_evsel__open(struct pyrf_evsel
*pevsel
,
751 PyObject
*args
, PyObject
*kwargs
)
753 struct perf_evsel
*evsel
= &pevsel
->evsel
;
754 struct cpu_map
*cpus
= NULL
;
755 struct thread_map
*threads
= NULL
;
756 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
757 int group
= 0, inherit
= 0;
758 static char *kwlist
[] = { "cpus", "threads", "group", "inherit", NULL
};
760 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOii", kwlist
,
761 &pcpus
, &pthreads
, &group
, &inherit
))
764 if (pthreads
!= NULL
)
765 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
768 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
770 evsel
->attr
.inherit
= inherit
;
772 * This will group just the fds for this single evsel, to group
773 * multiple events, use evlist.open().
775 if (perf_evsel__open(evsel
, cpus
, threads
) < 0) {
776 PyErr_SetFromErrno(PyExc_OSError
);
784 static PyMethodDef pyrf_evsel__methods
[] = {
787 .ml_meth
= (PyCFunction
)pyrf_evsel__open
,
788 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
789 .ml_doc
= PyDoc_STR("open the event selector file descriptor table.")
794 static char pyrf_evsel__doc
[] = PyDoc_STR("perf event selector list object.");
796 static PyTypeObject pyrf_evsel__type
= {
797 PyVarObject_HEAD_INIT(NULL
, 0)
798 .tp_name
= "perf.evsel",
799 .tp_basicsize
= sizeof(struct pyrf_evsel
),
800 .tp_dealloc
= (destructor
)pyrf_evsel__delete
,
801 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
802 .tp_doc
= pyrf_evsel__doc
,
803 .tp_methods
= pyrf_evsel__methods
,
804 .tp_init
= (initproc
)pyrf_evsel__init
,
807 static int pyrf_evsel__setup_types(void)
809 pyrf_evsel__type
.tp_new
= PyType_GenericNew
;
810 return PyType_Ready(&pyrf_evsel__type
);
816 struct perf_evlist evlist
;
819 static int pyrf_evlist__init(struct pyrf_evlist
*pevlist
,
820 PyObject
*args
, PyObject
*kwargs __maybe_unused
)
822 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
823 struct cpu_map
*cpus
;
824 struct thread_map
*threads
;
826 if (!PyArg_ParseTuple(args
, "OO", &pcpus
, &pthreads
))
829 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
830 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
831 perf_evlist__init(&pevlist
->evlist
, cpus
, threads
);
835 static void pyrf_evlist__delete(struct pyrf_evlist
*pevlist
)
837 perf_evlist__exit(&pevlist
->evlist
);
838 pevlist
->ob_type
->tp_free((PyObject
*)pevlist
);
841 static PyObject
*pyrf_evlist__mmap(struct pyrf_evlist
*pevlist
,
842 PyObject
*args
, PyObject
*kwargs
)
844 struct perf_evlist
*evlist
= &pevlist
->evlist
;
845 static char *kwlist
[] = { "pages", "overwrite", NULL
};
846 int pages
= 128, overwrite
= false;
848 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ii", kwlist
,
852 if (perf_evlist__mmap(evlist
, pages
, overwrite
) < 0) {
853 PyErr_SetFromErrno(PyExc_OSError
);
861 static PyObject
*pyrf_evlist__poll(struct pyrf_evlist
*pevlist
,
862 PyObject
*args
, PyObject
*kwargs
)
864 struct perf_evlist
*evlist
= &pevlist
->evlist
;
865 static char *kwlist
[] = { "timeout", NULL
};
868 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i", kwlist
, &timeout
))
871 n
= perf_evlist__poll(evlist
, timeout
);
873 PyErr_SetFromErrno(PyExc_OSError
);
877 return Py_BuildValue("i", n
);
880 static PyObject
*pyrf_evlist__get_pollfd(struct pyrf_evlist
*pevlist
,
881 PyObject
*args __maybe_unused
,
882 PyObject
*kwargs __maybe_unused
)
884 struct perf_evlist
*evlist
= &pevlist
->evlist
;
885 PyObject
*list
= PyList_New(0);
888 for (i
= 0; i
< evlist
->pollfd
.nr
; ++i
) {
890 FILE *fp
= fdopen(evlist
->pollfd
.entries
[i
].fd
, "r");
895 file
= PyFile_FromFile(fp
, "perf", "r", NULL
);
899 if (PyList_Append(list
, file
) != 0) {
909 return PyErr_NoMemory();
913 static PyObject
*pyrf_evlist__add(struct pyrf_evlist
*pevlist
,
915 PyObject
*kwargs __maybe_unused
)
917 struct perf_evlist
*evlist
= &pevlist
->evlist
;
919 struct perf_evsel
*evsel
;
921 if (!PyArg_ParseTuple(args
, "O", &pevsel
))
925 evsel
= &((struct pyrf_evsel
*)pevsel
)->evsel
;
926 evsel
->idx
= evlist
->nr_entries
;
927 perf_evlist__add(evlist
, evsel
);
929 return Py_BuildValue("i", evlist
->nr_entries
);
932 static PyObject
*pyrf_evlist__read_on_cpu(struct pyrf_evlist
*pevlist
,
933 PyObject
*args
, PyObject
*kwargs
)
935 struct perf_evlist
*evlist
= &pevlist
->evlist
;
936 union perf_event
*event
;
937 int sample_id_all
= 1, cpu
;
938 static char *kwlist
[] = { "cpu", "sample_id_all", NULL
};
941 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|i", kwlist
,
942 &cpu
, &sample_id_all
))
945 event
= perf_evlist__mmap_read(evlist
, cpu
);
947 PyObject
*pyevent
= pyrf_event__new(event
);
948 struct pyrf_event
*pevent
= (struct pyrf_event
*)pyevent
;
949 struct perf_evsel
*evsel
;
952 return PyErr_NoMemory();
954 evsel
= perf_evlist__event2evsel(evlist
, event
);
958 pevent
->evsel
= evsel
;
960 err
= perf_evsel__parse_sample(evsel
, event
, &pevent
->sample
);
962 /* Consume the even only after we parsed it out. */
963 perf_evlist__mmap_consume(evlist
, cpu
);
966 return PyErr_Format(PyExc_OSError
,
967 "perf: can't parse sample, err=%d", err
);
975 static PyObject
*pyrf_evlist__open(struct pyrf_evlist
*pevlist
,
976 PyObject
*args
, PyObject
*kwargs
)
978 struct perf_evlist
*evlist
= &pevlist
->evlist
;
980 static char *kwlist
[] = { "group", NULL
};
982 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOii", kwlist
, &group
))
986 perf_evlist__set_leader(evlist
);
988 if (perf_evlist__open(evlist
) < 0) {
989 PyErr_SetFromErrno(PyExc_OSError
);
997 static PyMethodDef pyrf_evlist__methods
[] = {
1000 .ml_meth
= (PyCFunction
)pyrf_evlist__mmap
,
1001 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1002 .ml_doc
= PyDoc_STR("mmap the file descriptor table.")
1006 .ml_meth
= (PyCFunction
)pyrf_evlist__open
,
1007 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1008 .ml_doc
= PyDoc_STR("open the file descriptors.")
1012 .ml_meth
= (PyCFunction
)pyrf_evlist__poll
,
1013 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1014 .ml_doc
= PyDoc_STR("poll the file descriptor table.")
1017 .ml_name
= "get_pollfd",
1018 .ml_meth
= (PyCFunction
)pyrf_evlist__get_pollfd
,
1019 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1020 .ml_doc
= PyDoc_STR("get the poll file descriptor table.")
1024 .ml_meth
= (PyCFunction
)pyrf_evlist__add
,
1025 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1026 .ml_doc
= PyDoc_STR("adds an event selector to the list.")
1029 .ml_name
= "read_on_cpu",
1030 .ml_meth
= (PyCFunction
)pyrf_evlist__read_on_cpu
,
1031 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1032 .ml_doc
= PyDoc_STR("reads an event.")
1034 { .ml_name
= NULL
, }
1037 static Py_ssize_t
pyrf_evlist__length(PyObject
*obj
)
1039 struct pyrf_evlist
*pevlist
= (void *)obj
;
1041 return pevlist
->evlist
.nr_entries
;
1044 static PyObject
*pyrf_evlist__item(PyObject
*obj
, Py_ssize_t i
)
1046 struct pyrf_evlist
*pevlist
= (void *)obj
;
1047 struct perf_evsel
*pos
;
1049 if (i
>= pevlist
->evlist
.nr_entries
)
1052 evlist__for_each_entry(&pevlist
->evlist
, pos
) {
1057 return Py_BuildValue("O", container_of(pos
, struct pyrf_evsel
, evsel
));
1060 static PySequenceMethods pyrf_evlist__sequence_methods
= {
1061 .sq_length
= pyrf_evlist__length
,
1062 .sq_item
= pyrf_evlist__item
,
1065 static char pyrf_evlist__doc
[] = PyDoc_STR("perf event selector list object.");
1067 static PyTypeObject pyrf_evlist__type
= {
1068 PyVarObject_HEAD_INIT(NULL
, 0)
1069 .tp_name
= "perf.evlist",
1070 .tp_basicsize
= sizeof(struct pyrf_evlist
),
1071 .tp_dealloc
= (destructor
)pyrf_evlist__delete
,
1072 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1073 .tp_as_sequence
= &pyrf_evlist__sequence_methods
,
1074 .tp_doc
= pyrf_evlist__doc
,
1075 .tp_methods
= pyrf_evlist__methods
,
1076 .tp_init
= (initproc
)pyrf_evlist__init
,
1079 static int pyrf_evlist__setup_types(void)
1081 pyrf_evlist__type
.tp_new
= PyType_GenericNew
;
1082 return PyType_Ready(&pyrf_evlist__type
);
1085 #define PERF_CONST(name) { #name, PERF_##name }
1090 } perf__constants
[] = {
1091 PERF_CONST(TYPE_HARDWARE
),
1092 PERF_CONST(TYPE_SOFTWARE
),
1093 PERF_CONST(TYPE_TRACEPOINT
),
1094 PERF_CONST(TYPE_HW_CACHE
),
1095 PERF_CONST(TYPE_RAW
),
1096 PERF_CONST(TYPE_BREAKPOINT
),
1098 PERF_CONST(COUNT_HW_CPU_CYCLES
),
1099 PERF_CONST(COUNT_HW_INSTRUCTIONS
),
1100 PERF_CONST(COUNT_HW_CACHE_REFERENCES
),
1101 PERF_CONST(COUNT_HW_CACHE_MISSES
),
1102 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS
),
1103 PERF_CONST(COUNT_HW_BRANCH_MISSES
),
1104 PERF_CONST(COUNT_HW_BUS_CYCLES
),
1105 PERF_CONST(COUNT_HW_CACHE_L1D
),
1106 PERF_CONST(COUNT_HW_CACHE_L1I
),
1107 PERF_CONST(COUNT_HW_CACHE_LL
),
1108 PERF_CONST(COUNT_HW_CACHE_DTLB
),
1109 PERF_CONST(COUNT_HW_CACHE_ITLB
),
1110 PERF_CONST(COUNT_HW_CACHE_BPU
),
1111 PERF_CONST(COUNT_HW_CACHE_OP_READ
),
1112 PERF_CONST(COUNT_HW_CACHE_OP_WRITE
),
1113 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH
),
1114 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS
),
1115 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS
),
1117 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND
),
1118 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND
),
1120 PERF_CONST(COUNT_SW_CPU_CLOCK
),
1121 PERF_CONST(COUNT_SW_TASK_CLOCK
),
1122 PERF_CONST(COUNT_SW_PAGE_FAULTS
),
1123 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES
),
1124 PERF_CONST(COUNT_SW_CPU_MIGRATIONS
),
1125 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN
),
1126 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ
),
1127 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS
),
1128 PERF_CONST(COUNT_SW_EMULATION_FAULTS
),
1129 PERF_CONST(COUNT_SW_DUMMY
),
1131 PERF_CONST(SAMPLE_IP
),
1132 PERF_CONST(SAMPLE_TID
),
1133 PERF_CONST(SAMPLE_TIME
),
1134 PERF_CONST(SAMPLE_ADDR
),
1135 PERF_CONST(SAMPLE_READ
),
1136 PERF_CONST(SAMPLE_CALLCHAIN
),
1137 PERF_CONST(SAMPLE_ID
),
1138 PERF_CONST(SAMPLE_CPU
),
1139 PERF_CONST(SAMPLE_PERIOD
),
1140 PERF_CONST(SAMPLE_STREAM_ID
),
1141 PERF_CONST(SAMPLE_RAW
),
1143 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED
),
1144 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING
),
1145 PERF_CONST(FORMAT_ID
),
1146 PERF_CONST(FORMAT_GROUP
),
1148 PERF_CONST(RECORD_MMAP
),
1149 PERF_CONST(RECORD_LOST
),
1150 PERF_CONST(RECORD_COMM
),
1151 PERF_CONST(RECORD_EXIT
),
1152 PERF_CONST(RECORD_THROTTLE
),
1153 PERF_CONST(RECORD_UNTHROTTLE
),
1154 PERF_CONST(RECORD_FORK
),
1155 PERF_CONST(RECORD_READ
),
1156 PERF_CONST(RECORD_SAMPLE
),
1157 PERF_CONST(RECORD_MMAP2
),
1158 PERF_CONST(RECORD_AUX
),
1159 PERF_CONST(RECORD_ITRACE_START
),
1160 PERF_CONST(RECORD_LOST_SAMPLES
),
1161 PERF_CONST(RECORD_SWITCH
),
1162 PERF_CONST(RECORD_SWITCH_CPU_WIDE
),
1164 PERF_CONST(RECORD_MISC_SWITCH_OUT
),
1168 static PyObject
*pyrf__tracepoint(struct pyrf_evsel
*pevsel
,
1169 PyObject
*args
, PyObject
*kwargs
)
1171 struct event_format
*tp_format
;
1172 static char *kwlist
[] = { "sys", "name", NULL
};
1176 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ss", kwlist
,
1180 tp_format
= trace_event__tp_format(sys
, name
);
1181 if (IS_ERR(tp_format
))
1182 return PyInt_FromLong(-1);
1184 return PyInt_FromLong(tp_format
->id
);
1187 static PyMethodDef perf__methods
[] = {
1189 .ml_name
= "tracepoint",
1190 .ml_meth
= (PyCFunction
) pyrf__tracepoint
,
1191 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1192 .ml_doc
= PyDoc_STR("Get tracepoint config.")
1194 { .ml_name
= NULL
, }
1197 PyMODINIT_FUNC
initperf(void)
1201 PyObject
*dict
, *module
= Py_InitModule("perf", perf__methods
);
1203 if (module
== NULL
||
1204 pyrf_event__setup_types() < 0 ||
1205 pyrf_evlist__setup_types() < 0 ||
1206 pyrf_evsel__setup_types() < 0 ||
1207 pyrf_thread_map__setup_types() < 0 ||
1208 pyrf_cpu_map__setup_types() < 0)
1211 /* The page_size is placed in util object. */
1212 page_size
= sysconf(_SC_PAGE_SIZE
);
1214 Py_INCREF(&pyrf_evlist__type
);
1215 PyModule_AddObject(module
, "evlist", (PyObject
*)&pyrf_evlist__type
);
1217 Py_INCREF(&pyrf_evsel__type
);
1218 PyModule_AddObject(module
, "evsel", (PyObject
*)&pyrf_evsel__type
);
1220 Py_INCREF(&pyrf_mmap_event__type
);
1221 PyModule_AddObject(module
, "mmap_event", (PyObject
*)&pyrf_mmap_event__type
);
1223 Py_INCREF(&pyrf_lost_event__type
);
1224 PyModule_AddObject(module
, "lost_event", (PyObject
*)&pyrf_lost_event__type
);
1226 Py_INCREF(&pyrf_comm_event__type
);
1227 PyModule_AddObject(module
, "comm_event", (PyObject
*)&pyrf_comm_event__type
);
1229 Py_INCREF(&pyrf_task_event__type
);
1230 PyModule_AddObject(module
, "task_event", (PyObject
*)&pyrf_task_event__type
);
1232 Py_INCREF(&pyrf_throttle_event__type
);
1233 PyModule_AddObject(module
, "throttle_event", (PyObject
*)&pyrf_throttle_event__type
);
1235 Py_INCREF(&pyrf_task_event__type
);
1236 PyModule_AddObject(module
, "task_event", (PyObject
*)&pyrf_task_event__type
);
1238 Py_INCREF(&pyrf_read_event__type
);
1239 PyModule_AddObject(module
, "read_event", (PyObject
*)&pyrf_read_event__type
);
1241 Py_INCREF(&pyrf_sample_event__type
);
1242 PyModule_AddObject(module
, "sample_event", (PyObject
*)&pyrf_sample_event__type
);
1244 Py_INCREF(&pyrf_context_switch_event__type
);
1245 PyModule_AddObject(module
, "switch_event", (PyObject
*)&pyrf_context_switch_event__type
);
1247 Py_INCREF(&pyrf_thread_map__type
);
1248 PyModule_AddObject(module
, "thread_map", (PyObject
*)&pyrf_thread_map__type
);
1250 Py_INCREF(&pyrf_cpu_map__type
);
1251 PyModule_AddObject(module
, "cpu_map", (PyObject
*)&pyrf_cpu_map__type
);
1253 dict
= PyModule_GetDict(module
);
1257 for (i
= 0; perf__constants
[i
].name
!= NULL
; i
++) {
1258 obj
= PyInt_FromLong(perf__constants
[i
].value
);
1261 PyDict_SetItemString(dict
, perf__constants
[i
].name
, obj
);
1266 if (PyErr_Occurred())
1267 PyErr_SetString(PyExc_ImportError
, "perf: Init failed!");
1271 * Dummy, to avoid dragging all the test_attr infrastructure in the python
1274 void test_attr__open(struct perf_event_attr
*attr
, pid_t pid
, int cpu
,
1275 int fd
, int group_fd
, unsigned long flags
)