1 // SPDX-License-Identifier: GPL-2.0
3 #include <structmember.h>
7 #include <perf/cpumap.h>
8 #ifdef HAVE_LIBTRACEEVENT
9 #include <event-parse.h>
11 #include <perf/mmap.h>
15 #include "print_binary.h"
16 #include "thread_map.h"
17 #include "trace-event.h"
19 #include "util/bpf-filter.h"
21 #include "util/kvm-stat.h"
22 #include "util/stat.h"
23 #include "util/kwork.h"
24 #include "util/sample.h"
25 #include "util/lock-contention.h"
26 #include <internal/lib.h>
27 #include "../builtin.h"
29 #if PY_MAJOR_VERSION < 3
30 #define _PyUnicode_FromString(arg) \
31 PyString_FromString(arg)
32 #define _PyUnicode_AsString(arg) \
33 PyString_AsString(arg)
34 #define _PyUnicode_FromFormat(...) \
35 PyString_FromFormat(__VA_ARGS__)
36 #define _PyLong_FromLong(arg) \
41 #define _PyUnicode_FromString(arg) \
42 PyUnicode_FromString(arg)
43 #define _PyUnicode_FromFormat(...) \
44 PyUnicode_FromFormat(__VA_ARGS__)
45 #define _PyLong_FromLong(arg) \
50 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
53 /* Define PyVarObject_HEAD_INIT for python 2.5 */
54 #ifndef PyVarObject_HEAD_INIT
55 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
58 #if PY_MAJOR_VERSION < 3
59 PyMODINIT_FUNC
initperf(void);
61 PyMODINIT_FUNC
PyInit_perf(void);
64 #define member_def(type, member, ptype, help) \
66 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
69 #define sample_member_def(name, member, ptype, help) \
71 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
77 struct perf_sample sample
;
78 union perf_event event
;
81 #define sample_members \
82 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
83 sample_member_def(sample_pid, pid, T_INT, "event pid"), \
84 sample_member_def(sample_tid, tid, T_INT, "event tid"), \
85 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
86 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
87 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
88 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
89 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
90 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
92 static char pyrf_mmap_event__doc
[] = PyDoc_STR("perf mmap event object.");
94 static PyMemberDef pyrf_mmap_event__members
[] = {
96 member_def(perf_event_header
, type
, T_UINT
, "event type"),
97 member_def(perf_event_header
, misc
, T_UINT
, "event misc"),
98 member_def(perf_record_mmap
, pid
, T_UINT
, "event pid"),
99 member_def(perf_record_mmap
, tid
, T_UINT
, "event tid"),
100 member_def(perf_record_mmap
, start
, T_ULONGLONG
, "start of the map"),
101 member_def(perf_record_mmap
, len
, T_ULONGLONG
, "map length"),
102 member_def(perf_record_mmap
, pgoff
, T_ULONGLONG
, "page offset"),
103 member_def(perf_record_mmap
, filename
, T_STRING_INPLACE
, "backing store"),
107 static PyObject
*pyrf_mmap_event__repr(struct pyrf_event
*pevent
)
112 if (asprintf(&s
, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64
", "
113 "length: %#" PRI_lx64
", offset: %#" PRI_lx64
", "
115 pevent
->event
.mmap
.pid
, pevent
->event
.mmap
.tid
,
116 pevent
->event
.mmap
.start
, pevent
->event
.mmap
.len
,
117 pevent
->event
.mmap
.pgoff
, pevent
->event
.mmap
.filename
) < 0) {
118 ret
= PyErr_NoMemory();
120 ret
= _PyUnicode_FromString(s
);
126 static PyTypeObject pyrf_mmap_event__type
= {
127 PyVarObject_HEAD_INIT(NULL
, 0)
128 .tp_name
= "perf.mmap_event",
129 .tp_basicsize
= sizeof(struct pyrf_event
),
130 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
131 .tp_doc
= pyrf_mmap_event__doc
,
132 .tp_members
= pyrf_mmap_event__members
,
133 .tp_repr
= (reprfunc
)pyrf_mmap_event__repr
,
136 static char pyrf_task_event__doc
[] = PyDoc_STR("perf task (fork/exit) event object.");
138 static PyMemberDef pyrf_task_event__members
[] = {
140 member_def(perf_event_header
, type
, T_UINT
, "event type"),
141 member_def(perf_record_fork
, pid
, T_UINT
, "event pid"),
142 member_def(perf_record_fork
, ppid
, T_UINT
, "event ppid"),
143 member_def(perf_record_fork
, tid
, T_UINT
, "event tid"),
144 member_def(perf_record_fork
, ptid
, T_UINT
, "event ptid"),
145 member_def(perf_record_fork
, time
, T_ULONGLONG
, "timestamp"),
149 static PyObject
*pyrf_task_event__repr(struct pyrf_event
*pevent
)
151 return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
152 "ptid: %u, time: %" PRI_lu64
"}",
153 pevent
->event
.header
.type
== PERF_RECORD_FORK
? "fork" : "exit",
154 pevent
->event
.fork
.pid
,
155 pevent
->event
.fork
.ppid
,
156 pevent
->event
.fork
.tid
,
157 pevent
->event
.fork
.ptid
,
158 pevent
->event
.fork
.time
);
161 static PyTypeObject pyrf_task_event__type
= {
162 PyVarObject_HEAD_INIT(NULL
, 0)
163 .tp_name
= "perf.task_event",
164 .tp_basicsize
= sizeof(struct pyrf_event
),
165 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
166 .tp_doc
= pyrf_task_event__doc
,
167 .tp_members
= pyrf_task_event__members
,
168 .tp_repr
= (reprfunc
)pyrf_task_event__repr
,
171 static char pyrf_comm_event__doc
[] = PyDoc_STR("perf comm event object.");
173 static PyMemberDef pyrf_comm_event__members
[] = {
175 member_def(perf_event_header
, type
, T_UINT
, "event type"),
176 member_def(perf_record_comm
, pid
, T_UINT
, "event pid"),
177 member_def(perf_record_comm
, tid
, T_UINT
, "event tid"),
178 member_def(perf_record_comm
, comm
, T_STRING_INPLACE
, "process name"),
182 static PyObject
*pyrf_comm_event__repr(struct pyrf_event
*pevent
)
184 return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
185 pevent
->event
.comm
.pid
,
186 pevent
->event
.comm
.tid
,
187 pevent
->event
.comm
.comm
);
190 static PyTypeObject pyrf_comm_event__type
= {
191 PyVarObject_HEAD_INIT(NULL
, 0)
192 .tp_name
= "perf.comm_event",
193 .tp_basicsize
= sizeof(struct pyrf_event
),
194 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
195 .tp_doc
= pyrf_comm_event__doc
,
196 .tp_members
= pyrf_comm_event__members
,
197 .tp_repr
= (reprfunc
)pyrf_comm_event__repr
,
200 static char pyrf_throttle_event__doc
[] = PyDoc_STR("perf throttle event object.");
202 static PyMemberDef pyrf_throttle_event__members
[] = {
204 member_def(perf_event_header
, type
, T_UINT
, "event type"),
205 member_def(perf_record_throttle
, time
, T_ULONGLONG
, "timestamp"),
206 member_def(perf_record_throttle
, id
, T_ULONGLONG
, "event id"),
207 member_def(perf_record_throttle
, stream_id
, T_ULONGLONG
, "event stream id"),
211 static PyObject
*pyrf_throttle_event__repr(struct pyrf_event
*pevent
)
213 struct perf_record_throttle
*te
= (struct perf_record_throttle
*)(&pevent
->event
.header
+ 1);
215 return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64
", id: %" PRI_lu64
216 ", stream_id: %" PRI_lu64
" }",
217 pevent
->event
.header
.type
== PERF_RECORD_THROTTLE
? "" : "un",
218 te
->time
, te
->id
, te
->stream_id
);
221 static PyTypeObject pyrf_throttle_event__type
= {
222 PyVarObject_HEAD_INIT(NULL
, 0)
223 .tp_name
= "perf.throttle_event",
224 .tp_basicsize
= sizeof(struct pyrf_event
),
225 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
226 .tp_doc
= pyrf_throttle_event__doc
,
227 .tp_members
= pyrf_throttle_event__members
,
228 .tp_repr
= (reprfunc
)pyrf_throttle_event__repr
,
231 static char pyrf_lost_event__doc
[] = PyDoc_STR("perf lost event object.");
233 static PyMemberDef pyrf_lost_event__members
[] = {
235 member_def(perf_record_lost
, id
, T_ULONGLONG
, "event id"),
236 member_def(perf_record_lost
, lost
, T_ULONGLONG
, "number of lost events"),
240 static PyObject
*pyrf_lost_event__repr(struct pyrf_event
*pevent
)
245 if (asprintf(&s
, "{ type: lost, id: %#" PRI_lx64
", "
246 "lost: %#" PRI_lx64
" }",
247 pevent
->event
.lost
.id
, pevent
->event
.lost
.lost
) < 0) {
248 ret
= PyErr_NoMemory();
250 ret
= _PyUnicode_FromString(s
);
256 static PyTypeObject pyrf_lost_event__type
= {
257 PyVarObject_HEAD_INIT(NULL
, 0)
258 .tp_name
= "perf.lost_event",
259 .tp_basicsize
= sizeof(struct pyrf_event
),
260 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
261 .tp_doc
= pyrf_lost_event__doc
,
262 .tp_members
= pyrf_lost_event__members
,
263 .tp_repr
= (reprfunc
)pyrf_lost_event__repr
,
266 static char pyrf_read_event__doc
[] = PyDoc_STR("perf read event object.");
268 static PyMemberDef pyrf_read_event__members
[] = {
270 member_def(perf_record_read
, pid
, T_UINT
, "event pid"),
271 member_def(perf_record_read
, tid
, T_UINT
, "event tid"),
275 static PyObject
*pyrf_read_event__repr(struct pyrf_event
*pevent
)
277 return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
278 pevent
->event
.read
.pid
,
279 pevent
->event
.read
.tid
);
281 * FIXME: return the array of read values,
282 * making this method useful ;-)
286 static PyTypeObject pyrf_read_event__type
= {
287 PyVarObject_HEAD_INIT(NULL
, 0)
288 .tp_name
= "perf.read_event",
289 .tp_basicsize
= sizeof(struct pyrf_event
),
290 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
291 .tp_doc
= pyrf_read_event__doc
,
292 .tp_members
= pyrf_read_event__members
,
293 .tp_repr
= (reprfunc
)pyrf_read_event__repr
,
296 static char pyrf_sample_event__doc
[] = PyDoc_STR("perf sample event object.");
298 static PyMemberDef pyrf_sample_event__members
[] = {
300 member_def(perf_event_header
, type
, T_UINT
, "event type"),
304 static PyObject
*pyrf_sample_event__repr(struct pyrf_event
*pevent
)
309 if (asprintf(&s
, "{ type: sample }") < 0) {
310 ret
= PyErr_NoMemory();
312 ret
= _PyUnicode_FromString(s
);
318 #ifdef HAVE_LIBTRACEEVENT
319 static bool is_tracepoint(struct pyrf_event
*pevent
)
321 return pevent
->evsel
->core
.attr
.type
== PERF_TYPE_TRACEPOINT
;
325 tracepoint_field(struct pyrf_event
*pe
, struct tep_format_field
*field
)
327 struct tep_handle
*pevent
= field
->event
->tep
;
328 void *data
= pe
->sample
.raw_data
;
329 PyObject
*ret
= NULL
;
330 unsigned long long val
;
331 unsigned int offset
, len
;
333 if (field
->flags
& TEP_FIELD_IS_ARRAY
) {
334 offset
= field
->offset
;
336 if (field
->flags
& TEP_FIELD_IS_DYNAMIC
) {
337 val
= tep_read_number(pevent
, data
+ offset
, len
);
341 if (tep_field_is_relative(field
->flags
))
342 offset
+= field
->offset
+ field
->size
;
344 if (field
->flags
& TEP_FIELD_IS_STRING
&&
345 is_printable_array(data
+ offset
, len
)) {
346 ret
= _PyUnicode_FromString((char *)data
+ offset
);
348 ret
= PyByteArray_FromStringAndSize((const char *) data
+ offset
, len
);
349 field
->flags
&= ~TEP_FIELD_IS_STRING
;
352 val
= tep_read_number(pevent
, data
+ field
->offset
,
354 if (field
->flags
& TEP_FIELD_IS_POINTER
)
355 ret
= PyLong_FromUnsignedLong((unsigned long) val
);
356 else if (field
->flags
& TEP_FIELD_IS_SIGNED
)
357 ret
= PyLong_FromLong((long) val
);
359 ret
= PyLong_FromUnsignedLong((unsigned long) val
);
366 get_tracepoint_field(struct pyrf_event
*pevent
, PyObject
*attr_name
)
368 const char *str
= _PyUnicode_AsString(PyObject_Str(attr_name
));
369 struct evsel
*evsel
= pevent
->evsel
;
370 struct tep_format_field
*field
;
372 if (!evsel
->tp_format
) {
373 struct tep_event
*tp_format
;
375 tp_format
= trace_event__tp_format_id(evsel
->core
.attr
.config
);
376 if (IS_ERR_OR_NULL(tp_format
))
379 evsel
->tp_format
= tp_format
;
382 field
= tep_find_any_field(evsel
->tp_format
, str
);
386 return tracepoint_field(pevent
, field
);
388 #endif /* HAVE_LIBTRACEEVENT */
391 pyrf_sample_event__getattro(struct pyrf_event
*pevent
, PyObject
*attr_name
)
393 PyObject
*obj
= NULL
;
395 #ifdef HAVE_LIBTRACEEVENT
396 if (is_tracepoint(pevent
))
397 obj
= get_tracepoint_field(pevent
, attr_name
);
400 return obj
?: PyObject_GenericGetAttr((PyObject
*) pevent
, attr_name
);
403 static PyTypeObject pyrf_sample_event__type
= {
404 PyVarObject_HEAD_INIT(NULL
, 0)
405 .tp_name
= "perf.sample_event",
406 .tp_basicsize
= sizeof(struct pyrf_event
),
407 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
408 .tp_doc
= pyrf_sample_event__doc
,
409 .tp_members
= pyrf_sample_event__members
,
410 .tp_repr
= (reprfunc
)pyrf_sample_event__repr
,
411 .tp_getattro
= (getattrofunc
) pyrf_sample_event__getattro
,
414 static char pyrf_context_switch_event__doc
[] = PyDoc_STR("perf context_switch event object.");
416 static PyMemberDef pyrf_context_switch_event__members
[] = {
418 member_def(perf_event_header
, type
, T_UINT
, "event type"),
419 member_def(perf_record_switch
, next_prev_pid
, T_UINT
, "next/prev pid"),
420 member_def(perf_record_switch
, next_prev_tid
, T_UINT
, "next/prev tid"),
424 static PyObject
*pyrf_context_switch_event__repr(struct pyrf_event
*pevent
)
429 if (asprintf(&s
, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
430 pevent
->event
.context_switch
.next_prev_pid
,
431 pevent
->event
.context_switch
.next_prev_tid
,
432 !!(pevent
->event
.header
.misc
& PERF_RECORD_MISC_SWITCH_OUT
)) < 0) {
433 ret
= PyErr_NoMemory();
435 ret
= _PyUnicode_FromString(s
);
441 static PyTypeObject pyrf_context_switch_event__type
= {
442 PyVarObject_HEAD_INIT(NULL
, 0)
443 .tp_name
= "perf.context_switch_event",
444 .tp_basicsize
= sizeof(struct pyrf_event
),
445 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
446 .tp_doc
= pyrf_context_switch_event__doc
,
447 .tp_members
= pyrf_context_switch_event__members
,
448 .tp_repr
= (reprfunc
)pyrf_context_switch_event__repr
,
451 static int pyrf_event__setup_types(void)
454 pyrf_mmap_event__type
.tp_new
=
455 pyrf_task_event__type
.tp_new
=
456 pyrf_comm_event__type
.tp_new
=
457 pyrf_lost_event__type
.tp_new
=
458 pyrf_read_event__type
.tp_new
=
459 pyrf_sample_event__type
.tp_new
=
460 pyrf_context_switch_event__type
.tp_new
=
461 pyrf_throttle_event__type
.tp_new
= PyType_GenericNew
;
462 err
= PyType_Ready(&pyrf_mmap_event__type
);
465 err
= PyType_Ready(&pyrf_lost_event__type
);
468 err
= PyType_Ready(&pyrf_task_event__type
);
471 err
= PyType_Ready(&pyrf_comm_event__type
);
474 err
= PyType_Ready(&pyrf_throttle_event__type
);
477 err
= PyType_Ready(&pyrf_read_event__type
);
480 err
= PyType_Ready(&pyrf_sample_event__type
);
483 err
= PyType_Ready(&pyrf_context_switch_event__type
);
490 static PyTypeObject
*pyrf_event__type
[] = {
491 [PERF_RECORD_MMAP
] = &pyrf_mmap_event__type
,
492 [PERF_RECORD_LOST
] = &pyrf_lost_event__type
,
493 [PERF_RECORD_COMM
] = &pyrf_comm_event__type
,
494 [PERF_RECORD_EXIT
] = &pyrf_task_event__type
,
495 [PERF_RECORD_THROTTLE
] = &pyrf_throttle_event__type
,
496 [PERF_RECORD_UNTHROTTLE
] = &pyrf_throttle_event__type
,
497 [PERF_RECORD_FORK
] = &pyrf_task_event__type
,
498 [PERF_RECORD_READ
] = &pyrf_read_event__type
,
499 [PERF_RECORD_SAMPLE
] = &pyrf_sample_event__type
,
500 [PERF_RECORD_SWITCH
] = &pyrf_context_switch_event__type
,
501 [PERF_RECORD_SWITCH_CPU_WIDE
] = &pyrf_context_switch_event__type
,
504 static PyObject
*pyrf_event__new(union perf_event
*event
)
506 struct pyrf_event
*pevent
;
509 if ((event
->header
.type
< PERF_RECORD_MMAP
||
510 event
->header
.type
> PERF_RECORD_SAMPLE
) &&
511 !(event
->header
.type
== PERF_RECORD_SWITCH
||
512 event
->header
.type
== PERF_RECORD_SWITCH_CPU_WIDE
))
515 ptype
= pyrf_event__type
[event
->header
.type
];
516 pevent
= PyObject_New(struct pyrf_event
, ptype
);
518 memcpy(&pevent
->event
, event
, event
->header
.size
);
519 return (PyObject
*)pevent
;
522 struct pyrf_cpu_map
{
525 struct perf_cpu_map
*cpus
;
528 static int pyrf_cpu_map__init(struct pyrf_cpu_map
*pcpus
,
529 PyObject
*args
, PyObject
*kwargs
)
531 static char *kwlist
[] = { "cpustr", NULL
};
534 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|s",
538 pcpus
->cpus
= perf_cpu_map__new(cpustr
);
539 if (pcpus
->cpus
== NULL
)
544 static void pyrf_cpu_map__delete(struct pyrf_cpu_map
*pcpus
)
546 perf_cpu_map__put(pcpus
->cpus
);
547 Py_TYPE(pcpus
)->tp_free((PyObject
*)pcpus
);
550 static Py_ssize_t
pyrf_cpu_map__length(PyObject
*obj
)
552 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
554 return perf_cpu_map__nr(pcpus
->cpus
);
557 static PyObject
*pyrf_cpu_map__item(PyObject
*obj
, Py_ssize_t i
)
559 struct pyrf_cpu_map
*pcpus
= (void *)obj
;
561 if (i
>= perf_cpu_map__nr(pcpus
->cpus
))
564 return Py_BuildValue("i", perf_cpu_map__cpu(pcpus
->cpus
, i
).cpu
);
567 static PySequenceMethods pyrf_cpu_map__sequence_methods
= {
568 .sq_length
= pyrf_cpu_map__length
,
569 .sq_item
= pyrf_cpu_map__item
,
572 static char pyrf_cpu_map__doc
[] = PyDoc_STR("cpu map object.");
574 static PyTypeObject pyrf_cpu_map__type
= {
575 PyVarObject_HEAD_INIT(NULL
, 0)
576 .tp_name
= "perf.cpu_map",
577 .tp_basicsize
= sizeof(struct pyrf_cpu_map
),
578 .tp_dealloc
= (destructor
)pyrf_cpu_map__delete
,
579 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
580 .tp_doc
= pyrf_cpu_map__doc
,
581 .tp_as_sequence
= &pyrf_cpu_map__sequence_methods
,
582 .tp_init
= (initproc
)pyrf_cpu_map__init
,
585 static int pyrf_cpu_map__setup_types(void)
587 pyrf_cpu_map__type
.tp_new
= PyType_GenericNew
;
588 return PyType_Ready(&pyrf_cpu_map__type
);
591 struct pyrf_thread_map
{
594 struct perf_thread_map
*threads
;
597 static int pyrf_thread_map__init(struct pyrf_thread_map
*pthreads
,
598 PyObject
*args
, PyObject
*kwargs
)
600 static char *kwlist
[] = { "pid", "tid", "uid", NULL
};
601 int pid
= -1, tid
= -1, uid
= UINT_MAX
;
603 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|iii",
604 kwlist
, &pid
, &tid
, &uid
))
607 pthreads
->threads
= thread_map__new(pid
, tid
, uid
);
608 if (pthreads
->threads
== NULL
)
613 static void pyrf_thread_map__delete(struct pyrf_thread_map
*pthreads
)
615 perf_thread_map__put(pthreads
->threads
);
616 Py_TYPE(pthreads
)->tp_free((PyObject
*)pthreads
);
619 static Py_ssize_t
pyrf_thread_map__length(PyObject
*obj
)
621 struct pyrf_thread_map
*pthreads
= (void *)obj
;
623 return perf_thread_map__nr(pthreads
->threads
);
626 static PyObject
*pyrf_thread_map__item(PyObject
*obj
, Py_ssize_t i
)
628 struct pyrf_thread_map
*pthreads
= (void *)obj
;
630 if (i
>= perf_thread_map__nr(pthreads
->threads
))
633 return Py_BuildValue("i", perf_thread_map__pid(pthreads
->threads
, i
));
636 static PySequenceMethods pyrf_thread_map__sequence_methods
= {
637 .sq_length
= pyrf_thread_map__length
,
638 .sq_item
= pyrf_thread_map__item
,
641 static char pyrf_thread_map__doc
[] = PyDoc_STR("thread map object.");
643 static PyTypeObject pyrf_thread_map__type
= {
644 PyVarObject_HEAD_INIT(NULL
, 0)
645 .tp_name
= "perf.thread_map",
646 .tp_basicsize
= sizeof(struct pyrf_thread_map
),
647 .tp_dealloc
= (destructor
)pyrf_thread_map__delete
,
648 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
649 .tp_doc
= pyrf_thread_map__doc
,
650 .tp_as_sequence
= &pyrf_thread_map__sequence_methods
,
651 .tp_init
= (initproc
)pyrf_thread_map__init
,
654 static int pyrf_thread_map__setup_types(void)
656 pyrf_thread_map__type
.tp_new
= PyType_GenericNew
;
657 return PyType_Ready(&pyrf_thread_map__type
);
666 static int pyrf_evsel__init(struct pyrf_evsel
*pevsel
,
667 PyObject
*args
, PyObject
*kwargs
)
669 struct perf_event_attr attr
= {
670 .type
= PERF_TYPE_HARDWARE
,
671 .config
= PERF_COUNT_HW_CPU_CYCLES
,
672 .sample_type
= PERF_SAMPLE_PERIOD
| PERF_SAMPLE_TID
,
674 static char *kwlist
[] = {
706 u64 sample_period
= 0;
728 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
,
729 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist
,
730 &attr
.type
, &attr
.config
, &attr
.sample_freq
,
731 &sample_period
, &attr
.sample_type
,
732 &attr
.read_format
, &disabled
, &inherit
,
733 &pinned
, &exclusive
, &exclude_user
,
734 &exclude_kernel
, &exclude_hv
, &exclude_idle
,
735 &mmap
, &context_switch
, &comm
, &freq
, &inherit_stat
,
736 &enable_on_exec
, &task
, &watermark
,
737 &precise_ip
, &mmap_data
, &sample_id_all
,
738 &attr
.wakeup_events
, &attr
.bp_type
,
739 &attr
.bp_addr
, &attr
.bp_len
, &idx
))
743 if (sample_period
!= 0) {
744 if (attr
.sample_freq
!= 0)
745 return -1; /* FIXME: throw right exception */
746 attr
.sample_period
= sample_period
;
750 attr
.disabled
= disabled
;
751 attr
.inherit
= inherit
;
752 attr
.pinned
= pinned
;
753 attr
.exclusive
= exclusive
;
754 attr
.exclude_user
= exclude_user
;
755 attr
.exclude_kernel
= exclude_kernel
;
756 attr
.exclude_hv
= exclude_hv
;
757 attr
.exclude_idle
= exclude_idle
;
759 attr
.context_switch
= context_switch
;
762 attr
.inherit_stat
= inherit_stat
;
763 attr
.enable_on_exec
= enable_on_exec
;
765 attr
.watermark
= watermark
;
766 attr
.precise_ip
= precise_ip
;
767 attr
.mmap_data
= mmap_data
;
768 attr
.sample_id_all
= sample_id_all
;
769 attr
.size
= sizeof(attr
);
771 evsel__init(&pevsel
->evsel
, &attr
, idx
);
775 static void pyrf_evsel__delete(struct pyrf_evsel
*pevsel
)
777 evsel__exit(&pevsel
->evsel
);
778 Py_TYPE(pevsel
)->tp_free((PyObject
*)pevsel
);
781 static PyObject
*pyrf_evsel__open(struct pyrf_evsel
*pevsel
,
782 PyObject
*args
, PyObject
*kwargs
)
784 struct evsel
*evsel
= &pevsel
->evsel
;
785 struct perf_cpu_map
*cpus
= NULL
;
786 struct perf_thread_map
*threads
= NULL
;
787 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
788 int group
= 0, inherit
= 0;
789 static char *kwlist
[] = { "cpus", "threads", "group", "inherit", NULL
};
791 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|OOii", kwlist
,
792 &pcpus
, &pthreads
, &group
, &inherit
))
795 if (pthreads
!= NULL
)
796 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
799 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
801 evsel
->core
.attr
.inherit
= inherit
;
803 * This will group just the fds for this single evsel, to group
804 * multiple events, use evlist.open().
806 if (evsel__open(evsel
, cpus
, threads
) < 0) {
807 PyErr_SetFromErrno(PyExc_OSError
);
815 static PyMethodDef pyrf_evsel__methods
[] = {
818 .ml_meth
= (PyCFunction
)pyrf_evsel__open
,
819 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
820 .ml_doc
= PyDoc_STR("open the event selector file descriptor table.")
825 static char pyrf_evsel__doc
[] = PyDoc_STR("perf event selector list object.");
827 static PyTypeObject pyrf_evsel__type
= {
828 PyVarObject_HEAD_INIT(NULL
, 0)
829 .tp_name
= "perf.evsel",
830 .tp_basicsize
= sizeof(struct pyrf_evsel
),
831 .tp_dealloc
= (destructor
)pyrf_evsel__delete
,
832 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
833 .tp_doc
= pyrf_evsel__doc
,
834 .tp_methods
= pyrf_evsel__methods
,
835 .tp_init
= (initproc
)pyrf_evsel__init
,
838 static int pyrf_evsel__setup_types(void)
840 pyrf_evsel__type
.tp_new
= PyType_GenericNew
;
841 return PyType_Ready(&pyrf_evsel__type
);
847 struct evlist evlist
;
850 static int pyrf_evlist__init(struct pyrf_evlist
*pevlist
,
851 PyObject
*args
, PyObject
*kwargs __maybe_unused
)
853 PyObject
*pcpus
= NULL
, *pthreads
= NULL
;
854 struct perf_cpu_map
*cpus
;
855 struct perf_thread_map
*threads
;
857 if (!PyArg_ParseTuple(args
, "OO", &pcpus
, &pthreads
))
860 threads
= ((struct pyrf_thread_map
*)pthreads
)->threads
;
861 cpus
= ((struct pyrf_cpu_map
*)pcpus
)->cpus
;
862 evlist__init(&pevlist
->evlist
, cpus
, threads
);
866 static void pyrf_evlist__delete(struct pyrf_evlist
*pevlist
)
868 evlist__exit(&pevlist
->evlist
);
869 Py_TYPE(pevlist
)->tp_free((PyObject
*)pevlist
);
872 static PyObject
*pyrf_evlist__mmap(struct pyrf_evlist
*pevlist
,
873 PyObject
*args
, PyObject
*kwargs
)
875 struct evlist
*evlist
= &pevlist
->evlist
;
876 static char *kwlist
[] = { "pages", "overwrite", NULL
};
877 int pages
= 128, overwrite
= false;
879 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ii", kwlist
,
883 if (evlist__mmap(evlist
, pages
) < 0) {
884 PyErr_SetFromErrno(PyExc_OSError
);
892 static PyObject
*pyrf_evlist__poll(struct pyrf_evlist
*pevlist
,
893 PyObject
*args
, PyObject
*kwargs
)
895 struct evlist
*evlist
= &pevlist
->evlist
;
896 static char *kwlist
[] = { "timeout", NULL
};
899 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|i", kwlist
, &timeout
))
902 n
= evlist__poll(evlist
, timeout
);
904 PyErr_SetFromErrno(PyExc_OSError
);
908 return Py_BuildValue("i", n
);
911 static PyObject
*pyrf_evlist__get_pollfd(struct pyrf_evlist
*pevlist
,
912 PyObject
*args __maybe_unused
,
913 PyObject
*kwargs __maybe_unused
)
915 struct evlist
*evlist
= &pevlist
->evlist
;
916 PyObject
*list
= PyList_New(0);
919 for (i
= 0; i
< evlist
->core
.pollfd
.nr
; ++i
) {
921 #if PY_MAJOR_VERSION < 3
922 FILE *fp
= fdopen(evlist
->core
.pollfd
.entries
[i
].fd
, "r");
927 file
= PyFile_FromFile(fp
, "perf", "r", NULL
);
929 file
= PyFile_FromFd(evlist
->core
.pollfd
.entries
[i
].fd
, "perf", "r", -1,
930 NULL
, NULL
, NULL
, 0);
935 if (PyList_Append(list
, file
) != 0) {
945 return PyErr_NoMemory();
949 static PyObject
*pyrf_evlist__add(struct pyrf_evlist
*pevlist
,
951 PyObject
*kwargs __maybe_unused
)
953 struct evlist
*evlist
= &pevlist
->evlist
;
957 if (!PyArg_ParseTuple(args
, "O", &pevsel
))
961 evsel
= &((struct pyrf_evsel
*)pevsel
)->evsel
;
962 evsel
->core
.idx
= evlist
->core
.nr_entries
;
963 evlist__add(evlist
, evsel
);
965 return Py_BuildValue("i", evlist
->core
.nr_entries
);
968 static struct mmap
*get_md(struct evlist
*evlist
, int cpu
)
972 for (i
= 0; i
< evlist
->core
.nr_mmaps
; i
++) {
973 struct mmap
*md
= &evlist
->mmap
[i
];
975 if (md
->core
.cpu
.cpu
== cpu
)
982 static PyObject
*pyrf_evlist__read_on_cpu(struct pyrf_evlist
*pevlist
,
983 PyObject
*args
, PyObject
*kwargs
)
985 struct evlist
*evlist
= &pevlist
->evlist
;
986 union perf_event
*event
;
987 int sample_id_all
= 1, cpu
;
988 static char *kwlist
[] = { "cpu", "sample_id_all", NULL
};
992 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "i|i", kwlist
,
993 &cpu
, &sample_id_all
))
996 md
= get_md(evlist
, cpu
);
1000 if (perf_mmap__read_init(&md
->core
) < 0)
1003 event
= perf_mmap__read_event(&md
->core
);
1004 if (event
!= NULL
) {
1005 PyObject
*pyevent
= pyrf_event__new(event
);
1006 struct pyrf_event
*pevent
= (struct pyrf_event
*)pyevent
;
1007 struct evsel
*evsel
;
1009 if (pyevent
== NULL
)
1010 return PyErr_NoMemory();
1012 evsel
= evlist__event2evsel(evlist
, event
);
1018 pevent
->evsel
= evsel
;
1020 err
= evsel__parse_sample(evsel
, event
, &pevent
->sample
);
1022 /* Consume the even only after we parsed it out. */
1023 perf_mmap__consume(&md
->core
);
1026 return PyErr_Format(PyExc_OSError
,
1027 "perf: can't parse sample, err=%d", err
);
1035 static PyObject
*pyrf_evlist__open(struct pyrf_evlist
*pevlist
,
1036 PyObject
*args
, PyObject
*kwargs
)
1038 struct evlist
*evlist
= &pevlist
->evlist
;
1040 if (evlist__open(evlist
) < 0) {
1041 PyErr_SetFromErrno(PyExc_OSError
);
1049 static PyMethodDef pyrf_evlist__methods
[] = {
1052 .ml_meth
= (PyCFunction
)pyrf_evlist__mmap
,
1053 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1054 .ml_doc
= PyDoc_STR("mmap the file descriptor table.")
1058 .ml_meth
= (PyCFunction
)pyrf_evlist__open
,
1059 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1060 .ml_doc
= PyDoc_STR("open the file descriptors.")
1064 .ml_meth
= (PyCFunction
)pyrf_evlist__poll
,
1065 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1066 .ml_doc
= PyDoc_STR("poll the file descriptor table.")
1069 .ml_name
= "get_pollfd",
1070 .ml_meth
= (PyCFunction
)pyrf_evlist__get_pollfd
,
1071 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1072 .ml_doc
= PyDoc_STR("get the poll file descriptor table.")
1076 .ml_meth
= (PyCFunction
)pyrf_evlist__add
,
1077 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1078 .ml_doc
= PyDoc_STR("adds an event selector to the list.")
1081 .ml_name
= "read_on_cpu",
1082 .ml_meth
= (PyCFunction
)pyrf_evlist__read_on_cpu
,
1083 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1084 .ml_doc
= PyDoc_STR("reads an event.")
1086 { .ml_name
= NULL
, }
1089 static Py_ssize_t
pyrf_evlist__length(PyObject
*obj
)
1091 struct pyrf_evlist
*pevlist
= (void *)obj
;
1093 return pevlist
->evlist
.core
.nr_entries
;
1096 static PyObject
*pyrf_evlist__item(PyObject
*obj
, Py_ssize_t i
)
1098 struct pyrf_evlist
*pevlist
= (void *)obj
;
1101 if (i
>= pevlist
->evlist
.core
.nr_entries
)
1104 evlist__for_each_entry(&pevlist
->evlist
, pos
) {
1109 return Py_BuildValue("O", container_of(pos
, struct pyrf_evsel
, evsel
));
1112 static PySequenceMethods pyrf_evlist__sequence_methods
= {
1113 .sq_length
= pyrf_evlist__length
,
1114 .sq_item
= pyrf_evlist__item
,
1117 static char pyrf_evlist__doc
[] = PyDoc_STR("perf event selector list object.");
1119 static PyTypeObject pyrf_evlist__type
= {
1120 PyVarObject_HEAD_INIT(NULL
, 0)
1121 .tp_name
= "perf.evlist",
1122 .tp_basicsize
= sizeof(struct pyrf_evlist
),
1123 .tp_dealloc
= (destructor
)pyrf_evlist__delete
,
1124 .tp_flags
= Py_TPFLAGS_DEFAULT
|Py_TPFLAGS_BASETYPE
,
1125 .tp_as_sequence
= &pyrf_evlist__sequence_methods
,
1126 .tp_doc
= pyrf_evlist__doc
,
1127 .tp_methods
= pyrf_evlist__methods
,
1128 .tp_init
= (initproc
)pyrf_evlist__init
,
1131 static int pyrf_evlist__setup_types(void)
1133 pyrf_evlist__type
.tp_new
= PyType_GenericNew
;
1134 return PyType_Ready(&pyrf_evlist__type
);
1137 #define PERF_CONST(name) { #name, PERF_##name }
1142 } perf__constants
[] = {
1143 PERF_CONST(TYPE_HARDWARE
),
1144 PERF_CONST(TYPE_SOFTWARE
),
1145 PERF_CONST(TYPE_TRACEPOINT
),
1146 PERF_CONST(TYPE_HW_CACHE
),
1147 PERF_CONST(TYPE_RAW
),
1148 PERF_CONST(TYPE_BREAKPOINT
),
1150 PERF_CONST(COUNT_HW_CPU_CYCLES
),
1151 PERF_CONST(COUNT_HW_INSTRUCTIONS
),
1152 PERF_CONST(COUNT_HW_CACHE_REFERENCES
),
1153 PERF_CONST(COUNT_HW_CACHE_MISSES
),
1154 PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS
),
1155 PERF_CONST(COUNT_HW_BRANCH_MISSES
),
1156 PERF_CONST(COUNT_HW_BUS_CYCLES
),
1157 PERF_CONST(COUNT_HW_CACHE_L1D
),
1158 PERF_CONST(COUNT_HW_CACHE_L1I
),
1159 PERF_CONST(COUNT_HW_CACHE_LL
),
1160 PERF_CONST(COUNT_HW_CACHE_DTLB
),
1161 PERF_CONST(COUNT_HW_CACHE_ITLB
),
1162 PERF_CONST(COUNT_HW_CACHE_BPU
),
1163 PERF_CONST(COUNT_HW_CACHE_OP_READ
),
1164 PERF_CONST(COUNT_HW_CACHE_OP_WRITE
),
1165 PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH
),
1166 PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS
),
1167 PERF_CONST(COUNT_HW_CACHE_RESULT_MISS
),
1169 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND
),
1170 PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND
),
1172 PERF_CONST(COUNT_SW_CPU_CLOCK
),
1173 PERF_CONST(COUNT_SW_TASK_CLOCK
),
1174 PERF_CONST(COUNT_SW_PAGE_FAULTS
),
1175 PERF_CONST(COUNT_SW_CONTEXT_SWITCHES
),
1176 PERF_CONST(COUNT_SW_CPU_MIGRATIONS
),
1177 PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN
),
1178 PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ
),
1179 PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS
),
1180 PERF_CONST(COUNT_SW_EMULATION_FAULTS
),
1181 PERF_CONST(COUNT_SW_DUMMY
),
1183 PERF_CONST(SAMPLE_IP
),
1184 PERF_CONST(SAMPLE_TID
),
1185 PERF_CONST(SAMPLE_TIME
),
1186 PERF_CONST(SAMPLE_ADDR
),
1187 PERF_CONST(SAMPLE_READ
),
1188 PERF_CONST(SAMPLE_CALLCHAIN
),
1189 PERF_CONST(SAMPLE_ID
),
1190 PERF_CONST(SAMPLE_CPU
),
1191 PERF_CONST(SAMPLE_PERIOD
),
1192 PERF_CONST(SAMPLE_STREAM_ID
),
1193 PERF_CONST(SAMPLE_RAW
),
1195 PERF_CONST(FORMAT_TOTAL_TIME_ENABLED
),
1196 PERF_CONST(FORMAT_TOTAL_TIME_RUNNING
),
1197 PERF_CONST(FORMAT_ID
),
1198 PERF_CONST(FORMAT_GROUP
),
1200 PERF_CONST(RECORD_MMAP
),
1201 PERF_CONST(RECORD_LOST
),
1202 PERF_CONST(RECORD_COMM
),
1203 PERF_CONST(RECORD_EXIT
),
1204 PERF_CONST(RECORD_THROTTLE
),
1205 PERF_CONST(RECORD_UNTHROTTLE
),
1206 PERF_CONST(RECORD_FORK
),
1207 PERF_CONST(RECORD_READ
),
1208 PERF_CONST(RECORD_SAMPLE
),
1209 PERF_CONST(RECORD_MMAP2
),
1210 PERF_CONST(RECORD_AUX
),
1211 PERF_CONST(RECORD_ITRACE_START
),
1212 PERF_CONST(RECORD_LOST_SAMPLES
),
1213 PERF_CONST(RECORD_SWITCH
),
1214 PERF_CONST(RECORD_SWITCH_CPU_WIDE
),
1216 PERF_CONST(RECORD_MISC_SWITCH_OUT
),
1220 static PyObject
*pyrf__tracepoint(struct pyrf_evsel
*pevsel
,
1221 PyObject
*args
, PyObject
*kwargs
)
1223 #ifndef HAVE_LIBTRACEEVENT
1226 struct tep_event
*tp_format
;
1227 static char *kwlist
[] = { "sys", "name", NULL
};
1231 if (!PyArg_ParseTupleAndKeywords(args
, kwargs
, "|ss", kwlist
,
1235 tp_format
= trace_event__tp_format(sys
, name
);
1236 if (IS_ERR(tp_format
))
1237 return _PyLong_FromLong(-1);
1239 return _PyLong_FromLong(tp_format
->id
);
1240 #endif // HAVE_LIBTRACEEVENT
1243 static PyMethodDef perf__methods
[] = {
1245 .ml_name
= "tracepoint",
1246 .ml_meth
= (PyCFunction
) pyrf__tracepoint
,
1247 .ml_flags
= METH_VARARGS
| METH_KEYWORDS
,
1248 .ml_doc
= PyDoc_STR("Get tracepoint config.")
1250 { .ml_name
= NULL
, }
1253 #if PY_MAJOR_VERSION < 3
1254 PyMODINIT_FUNC
initperf(void)
1256 PyMODINIT_FUNC
PyInit_perf(void)
1262 #if PY_MAJOR_VERSION < 3
1263 PyObject
*module
= Py_InitModule("perf", perf__methods
);
1265 static struct PyModuleDef moduledef
= {
1266 PyModuleDef_HEAD_INIT
,
1267 "perf", /* m_name */
1270 perf__methods
, /* m_methods */
1271 NULL
, /* m_reload */
1272 NULL
, /* m_traverse */
1276 PyObject
*module
= PyModule_Create(&moduledef
);
1279 if (module
== NULL
||
1280 pyrf_event__setup_types() < 0 ||
1281 pyrf_evlist__setup_types() < 0 ||
1282 pyrf_evsel__setup_types() < 0 ||
1283 pyrf_thread_map__setup_types() < 0 ||
1284 pyrf_cpu_map__setup_types() < 0)
1285 #if PY_MAJOR_VERSION < 3
1291 /* The page_size is placed in util object. */
1292 page_size
= sysconf(_SC_PAGE_SIZE
);
1294 Py_INCREF(&pyrf_evlist__type
);
1295 PyModule_AddObject(module
, "evlist", (PyObject
*)&pyrf_evlist__type
);
1297 Py_INCREF(&pyrf_evsel__type
);
1298 PyModule_AddObject(module
, "evsel", (PyObject
*)&pyrf_evsel__type
);
1300 Py_INCREF(&pyrf_mmap_event__type
);
1301 PyModule_AddObject(module
, "mmap_event", (PyObject
*)&pyrf_mmap_event__type
);
1303 Py_INCREF(&pyrf_lost_event__type
);
1304 PyModule_AddObject(module
, "lost_event", (PyObject
*)&pyrf_lost_event__type
);
1306 Py_INCREF(&pyrf_comm_event__type
);
1307 PyModule_AddObject(module
, "comm_event", (PyObject
*)&pyrf_comm_event__type
);
1309 Py_INCREF(&pyrf_task_event__type
);
1310 PyModule_AddObject(module
, "task_event", (PyObject
*)&pyrf_task_event__type
);
1312 Py_INCREF(&pyrf_throttle_event__type
);
1313 PyModule_AddObject(module
, "throttle_event", (PyObject
*)&pyrf_throttle_event__type
);
1315 Py_INCREF(&pyrf_task_event__type
);
1316 PyModule_AddObject(module
, "task_event", (PyObject
*)&pyrf_task_event__type
);
1318 Py_INCREF(&pyrf_read_event__type
);
1319 PyModule_AddObject(module
, "read_event", (PyObject
*)&pyrf_read_event__type
);
1321 Py_INCREF(&pyrf_sample_event__type
);
1322 PyModule_AddObject(module
, "sample_event", (PyObject
*)&pyrf_sample_event__type
);
1324 Py_INCREF(&pyrf_context_switch_event__type
);
1325 PyModule_AddObject(module
, "switch_event", (PyObject
*)&pyrf_context_switch_event__type
);
1327 Py_INCREF(&pyrf_thread_map__type
);
1328 PyModule_AddObject(module
, "thread_map", (PyObject
*)&pyrf_thread_map__type
);
1330 Py_INCREF(&pyrf_cpu_map__type
);
1331 PyModule_AddObject(module
, "cpu_map", (PyObject
*)&pyrf_cpu_map__type
);
1333 dict
= PyModule_GetDict(module
);
1337 for (i
= 0; perf__constants
[i
].name
!= NULL
; i
++) {
1338 obj
= _PyLong_FromLong(perf__constants
[i
].value
);
1341 PyDict_SetItemString(dict
, perf__constants
[i
].name
, obj
);
1346 if (PyErr_Occurred())
1347 PyErr_SetString(PyExc_ImportError
, "perf: Init failed!");
1348 #if PY_MAJOR_VERSION >= 3
1354 /* The following are stubs to avoid dragging in builtin-* objects. */
1355 /* TODO: move the code out of the builtin-* file into util. */
1357 unsigned int scripting_max_stack
= PERF_MAX_STACK_DEPTH
;
1359 #ifdef HAVE_KVM_STAT_SUPPORT
1360 bool kvm_entry_event(struct evsel
*evsel __maybe_unused
)
1365 bool kvm_exit_event(struct evsel
*evsel __maybe_unused
)
1370 bool exit_event_begin(struct evsel
*evsel __maybe_unused
,
1371 struct perf_sample
*sample __maybe_unused
,
1372 struct event_key
*key __maybe_unused
)
1377 bool exit_event_end(struct evsel
*evsel __maybe_unused
,
1378 struct perf_sample
*sample __maybe_unused
,
1379 struct event_key
*key __maybe_unused
)
1384 void exit_event_decode_key(struct perf_kvm_stat
*kvm __maybe_unused
,
1385 struct event_key
*key __maybe_unused
,
1386 char *decode __maybe_unused
)
1389 #endif // HAVE_KVM_STAT_SUPPORT
1391 int find_scripts(char **scripts_array __maybe_unused
, char **scripts_path_array __maybe_unused
,
1392 int num __maybe_unused
, int pathlen __maybe_unused
)
1397 void perf_stat__set_no_csv_summary(int set __maybe_unused
)
1401 void perf_stat__set_big_num(int set __maybe_unused
)
1405 int script_spec_register(const char *spec __maybe_unused
, struct scripting_ops
*ops __maybe_unused
)
1410 arch_syscalls__strerrno_t
*arch_syscalls__strerrno_function(const char *arch __maybe_unused
)
1415 struct kwork_work
*perf_kwork_add_work(struct perf_kwork
*kwork __maybe_unused
,
1416 struct kwork_class
*class __maybe_unused
,
1417 struct kwork_work
*key __maybe_unused
)
1422 void script_fetch_insn(struct perf_sample
*sample __maybe_unused
,
1423 struct thread
*thread __maybe_unused
,
1424 struct machine
*machine __maybe_unused
)
1428 int perf_sample__sprintf_flags(u32 flags __maybe_unused
, char *str __maybe_unused
,
1429 size_t sz __maybe_unused
)
1434 bool match_callstack_filter(struct machine
*machine __maybe_unused
, u64
*callstack __maybe_unused
)
1439 struct lock_stat
*lock_stat_find(u64 addr __maybe_unused
)
1444 struct lock_stat
*lock_stat_findnew(u64 addr __maybe_unused
, const char *name __maybe_unused
,
1445 int flags __maybe_unused
)
1450 int cmd_inject(int argc __maybe_unused
, const char *argv
[] __maybe_unused
)