xref: /linux/tools/perf/util/python.c (revision 473f6c8f437b049f8ec015d57cd59bb983b1d85c)
1 // SPDX-License-Identifier: GPL-2.0
2 #define PY_SSIZE_T_CLEAN
3 #include <Python.h>
4 
5 #include <inttypes.h>
6 #include <string.h>
7 
8 #include <linux/err.h>
9 #include <poll.h>
10 #include <unistd.h>
11 
12 #include <internal/lib.h>
13 #include <perf/cpumap.h>
14 #include <perf/mmap.h>
15 #include <structmember.h>
16 
17 #include "addr_location.h"
18 #include "build-id.h"
19 #include "callchain.h"
20 #include "comm.h"
21 #include "config.h"
22 #include "counts.h"
23 #include "data.h"
24 #include "debug.h"
25 #include "dso.h"
26 #include "dwarf-regs.h"
27 #include "event.h"
28 #include "branch.h"
29 #include "evlist.h"
30 #include "evsel.h"
31 #include "expr.h"
32 #include "map.h"
33 #include "metricgroup.h"
34 #include "mmap.h"
35 #include "pmus.h"
36 #include "print_binary.h"
37 #include "record.h"
38 #include "sample.h"
39 #include "session.h"
40 #include "srccode.h"
41 #include "srcline.h"
42 #include "strbuf.h"
43 #include "symbol.h"
44 #include "stat.h"
45 #include "header.h"
46 #include "trace/beauty/syscalltbl.h"
47 #include "thread.h"
48 #include "thread_map.h"
49 #include "tool.h"
50 #include "tp_pmu.h"
51 #include "trace-event.h"
52 
53 #ifdef HAVE_LIBTRACEEVENT
54 #include <event-parse.h>
55 #endif
56 
57 PyMODINIT_FUNC PyInit_perf(void);
58 
59 static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel);
60 
61 #define member_def(type, member, ptype, help) \
62 	{ #member, ptype, \
63 	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
64 	  0, help }
65 
66 #define sample_member_def(name, member, ptype, help) \
67 	{ #name, ptype, \
68 	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
69 	  0, help }
70 
71 #define CHECK_INITIALIZED(ptr, msg) \
72 	do { \
73 		if (!(ptr)) { \
74 			PyErr_SetString(PyExc_ValueError, msg " not initialized"); \
75 			return NULL; \
76 		} \
77 	} while (0)
78 
79 #define CHECK_INITIALIZED_INT(ptr, msg) \
80 	do { \
81 		if (!(ptr)) { \
82 			PyErr_SetString(PyExc_ValueError, msg " not initialized"); \
83 			return -1; \
84 		} \
85 	} while (0)
86 
87 struct pyrf_event {
88 	PyObject_HEAD
89 	/** @sample: The parsed sample from the event. */
90 	struct perf_sample sample;
91 	/** @al: The address location from machine__resolve, lazily computed. */
92 	struct addr_location al;
93 	/** @al_resolved: True when machine__resolve been called. */
94 	bool al_resolved;
95 	/** @callchain: Resolved callchain, eagerly computed if requested. */
96 	PyObject *callchain;
97 	/** @brstack: Resolved branch stack, eagerly computed if requested. */
98 	PyObject *brstack;
99 	/** @event: The underlying perf_event that may be in a file or ring buffer. */
100 	union perf_event event;
101 };
102 
103 #define sample_members \
104 	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
105 	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
106 	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
107 	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
108 	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
109 	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
110 	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
111 
112 static PyObject *pyrf_event__get_evsel(PyObject *self, void *closure __maybe_unused)
113 {
114 	struct pyrf_event *pevent = (void *)self;
115 
116 	if (!pevent->sample.evsel)
117 		Py_RETURN_NONE;
118 
119 	return pyrf_evsel__from_evsel(pevent->sample.evsel);
120 }
121 
122 static PyGetSetDef pyrf_event__getset[] = {
123 	{
124 		.name = "evsel",
125 		.get = pyrf_event__get_evsel,
126 		.set = NULL,
127 		.doc = "tracking event.",
128 	},
129 	{ .name = NULL, },
130 };
131 
132 static void pyrf_event__delete(struct pyrf_event *pevent)
133 {
134 	if (pevent->al_resolved)
135 		addr_location__exit(&pevent->al);
136 	Py_XDECREF(pevent->callchain);
137 	Py_XDECREF(pevent->brstack);
138 	perf_sample__exit(&pevent->sample);
139 	Py_TYPE(pevent)->tp_free((PyObject *)pevent);
140 }
141 
142 static const char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
143 
144 static PyMemberDef pyrf_mmap_event__members[] = {
145 	sample_members
146 	member_def(perf_event_header, type, T_UINT, "event type"),
147 	member_def(perf_event_header, misc, T_USHORT, "event misc"),
148 	member_def(perf_record_mmap, pid, T_UINT, "event pid"),
149 	member_def(perf_record_mmap, tid, T_UINT, "event tid"),
150 	member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"),
151 	member_def(perf_record_mmap, len, T_ULONGLONG, "map length"),
152 	member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"),
153 	member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"),
154 	{ .name = NULL, },
155 };
156 
157 static PyObject *pyrf_mmap_event__repr(const struct pyrf_event *pevent)
158 {
159 	PyObject *ret;
160 	char *s;
161 
162 	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", "
163 			 "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", "
164 			 "filename: %s }",
165 		     pevent->event.mmap.pid, pevent->event.mmap.tid,
166 		     pevent->event.mmap.start, pevent->event.mmap.len,
167 		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
168 		ret = PyErr_NoMemory();
169 	} else {
170 		ret = PyUnicode_FromString(s);
171 		free(s);
172 	}
173 	return ret;
174 }
175 
176 static PyTypeObject pyrf_mmap_event__type = {
177 	PyVarObject_HEAD_INIT(NULL, 0)
178 	.tp_name	= "perf.mmap_event",
179 	.tp_basicsize	= sizeof(struct pyrf_event),
180 	.tp_dealloc	= (destructor)pyrf_event__delete,
181 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
182 	.tp_doc		= pyrf_mmap_event__doc,
183 	.tp_members	= pyrf_mmap_event__members,
184 	.tp_getset	= pyrf_event__getset,
185 	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
186 };
187 
188 static const char pyrf_mmap2_event__doc[] = PyDoc_STR("perf mmap2 event object.");
189 
190 static PyObject *pyrf_mmap2_event__get_maj(PyObject *self, void *closure __maybe_unused)
191 {
192 	struct pyrf_event *pevent = (void *)self;
193 
194 	if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
195 		Py_RETURN_NONE;
196 
197 	return PyLong_FromUnsignedLong(pevent->event.mmap2.maj);
198 }
199 
200 static PyObject *pyrf_mmap2_event__get_min(PyObject *self, void *closure __maybe_unused)
201 {
202 	struct pyrf_event *pevent = (void *)self;
203 
204 	if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
205 		Py_RETURN_NONE;
206 
207 	return PyLong_FromUnsignedLong(pevent->event.mmap2.min);
208 }
209 
210 static PyObject *pyrf_mmap2_event__get_ino(PyObject *self, void *closure __maybe_unused)
211 {
212 	struct pyrf_event *pevent = (void *)self;
213 
214 	if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
215 		Py_RETURN_NONE;
216 
217 	return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino);
218 }
219 
220 static PyObject *pyrf_mmap2_event__get_ino_generation(PyObject *self, void *closure __maybe_unused)
221 {
222 	struct pyrf_event *pevent = (void *)self;
223 
224 	if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)
225 		Py_RETURN_NONE;
226 
227 	return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino_generation);
228 }
229 
230 static PyObject *pyrf_mmap2_event__get_build_id(PyObject *self, void *closure __maybe_unused)
231 {
232 	struct pyrf_event *pevent = (void *)self;
233 
234 	if (!(pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID))
235 		Py_RETURN_NONE;
236 
237 	int size = pevent->event.mmap2.build_id_size;
238 
239 	if (size > 20)
240 		size = 20;
241 
242 	return PyBytes_FromStringAndSize((const char *)pevent->event.mmap2.build_id, size);
243 }
244 
245 static PyGetSetDef pyrf_mmap2_event__getset[] = {
246 	{
247 		.name = "evsel",
248 		.get = pyrf_event__get_evsel,
249 		.set = NULL,
250 		.doc = "tracking event.",
251 	},
252 	{
253 		.name = "maj",
254 		.get = pyrf_mmap2_event__get_maj,
255 		.set = NULL,
256 		.doc = "major number.",
257 	},
258 	{
259 		.name = "min",
260 		.get = pyrf_mmap2_event__get_min,
261 		.set = NULL,
262 		.doc = "minor number.",
263 	},
264 	{
265 		.name = "ino",
266 		.get = pyrf_mmap2_event__get_ino,
267 		.set = NULL,
268 		.doc = "inode number.",
269 	},
270 	{
271 		.name = "ino_generation",
272 		.get = pyrf_mmap2_event__get_ino_generation,
273 		.set = NULL,
274 		.doc = "inode generation.",
275 	},
276 	{
277 		.name = "build_id",
278 		.get = pyrf_mmap2_event__get_build_id,
279 		.set = NULL,
280 		.doc = "binary build ID.",
281 	},
282 	{ .name = NULL, },
283 };
284 
285 static PyMemberDef pyrf_mmap2_event__members[] = {
286 	sample_members
287 	member_def(perf_event_header, type, T_UINT, "event type"),
288 	member_def(perf_event_header, misc, T_USHORT, "event misc"),
289 	member_def(perf_record_mmap2, pid, T_UINT, "event pid"),
290 	member_def(perf_record_mmap2, tid, T_UINT, "event tid"),
291 	member_def(perf_record_mmap2, start, T_ULONGLONG, "start of the map"),
292 	member_def(perf_record_mmap2, len, T_ULONGLONG, "map length"),
293 	member_def(perf_record_mmap2, pgoff, T_ULONGLONG, "page offset"),
294 	member_def(perf_record_mmap2, prot, T_UINT, "protection"),
295 	member_def(perf_record_mmap2, flags, T_UINT, "flags"),
296 	member_def(perf_record_mmap2, filename, T_STRING_INPLACE, "backing store"),
297 	{ .name = NULL, },
298 };
299 
300 static PyObject *pyrf_mmap2_event__repr(const struct pyrf_event *pevent)
301 {
302 	PyObject *ret;
303 	char *s;
304 
305 	if (asprintf(&s, "{ type: mmap2, pid: %u, tid: %u, start: %#" PRI_lx64 ", length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", flags: %#x, prot: %#x, filename: %s }",
306 		     pevent->event.mmap2.pid, pevent->event.mmap2.tid,
307 		     pevent->event.mmap2.start, pevent->event.mmap2.len,
308 		     pevent->event.mmap2.pgoff, pevent->event.mmap2.flags,
309 		     pevent->event.mmap2.prot, pevent->event.mmap2.filename) < 0)
310 		return PyErr_NoMemory();
311 
312 	ret = PyUnicode_FromString(s);
313 	free(s);
314 	return ret;
315 }
316 
317 static PyTypeObject pyrf_mmap2_event__type = {
318 	PyVarObject_HEAD_INIT(NULL, 0)
319 	.tp_name	= "perf.mmap2_event",
320 	.tp_basicsize	= sizeof(struct pyrf_event),
321 	.tp_dealloc	= (destructor)pyrf_event__delete,
322 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
323 	.tp_doc		= pyrf_mmap2_event__doc,
324 	.tp_members	= pyrf_mmap2_event__members,
325 	.tp_getset	= pyrf_mmap2_event__getset,
326 	.tp_repr	= (reprfunc)pyrf_mmap2_event__repr,
327 };
328 
329 static const char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
330 
331 static PyMemberDef pyrf_task_event__members[] = {
332 	sample_members
333 	member_def(perf_event_header, type, T_UINT, "event type"),
334 	member_def(perf_record_fork, pid, T_UINT, "event pid"),
335 	member_def(perf_record_fork, ppid, T_UINT, "event ppid"),
336 	member_def(perf_record_fork, tid, T_UINT, "event tid"),
337 	member_def(perf_record_fork, ptid, T_UINT, "event ptid"),
338 	member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"),
339 	{ .name = NULL, },
340 };
341 
342 static PyObject *pyrf_task_event__repr(const struct pyrf_event *pevent)
343 {
344 	return PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
345 				   "ptid: %u, time: %" PRI_lu64 "}",
346 				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
347 				   pevent->event.fork.pid,
348 				   pevent->event.fork.ppid,
349 				   pevent->event.fork.tid,
350 				   pevent->event.fork.ptid,
351 				   pevent->event.fork.time);
352 }
353 
354 static PyTypeObject pyrf_task_event__type = {
355 	PyVarObject_HEAD_INIT(NULL, 0)
356 	.tp_name	= "perf.task_event",
357 	.tp_basicsize	= sizeof(struct pyrf_event),
358 	.tp_dealloc	= (destructor)pyrf_event__delete,
359 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
360 	.tp_doc		= pyrf_task_event__doc,
361 	.tp_members	= pyrf_task_event__members,
362 	.tp_getset	= pyrf_event__getset,
363 	.tp_repr	= (reprfunc)pyrf_task_event__repr,
364 };
365 
366 static const char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
367 
368 static PyMemberDef pyrf_comm_event__members[] = {
369 	sample_members
370 	member_def(perf_event_header, type, T_UINT, "event type"),
371 	member_def(perf_record_comm, pid, T_UINT, "event pid"),
372 	member_def(perf_record_comm, tid, T_UINT, "event tid"),
373 	member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"),
374 	{ .name = NULL, },
375 };
376 
377 static PyObject *pyrf_comm_event__repr(const struct pyrf_event *pevent)
378 {
379 	return PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
380 				   pevent->event.comm.pid,
381 				   pevent->event.comm.tid,
382 				   pevent->event.comm.comm);
383 }
384 
385 static PyTypeObject pyrf_comm_event__type = {
386 	PyVarObject_HEAD_INIT(NULL, 0)
387 	.tp_name	= "perf.comm_event",
388 	.tp_basicsize	= sizeof(struct pyrf_event),
389 	.tp_dealloc	= (destructor)pyrf_event__delete,
390 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
391 	.tp_doc		= pyrf_comm_event__doc,
392 	.tp_members	= pyrf_comm_event__members,
393 	.tp_getset	= pyrf_event__getset,
394 	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
395 };
396 
397 static const char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
398 
399 static PyMemberDef pyrf_throttle_event__members[] = {
400 	sample_members
401 	member_def(perf_event_header, type, T_UINT, "event type"),
402 	member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"),
403 	member_def(perf_record_throttle, id, T_ULONGLONG, "event id"),
404 	member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"),
405 	{ .name = NULL, },
406 };
407 
408 static PyObject *pyrf_throttle_event__repr(const struct pyrf_event *pevent)
409 {
410 	const struct perf_record_throttle *te = (const struct perf_record_throttle *)
411 		(&pevent->event.header + 1);
412 
413 	return PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64
414 				   ", stream_id: %" PRI_lu64 " }",
415 				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
416 				   te->time, te->id, te->stream_id);
417 }
418 
419 static PyTypeObject pyrf_throttle_event__type = {
420 	PyVarObject_HEAD_INIT(NULL, 0)
421 	.tp_name	= "perf.throttle_event",
422 	.tp_basicsize	= sizeof(struct pyrf_event),
423 	.tp_dealloc	= (destructor)pyrf_event__delete,
424 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
425 	.tp_doc		= pyrf_throttle_event__doc,
426 	.tp_members	= pyrf_throttle_event__members,
427 	.tp_getset	= pyrf_event__getset,
428 	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
429 };
430 
431 static const char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
432 
433 static PyMemberDef pyrf_lost_event__members[] = {
434 	sample_members
435 	member_def(perf_event_header, type, T_UINT, "event type"),
436 	member_def(perf_record_lost, id, T_ULONGLONG, "event id"),
437 	member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"),
438 	{ .name = NULL, },
439 };
440 
441 static PyObject *pyrf_lost_event__repr(const struct pyrf_event *pevent)
442 {
443 	PyObject *ret;
444 	char *s;
445 
446 	if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", "
447 			 "lost: %#" PRI_lx64 " }",
448 		     pevent->event.lost.id, pevent->event.lost.lost) < 0) {
449 		ret = PyErr_NoMemory();
450 	} else {
451 		ret = PyUnicode_FromString(s);
452 		free(s);
453 	}
454 	return ret;
455 }
456 
457 static PyTypeObject pyrf_lost_event__type = {
458 	PyVarObject_HEAD_INIT(NULL, 0)
459 	.tp_name	= "perf.lost_event",
460 	.tp_basicsize	= sizeof(struct pyrf_event),
461 	.tp_dealloc	= (destructor)pyrf_event__delete,
462 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
463 	.tp_doc		= pyrf_lost_event__doc,
464 	.tp_members	= pyrf_lost_event__members,
465 	.tp_getset	= pyrf_event__getset,
466 	.tp_repr	= (reprfunc)pyrf_lost_event__repr,
467 };
468 
469 static const char pyrf_stat_event__doc[] = PyDoc_STR("perf stat event object.");
470 
471 static PyMemberDef pyrf_stat_event__members[] = {
472 	sample_members
473 	member_def(perf_event_header, type, T_UINT, "event type"),
474 	member_def(perf_record_stat, id, T_ULONGLONG, "event id"),
475 	member_def(perf_record_stat, cpu, T_UINT, "event cpu"),
476 	member_def(perf_record_stat, thread, T_UINT, "event thread"),
477 	member_def(perf_record_stat, val, T_ULONGLONG, "counter value"),
478 	member_def(perf_record_stat, ena, T_ULONGLONG, "enabled time"),
479 	member_def(perf_record_stat, run, T_ULONGLONG, "running time"),
480 	{ .name = NULL, },
481 };
482 
483 static PyObject *pyrf_stat_event__repr(const struct pyrf_event *pevent)
484 {
485 	return PyUnicode_FromFormat(
486 		"{ type: stat, id: %llu, cpu: %u, thread: %u, val: %llu, ena: %llu, run: %llu }",
487 		pevent->event.stat.id,
488 		pevent->event.stat.cpu,
489 		pevent->event.stat.thread,
490 		pevent->event.stat.val,
491 		pevent->event.stat.ena,
492 		pevent->event.stat.run);
493 }
494 
495 static PyTypeObject pyrf_stat_event__type = {
496 	PyVarObject_HEAD_INIT(NULL, 0)
497 	.tp_name	= "perf.stat_event",
498 	.tp_basicsize	= sizeof(struct pyrf_event),
499 	.tp_new		= PyType_GenericNew,
500 	.tp_dealloc	= (destructor)pyrf_event__delete,
501 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
502 	.tp_doc		= pyrf_stat_event__doc,
503 	.tp_members	= pyrf_stat_event__members,
504 	.tp_getset	= pyrf_event__getset,
505 	.tp_repr	= (reprfunc)pyrf_stat_event__repr,
506 };
507 
508 static const char pyrf_stat_round_event__doc[] = PyDoc_STR("perf stat round event object.");
509 
510 static PyMemberDef pyrf_stat_round_event__members[] = {
511 	sample_members
512 	member_def(perf_event_header, type, T_UINT, "event type"),
513 	{ .name = "stat_round_type", .type = T_ULONGLONG,
514 	  .offset = offsetof(struct pyrf_event, event) + offsetof(struct perf_record_stat_round, type),
515 	  .doc = "round type" },
516 	member_def(perf_record_stat_round, time, T_ULONGLONG, "round time"),
517 	{ .name = NULL, },
518 };
519 
520 static PyObject *pyrf_stat_round_event__repr(const struct pyrf_event *pevent)
521 {
522 	return PyUnicode_FromFormat("{ type: stat_round, type: %llu, time: %llu }",
523 				   pevent->event.stat_round.type,
524 				   pevent->event.stat_round.time);
525 }
526 
527 static PyTypeObject pyrf_stat_round_event__type = {
528 	PyVarObject_HEAD_INIT(NULL, 0)
529 	.tp_name	= "perf.stat_round_event",
530 	.tp_basicsize	= sizeof(struct pyrf_event),
531 	.tp_new		= PyType_GenericNew,
532 	.tp_dealloc	= (destructor)pyrf_event__delete,
533 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
534 	.tp_doc		= pyrf_stat_round_event__doc,
535 	.tp_members	= pyrf_stat_round_event__members,
536 	.tp_getset	= pyrf_event__getset,
537 	.tp_repr	= (reprfunc)pyrf_stat_round_event__repr,
538 };
539 
540 static const char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
541 
542 static PyMemberDef pyrf_read_event__members[] = {
543 	sample_members
544 	member_def(perf_event_header, type, T_UINT, "event type"),
545 	member_def(perf_record_read, pid, T_UINT, "event pid"),
546 	member_def(perf_record_read, tid, T_UINT, "event tid"),
547 	{ .name = NULL, },
548 };
549 
550 static PyObject *pyrf_read_event__repr(const struct pyrf_event *pevent)
551 {
552 	return PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
553 				   pevent->event.read.pid,
554 				   pevent->event.read.tid);
555 	/*
556  	 * FIXME: return the array of read values,
557  	 * making this method useful ;-)
558  	 */
559 }
560 
561 static PyTypeObject pyrf_read_event__type = {
562 	PyVarObject_HEAD_INIT(NULL, 0)
563 	.tp_name	= "perf.read_event",
564 	.tp_basicsize	= sizeof(struct pyrf_event),
565 	.tp_dealloc	= (destructor)pyrf_event__delete,
566 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
567 	.tp_doc		= pyrf_read_event__doc,
568 	.tp_members	= pyrf_read_event__members,
569 	.tp_getset	= pyrf_event__getset,
570 	.tp_repr	= (reprfunc)pyrf_read_event__repr,
571 };
572 
573 static const char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
574 
575 static PyMemberDef pyrf_sample_event__members[] = {
576 	sample_members
577 	sample_member_def(sample_ip, ip, T_ULONGLONG, "event ip"),
578 	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),
579 	sample_member_def(sample_phys_addr, phys_addr, T_ULONGLONG, "event physical addr"),
580 	sample_member_def(sample_weight, weight, T_ULONGLONG, "event weight"),
581 	sample_member_def(sample_data_src, data_src, T_ULONGLONG, "event data source"),
582 	sample_member_def(sample_insn_count, insn_cnt, T_ULONGLONG, "event instruction count"),
583 	sample_member_def(sample_cyc_count, cyc_cnt, T_ULONGLONG, "event cycle count"),
584 	member_def(perf_event_header, type, T_UINT, "event type"),
585 	{ .name = NULL, },
586 };
587 
588 static PyObject *pyrf_sample_event__repr(const struct pyrf_event *pevent)
589 {
590 	PyObject *ret;
591 	char *s;
592 
593 	if (asprintf(&s, "{ type: sample }") < 0) {
594 		ret = PyErr_NoMemory();
595 	} else {
596 		ret = PyUnicode_FromString(s);
597 		free(s);
598 	}
599 	return ret;
600 }
601 
602 #ifdef HAVE_LIBTRACEEVENT
603 static bool is_tracepoint(const struct pyrf_event *pevent)
604 {
605 	if (!pevent->sample.evsel)
606 		return false;
607 	return pevent->sample.evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
608 }
609 
610 static PyObject*
611 tracepoint_field(const struct pyrf_event *pe, struct tep_format_field *field)
612 {
613 	struct tep_handle *pevent = field->event->tep;
614 	void *data = pe->sample.raw_data;
615 	PyObject *ret = NULL;
616 	unsigned long long val;
617 	unsigned int offset, len;
618 
619 	if (field->flags & TEP_FIELD_IS_ARRAY) {
620 		offset = field->offset;
621 		len    = field->size;
622 		if (field->flags & TEP_FIELD_IS_DYNAMIC) {
623 			val     = tep_read_number(pevent, data + offset, len);
624 			offset  = val;
625 			len     = offset >> 16;
626 			offset &= 0xffff;
627 			if (tep_field_is_relative(field->flags))
628 				offset += field->offset + field->size;
629 		}
630 		if (field->flags & TEP_FIELD_IS_STRING &&
631 		    is_printable_array(data + offset, len)) {
632 			ret = PyUnicode_FromString((char *)data + offset);
633 		} else {
634 			ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
635 			field->flags &= ~TEP_FIELD_IS_STRING;
636 		}
637 	} else {
638 		val = tep_read_number(pevent, data + field->offset,
639 				      field->size);
640 		if (field->flags & TEP_FIELD_IS_POINTER)
641 			ret = PyLong_FromUnsignedLong((unsigned long) val);
642 		else if (field->flags & TEP_FIELD_IS_SIGNED)
643 			ret = PyLong_FromLong((long) val);
644 		else
645 			ret = PyLong_FromUnsignedLong((unsigned long) val);
646 	}
647 
648 	return ret;
649 }
650 
651 static PyObject*
652 get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
653 {
654 	struct evsel *evsel = pevent->sample.evsel;
655 	struct tep_event *tp_format = evsel__tp_format(evsel);
656 	struct tep_format_field *field;
657 
658 	if (IS_ERR_OR_NULL(tp_format))
659 		return NULL;
660 
661 	PyObject *obj = PyObject_Str(attr_name);
662 	if (obj == NULL)
663 		return NULL;
664 
665 	const char *str = PyUnicode_AsUTF8(obj);
666 	if (str == NULL) {
667 		Py_DECREF(obj);
668 		return NULL;
669 	}
670 
671 	field = tep_find_any_field(tp_format, str);
672 	Py_DECREF(obj);
673 	return field ? tracepoint_field(pevent, field) : NULL;
674 }
675 #endif /* HAVE_LIBTRACEEVENT */
676 
677 static int pyrf_sample_event__resolve_al(struct pyrf_event *pevent)
678 {
679 	struct evsel *evsel = pevent->sample.evsel;
680 	struct evlist *evlist = evsel ? evsel->evlist : NULL;
681 	struct perf_session *session = evlist ? evlist__session(evlist) : NULL;
682 
683 	if (pevent->al_resolved)
684 		return 0;
685 
686 	if (!session)
687 		return -1;
688 
689 	addr_location__init(&pevent->al);
690 	if (machine__resolve(&session->machines.host, &pevent->al, &pevent->sample) < 0) {
691 		addr_location__exit(&pevent->al);
692 		return -1;
693 	}
694 
695 	pevent->al_resolved = true;
696 	return 0;
697 }
698 
699 static PyObject *pyrf_sample_event__get_dso(struct pyrf_event *pevent,
700 					    void *closure __maybe_unused)
701 {
702 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
703 		Py_RETURN_NONE;
704 
705 	return PyUnicode_FromString(dso__name(map__dso(pevent->al.map)));
706 }
707 
708 static PyObject *pyrf_sample_event__get_dso_long_name(struct pyrf_event *pevent,
709 						      void *closure __maybe_unused)
710 {
711 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
712 		Py_RETURN_NONE;
713 
714 	return PyUnicode_FromString(dso__long_name(map__dso(pevent->al.map)));
715 }
716 
717 static PyObject *pyrf_sample_event__get_dso_bid(struct pyrf_event *pevent,
718 						void *closure __maybe_unused)
719 {
720 	char sbuild_id[SBUILD_ID_SIZE];
721 
722 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
723 		Py_RETURN_NONE;
724 
725 	build_id__snprintf(dso__bid(map__dso(pevent->al.map)), sbuild_id, sizeof(sbuild_id));
726 	return PyUnicode_FromString(sbuild_id);
727 }
728 
729 static PyObject *pyrf_sample_event__get_map_start(struct pyrf_event *pevent,
730 						  void *closure __maybe_unused)
731 {
732 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
733 		Py_RETURN_NONE;
734 
735 	return PyLong_FromUnsignedLong(map__start(pevent->al.map));
736 }
737 
738 static PyObject *pyrf_sample_event__get_map_end(struct pyrf_event *pevent,
739 						void *closure __maybe_unused)
740 {
741 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
742 		Py_RETURN_NONE;
743 
744 	return PyLong_FromUnsignedLong(map__end(pevent->al.map));
745 }
746 
747 static PyObject *pyrf_sample_event__get_map_pgoff(struct pyrf_event *pevent,
748 						  void *closure __maybe_unused)
749 {
750 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.map)
751 		Py_RETURN_NONE;
752 
753 	return PyLong_FromUnsignedLongLong(map__pgoff(pevent->al.map));
754 }
755 
756 static PyObject *pyrf_sample_event__get_symbol(struct pyrf_event *pevent,
757 					       void *closure __maybe_unused)
758 {
759 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym)
760 		Py_RETURN_NONE;
761 
762 	return PyUnicode_FromString(pevent->al.sym->name);
763 }
764 
765 static PyObject *pyrf_sample_event__get_sym_start(struct pyrf_event *pevent,
766 						  void *closure __maybe_unused)
767 {
768 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym)
769 		Py_RETURN_NONE;
770 
771 	return PyLong_FromUnsignedLongLong(pevent->al.sym->start);
772 }
773 
774 static PyObject *pyrf_sample_event__get_sym_end(struct pyrf_event *pevent,
775 						void *closure __maybe_unused)
776 {
777 	if (pyrf_sample_event__resolve_al(pevent) < 0 || !pevent->al.sym)
778 		Py_RETURN_NONE;
779 
780 	return PyLong_FromUnsignedLongLong(pevent->al.sym->end);
781 }
782 
783 static PyObject *pyrf_sample_event__get_raw_buf(struct pyrf_event *pevent,
784 						void *closure __maybe_unused)
785 {
786 	if (pevent->event.header.type != PERF_RECORD_SAMPLE)
787 		Py_RETURN_NONE;
788 
789 	return PyBytes_FromStringAndSize((const char *)pevent->sample.raw_data,
790 					 pevent->sample.raw_size);
791 }
792 
793 static PyObject *pyrf_sample_event__srccode(PyObject *self, PyObject *args)
794 {
795 	struct pyrf_event *pevent = (void *)self;
796 	u64 addr = pevent->sample.ip;
797 	char *srcfile = NULL;
798 	char *srccode = NULL;
799 	unsigned int line = 0;
800 	int len = 0;
801 	PyObject *result;
802 	struct addr_location al;
803 
804 	if (!PyArg_ParseTuple(args, "|K", &addr))
805 		return NULL;
806 
807 	if (pyrf_sample_event__resolve_al(pevent) < 0)
808 		Py_RETURN_NONE;
809 
810 	if (addr != pevent->sample.ip) {
811 		addr_location__init(&al);
812 		thread__find_symbol_fb(pevent->al.thread, pevent->sample.cpumode, addr, &al);
813 	} else {
814 		addr_location__init(&al);
815 		al.thread = thread__get(pevent->al.thread);
816 		al.map = map__get(pevent->al.map);
817 		al.sym = pevent->al.sym;
818 		al.addr = pevent->al.addr;
819 	}
820 
821 	if (al.map) {
822 		struct dso *dso = map__dso(al.map);
823 
824 		if (dso) {
825 			srcfile = get_srcline_split(dso, map__rip_2objdump(al.map, addr),
826 						    &line);
827 		}
828 	}
829 	addr_location__exit(&al);
830 
831 	if (srcfile) {
832 		srccode = find_sourceline(srcfile, line, &len);
833 		result = Py_BuildValue("(sIs#)", srcfile, line, srccode, (Py_ssize_t)len);
834 		free(srcfile);
835 	} else {
836 		result = Py_BuildValue("(sIs#)", NULL, 0, NULL, (Py_ssize_t)0);
837 	}
838 
839 	return result;
840 }
841 
842 static PyObject *pyrf_sample_event__insn(PyObject *self, PyObject *args __maybe_unused)
843 {
844 	struct pyrf_event *pevent = (void *)self;
845 	struct thread *thread;
846 	struct machine *machine;
847 
848 	if (pyrf_sample_event__resolve_al(pevent) < 0)
849 		Py_RETURN_NONE;
850 
851 	thread = pevent->al.thread;
852 
853 	if (!thread || !thread__maps(thread))
854 		Py_RETURN_NONE;
855 
856 	machine = maps__machine(thread__maps(thread));
857 	if (!machine)
858 		Py_RETURN_NONE;
859 
860 	if (pevent->sample.ip && !pevent->sample.insn_len)
861 		perf_sample__fetch_insn(&pevent->sample, thread, machine);
862 
863 	if (!pevent->sample.insn_len)
864 		Py_RETURN_NONE;
865 
866 	return PyBytes_FromStringAndSize((const char *)pevent->sample.insn,
867 					 pevent->sample.insn_len);
868 }
869 
870 struct pyrf_callchain_node {
871 	PyObject_HEAD
872 	u64 ip;
873 	struct map *map;
874 	struct symbol *sym;
875 };
876 
877 static void pyrf_callchain_node__delete(struct pyrf_callchain_node *pnode)
878 {
879 	map__put(pnode->map);
880 	Py_TYPE(pnode)->tp_free((PyObject *)pnode);
881 }
882 
883 static PyObject *pyrf_callchain_node__get_ip(struct pyrf_callchain_node *pnode,
884 					     void *closure __maybe_unused)
885 {
886 	return PyLong_FromUnsignedLongLong(pnode->ip);
887 }
888 
889 static PyObject *pyrf_callchain_node__get_symbol(struct pyrf_callchain_node *pnode,
890 						 void *closure __maybe_unused)
891 {
892 	if (pnode->sym)
893 		return PyUnicode_FromString(pnode->sym->name);
894 	return PyUnicode_FromString("[unknown]");
895 }
896 
897 static PyObject *pyrf_callchain_node__get_dso(struct pyrf_callchain_node *pnode,
898 					      void *closure __maybe_unused)
899 {
900 	const char *dsoname = "[unknown]";
901 
902 	if (pnode->map) {
903 		struct dso *dso = map__dso(pnode->map);
904 
905 		if (dso) {
906 			if (symbol_conf.show_kernel_path && dso__long_name(dso))
907 				dsoname = dso__long_name(dso);
908 			else
909 				dsoname = dso__name(dso);
910 		}
911 	}
912 	return PyUnicode_FromString(dsoname);
913 }
914 
915 static PyGetSetDef pyrf_callchain_node__getset[] = {
916 	{ .name = "ip",     .get = (getter)pyrf_callchain_node__get_ip, },
917 	{ .name = "symbol", .get = (getter)pyrf_callchain_node__get_symbol, },
918 	{ .name = "dso",    .get = (getter)pyrf_callchain_node__get_dso, },
919 	{ .name = NULL, },
920 };
921 
922 static PyTypeObject pyrf_callchain_node__type = {
923 	PyVarObject_HEAD_INIT(NULL, 0)
924 	.tp_name	= "perf.callchain_node",
925 	.tp_basicsize	= sizeof(struct pyrf_callchain_node),
926 	.tp_dealloc	= (destructor)pyrf_callchain_node__delete,
927 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
928 	.tp_doc		= "perf callchain node object.",
929 	.tp_getset	= pyrf_callchain_node__getset,
930 };
931 
932 struct pyrf_callchain_frame {
933 	u64 ip;
934 	struct map *map;
935 	struct symbol *sym;
936 };
937 
938 struct pyrf_callchain {
939 	PyObject_HEAD
940 	struct pyrf_callchain_frame *frames;
941 	u64 nr_frames;
942 };
943 
944 static void pyrf_callchain__delete(struct pyrf_callchain *pchain)
945 {
946 	if (pchain->frames) {
947 		for (u64 i = 0; i < pchain->nr_frames; i++)
948 			map__put(pchain->frames[i].map);
949 		free(pchain->frames);
950 	}
951 	Py_TYPE(pchain)->tp_free((PyObject *)pchain);
952 }
953 
954 static Py_ssize_t pyrf_callchain__length(PyObject *obj)
955 {
956 	struct pyrf_callchain *pchain = (void *)obj;
957 
958 	return pchain->nr_frames;
959 }
960 
961 static PyObject *pyrf_callchain__item(PyObject *obj, Py_ssize_t i)
962 {
963 	struct pyrf_callchain *pchain = (void *)obj;
964 	struct pyrf_callchain_node *pnode;
965 
966 	if (i < 0 || i >= (Py_ssize_t)pchain->nr_frames) {
967 		PyErr_SetString(PyExc_IndexError, "Index out of range");
968 		return NULL;
969 	}
970 
971 	pnode = PyObject_New(struct pyrf_callchain_node, &pyrf_callchain_node__type);
972 	if (!pnode)
973 		return NULL;
974 
975 	pnode->ip = pchain->frames[i].ip;
976 	pnode->map = map__get(pchain->frames[i].map);
977 	pnode->sym = pchain->frames[i].sym;
978 
979 	return (PyObject *)pnode;
980 }
981 
982 static PySequenceMethods pyrf_callchain__sequence_methods = {
983 	.sq_length = pyrf_callchain__length,
984 	.sq_item   = pyrf_callchain__item,
985 };
986 
987 static PyTypeObject pyrf_callchain__type = {
988 	PyVarObject_HEAD_INIT(NULL, 0)
989 	.tp_name	= "perf.callchain",
990 	.tp_basicsize	= sizeof(struct pyrf_callchain),
991 	.tp_dealloc	= (destructor)pyrf_callchain__delete,
992 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
993 	.tp_doc		= "perf callchain object.",
994 	.tp_as_sequence	= &pyrf_callchain__sequence_methods,
995 };
996 
997 static PyObject *pyrf_sample_event__get_callchain(PyObject *self, void *closure __maybe_unused)
998 {
999 	struct pyrf_event *pevent = (void *)self;
1000 
1001 	if (!pevent->callchain)
1002 		Py_RETURN_NONE;
1003 
1004 	Py_INCREF(pevent->callchain);
1005 	return pevent->callchain;
1006 }
1007 
1008 struct pyrf_branch_entry {
1009 	PyObject_HEAD
1010 	u64 from;
1011 	u64 to;
1012 	struct branch_flags flags;
1013 };
1014 
1015 static void pyrf_branch_entry__delete(struct pyrf_branch_entry *pentry)
1016 {
1017 	Py_TYPE(pentry)->tp_free((PyObject *)pentry);
1018 }
1019 
1020 static PyObject *pyrf_branch_entry__get_from(struct pyrf_branch_entry *pentry,
1021 					     void *closure __maybe_unused)
1022 {
1023 	return PyLong_FromUnsignedLongLong(pentry->from);
1024 }
1025 
1026 static PyObject *pyrf_branch_entry__get_to(struct pyrf_branch_entry *pentry,
1027 					   void *closure __maybe_unused)
1028 {
1029 	return PyLong_FromUnsignedLongLong(pentry->to);
1030 }
1031 
1032 static PyObject *pyrf_branch_entry__get_mispred(struct pyrf_branch_entry *pentry,
1033 						void *closure __maybe_unused)
1034 {
1035 	return PyBool_FromLong(pentry->flags.mispred);
1036 }
1037 
1038 static PyObject *pyrf_branch_entry__get_predicted(struct pyrf_branch_entry *pentry,
1039 						  void *closure __maybe_unused)
1040 {
1041 	return PyBool_FromLong(pentry->flags.predicted);
1042 }
1043 
1044 static PyObject *pyrf_branch_entry__get_in_tx(struct pyrf_branch_entry *pentry,
1045 					      void *closure __maybe_unused)
1046 {
1047 	return PyBool_FromLong(pentry->flags.in_tx);
1048 }
1049 
1050 static PyObject *pyrf_branch_entry__get_abort(struct pyrf_branch_entry *pentry,
1051 					      void *closure __maybe_unused)
1052 {
1053 	return PyBool_FromLong(pentry->flags.abort);
1054 }
1055 
1056 static PyObject *pyrf_branch_entry__get_cycles(struct pyrf_branch_entry *pentry,
1057 					       void *closure __maybe_unused)
1058 {
1059 	return PyLong_FromUnsignedLongLong(pentry->flags.cycles);
1060 }
1061 
1062 static PyObject *pyrf_branch_entry__get_type(struct pyrf_branch_entry *pentry,
1063 					     void *closure __maybe_unused)
1064 {
1065 	return PyLong_FromUnsignedLongLong((unsigned long long)pentry->flags.type);
1066 }
1067 
1068 static PyGetSetDef pyrf_branch_entry__getset[] = {
1069 	{ .name = "from_ip",      .get = (getter)pyrf_branch_entry__get_from, },
1070 	{ .name = "to_ip",        .get = (getter)pyrf_branch_entry__get_to, },
1071 	{ .name = "mispred",   .get = (getter)pyrf_branch_entry__get_mispred, },
1072 	{ .name = "predicted", .get = (getter)pyrf_branch_entry__get_predicted, },
1073 	{ .name = "in_tx",     .get = (getter)pyrf_branch_entry__get_in_tx, },
1074 	{ .name = "abort",     .get = (getter)pyrf_branch_entry__get_abort, },
1075 	{ .name = "cycles",    .get = (getter)pyrf_branch_entry__get_cycles, },
1076 	{ .name = "type",      .get = (getter)pyrf_branch_entry__get_type, },
1077 	{ .name = NULL, },
1078 };
1079 
1080 static PyTypeObject pyrf_branch_entry__type = {
1081 	PyVarObject_HEAD_INIT(NULL, 0)
1082 	.tp_name	= "perf.branch_entry",
1083 	.tp_basicsize	= sizeof(struct pyrf_branch_entry),
1084 	.tp_dealloc	= (destructor)pyrf_branch_entry__delete,
1085 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1086 	.tp_doc		= "perf branch entry object.",
1087 	.tp_getset	= pyrf_branch_entry__getset,
1088 };
1089 
1090 struct pyrf_branch_stack {
1091 	PyObject_HEAD
1092 	struct branch_entry *entries;
1093 	u64 nr;
1094 };
1095 
1096 static void pyrf_branch_stack__delete(struct pyrf_branch_stack *pstack)
1097 {
1098 	free(pstack->entries);
1099 	Py_TYPE(pstack)->tp_free((PyObject *)pstack);
1100 }
1101 
1102 static Py_ssize_t pyrf_branch_stack__length(PyObject *obj)
1103 {
1104 	struct pyrf_branch_stack *pstack = (void *)obj;
1105 
1106 	return pstack->nr;
1107 }
1108 
1109 static PyObject *pyrf_branch_stack__item(PyObject *obj, Py_ssize_t i)
1110 {
1111 	struct pyrf_branch_stack *pstack = (void *)obj;
1112 	struct pyrf_branch_entry *pentry;
1113 
1114 	if (i < 0 || i >= (Py_ssize_t)pstack->nr) {
1115 		PyErr_SetString(PyExc_IndexError, "Index out of range");
1116 		return NULL;
1117 	}
1118 
1119 	pentry = PyObject_New(struct pyrf_branch_entry, &pyrf_branch_entry__type);
1120 	if (!pentry)
1121 		return NULL;
1122 
1123 	pentry->from = pstack->entries[i].from;
1124 	pentry->to = pstack->entries[i].to;
1125 	pentry->flags = pstack->entries[i].flags;
1126 
1127 	return (PyObject *)pentry;
1128 }
1129 
1130 static PySequenceMethods pyrf_branch_stack__sequence_methods = {
1131 	.sq_length = pyrf_branch_stack__length,
1132 	.sq_item   = pyrf_branch_stack__item,
1133 };
1134 
1135 static PyTypeObject pyrf_branch_stack__type = {
1136 	PyVarObject_HEAD_INIT(NULL, 0)
1137 	.tp_name	= "perf.branch_stack",
1138 	.tp_basicsize	= sizeof(struct pyrf_branch_stack),
1139 	.tp_dealloc	= (destructor)pyrf_branch_stack__delete,
1140 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1141 	.tp_doc		= "perf branch stack object.",
1142 	.tp_as_sequence	= &pyrf_branch_stack__sequence_methods,
1143 };
1144 
1145 static PyObject *pyrf_sample_event__get_brstack(PyObject *self, void *closure __maybe_unused)
1146 {
1147 	struct pyrf_event *pevent = (void *)self;
1148 
1149 	if (!pevent->brstack)
1150 		Py_RETURN_NONE;
1151 
1152 	Py_INCREF(pevent->brstack);
1153 	return pevent->brstack;
1154 }
1155 
1156 static PyObject*
1157 pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
1158 {
1159 	PyObject *obj = NULL;
1160 
1161 #ifdef HAVE_LIBTRACEEVENT
1162 	if (is_tracepoint(pevent))
1163 		obj = get_tracepoint_field(pevent, attr_name);
1164 #endif
1165 
1166 	return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
1167 }
1168 
1169 static PyGetSetDef pyrf_sample_event__getset[] = {
1170 	{
1171 		.name = "callchain",
1172 		.get = pyrf_sample_event__get_callchain,
1173 		.set = NULL,
1174 		.doc = "event callchain.",
1175 	},
1176 	{
1177 		.name = "brstack",
1178 		.get = pyrf_sample_event__get_brstack,
1179 		.set = NULL,
1180 		.doc = "event branch stack.",
1181 	},
1182 	{
1183 		.name = "raw_buf",
1184 		.get = (getter)pyrf_sample_event__get_raw_buf,
1185 		.set = NULL,
1186 		.doc = "event raw buffer.",
1187 	},
1188 	{
1189 		.name = "evsel",
1190 		.get = pyrf_event__get_evsel,
1191 		.set = NULL,
1192 		.doc = "tracking event.",
1193 	},
1194 	{
1195 		.name = "dso",
1196 		.get = (getter)pyrf_sample_event__get_dso,
1197 		.set = NULL,
1198 		.doc = "event dso short name.",
1199 	},
1200 	{
1201 		.name = "dso_long_name",
1202 		.get = (getter)pyrf_sample_event__get_dso_long_name,
1203 		.set = NULL,
1204 		.doc = "event dso long name.",
1205 	},
1206 	{
1207 		.name = "dso_bid",
1208 		.get = (getter)pyrf_sample_event__get_dso_bid,
1209 		.set = NULL,
1210 		.doc = "event dso build id.",
1211 	},
1212 	{
1213 		.name = "map_start",
1214 		.get = (getter)pyrf_sample_event__get_map_start,
1215 		.set = NULL,
1216 		.doc = "event map start address.",
1217 	},
1218 	{
1219 		.name = "map_end",
1220 		.get = (getter)pyrf_sample_event__get_map_end,
1221 		.set = NULL,
1222 		.doc = "event map end address.",
1223 	},
1224 	{
1225 		.name = "map_pgoff",
1226 		.get = (getter)pyrf_sample_event__get_map_pgoff,
1227 		.set = NULL,
1228 		.doc = "event map page offset.",
1229 	},
1230 	{
1231 		.name = "symbol",
1232 		.get = (getter)pyrf_sample_event__get_symbol,
1233 		.set = NULL,
1234 		.doc = "event symbol name.",
1235 	},
1236 	{
1237 		.name = "sym_start",
1238 		.get = (getter)pyrf_sample_event__get_sym_start,
1239 		.set = NULL,
1240 		.doc = "event symbol start address.",
1241 	},
1242 	{
1243 		.name = "sym_end",
1244 		.get = (getter)pyrf_sample_event__get_sym_end,
1245 		.set = NULL,
1246 		.doc = "event symbol end address.",
1247 	},
1248 	{ .name = NULL, },
1249 };
1250 
1251 static PyMethodDef pyrf_sample_event__methods[] = {
1252 	{
1253 		.ml_name  = "srccode",
1254 		.ml_meth  = (PyCFunction)pyrf_sample_event__srccode,
1255 		.ml_flags = METH_VARARGS,
1256 		.ml_doc	  = PyDoc_STR("Get source code for an address.")
1257 	},
1258 	{
1259 		.ml_name  = "insn",
1260 		.ml_meth  = (PyCFunction)pyrf_sample_event__insn,
1261 		.ml_flags = METH_NOARGS,
1262 		.ml_doc	  = PyDoc_STR("Get instruction bytes for a sample.")
1263 	},
1264 	{ .ml_name = NULL, }
1265 };
1266 
1267 static PyTypeObject pyrf_sample_event__type = {
1268 	PyVarObject_HEAD_INIT(NULL, 0)
1269 	.tp_name	= "perf.sample_event",
1270 	.tp_basicsize	= sizeof(struct pyrf_event),
1271 	.tp_dealloc	= (destructor)pyrf_event__delete,
1272 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1273 	.tp_doc		= pyrf_sample_event__doc,
1274 	.tp_members	= pyrf_sample_event__members,
1275 	.tp_getset	= pyrf_sample_event__getset,
1276 	.tp_methods	= pyrf_sample_event__methods,
1277 	.tp_repr	= (reprfunc)pyrf_sample_event__repr,
1278 	.tp_getattro	= (getattrofunc) pyrf_sample_event__getattro,
1279 };
1280 
1281 static const char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
1282 
1283 static PyMemberDef pyrf_context_switch_event__members[] = {
1284 	sample_members
1285 	member_def(perf_event_header, type, T_UINT, "event type"),
1286 	member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"),
1287 	member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"),
1288 	{ .name = NULL, },
1289 };
1290 
1291 static PyObject *pyrf_context_switch_event__repr(const struct pyrf_event *pevent)
1292 {
1293 	PyObject *ret;
1294 	char *s;
1295 
1296 	if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
1297 		     pevent->event.context_switch.next_prev_pid,
1298 		     pevent->event.context_switch.next_prev_tid,
1299 		     !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
1300 		ret = PyErr_NoMemory();
1301 	} else {
1302 		ret = PyUnicode_FromString(s);
1303 		free(s);
1304 	}
1305 	return ret;
1306 }
1307 
1308 static PyTypeObject pyrf_context_switch_event__type = {
1309 	PyVarObject_HEAD_INIT(NULL, 0)
1310 	.tp_name	= "perf.context_switch_event",
1311 	.tp_basicsize	= sizeof(struct pyrf_event),
1312 	.tp_dealloc	= (destructor)pyrf_event__delete,
1313 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1314 	.tp_doc		= pyrf_context_switch_event__doc,
1315 	.tp_members	= pyrf_context_switch_event__members,
1316 	.tp_getset	= pyrf_event__getset,
1317 	.tp_repr	= (reprfunc)pyrf_context_switch_event__repr,
1318 };
1319 
1320 static int pyrf_event__setup_types(void)
1321 {
1322 	int err;
1323 
1324 	err = PyType_Ready(&pyrf_mmap_event__type);
1325 	if (err < 0)
1326 		goto out;
1327 	err = PyType_Ready(&pyrf_mmap2_event__type);
1328 	if (err < 0)
1329 		goto out;
1330 	err = PyType_Ready(&pyrf_lost_event__type);
1331 	if (err < 0)
1332 		goto out;
1333 	err = PyType_Ready(&pyrf_task_event__type);
1334 	if (err < 0)
1335 		goto out;
1336 	err = PyType_Ready(&pyrf_comm_event__type);
1337 	if (err < 0)
1338 		goto out;
1339 	err = PyType_Ready(&pyrf_throttle_event__type);
1340 	if (err < 0)
1341 		goto out;
1342 	err = PyType_Ready(&pyrf_read_event__type);
1343 	if (err < 0)
1344 		goto out;
1345 	err = PyType_Ready(&pyrf_sample_event__type);
1346 	if (err < 0)
1347 		goto out;
1348 	err = PyType_Ready(&pyrf_context_switch_event__type);
1349 	if (err < 0)
1350 		goto out;
1351 	err = PyType_Ready(&pyrf_stat_event__type);
1352 	if (err < 0)
1353 		goto out;
1354 	err = PyType_Ready(&pyrf_stat_round_event__type);
1355 	if (err < 0)
1356 		goto out;
1357 	err = PyType_Ready(&pyrf_callchain_node__type);
1358 	if (err < 0)
1359 		goto out;
1360 	err = PyType_Ready(&pyrf_callchain__type);
1361 	if (err < 0)
1362 		goto out;
1363 	err = PyType_Ready(&pyrf_branch_entry__type);
1364 	if (err < 0)
1365 		goto out;
1366 	err = PyType_Ready(&pyrf_branch_stack__type);
1367 	if (err < 0)
1368 		goto out;
1369 out:
1370 	return err;
1371 }
1372 
1373 static PyTypeObject *pyrf_event__type[] = {
1374 	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
1375 	[PERF_RECORD_MMAP2]	 = &pyrf_mmap2_event__type,
1376 	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,
1377 	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
1378 	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
1379 	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
1380 	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
1381 	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
1382 	[PERF_RECORD_READ]	 = &pyrf_read_event__type,
1383 	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,
1384 	[PERF_RECORD_SWITCH]	 = &pyrf_context_switch_event__type,
1385 	[PERF_RECORD_SWITCH_CPU_WIDE]  = &pyrf_context_switch_event__type,
1386 	[PERF_RECORD_STAT]	 = &pyrf_stat_event__type,
1387 	[PERF_RECORD_STAT_ROUND] = &pyrf_stat_round_event__type,
1388 };
1389 
1390 static PyObject *pyrf_event__new(const union perf_event *event, struct evsel *evsel,
1391 				 struct perf_session *session,
1392 				 struct machine *machine)
1393 {
1394 	struct pyrf_event *pevent;
1395 	struct perf_sample *sample;
1396 	int err;
1397 	u32 min_size;
1398 	bool needs_swap;
1399 
1400 	if (!machine)
1401 		machine = session ? &session->machines.host : NULL;
1402 
1403 	if (event->header.type >= ARRAY_SIZE(pyrf_event__type) ||
1404 	    pyrf_event__type[event->header.type] == NULL) {
1405 		return PyErr_Format(PyExc_TypeError, "Unexpected header type %u",
1406 			     event->header.type);
1407 	}
1408 
1409 	if (perf_event__too_small(event, &min_size)) {
1410 		return PyErr_Format(PyExc_ValueError, "Event size %u too small for type %u",
1411 				    event->header.size, event->header.type);
1412 	}
1413 
1414 	size_t copy_size = event->header.size;
1415 
1416 	if (copy_size > sizeof(pevent->event)) {
1417 		return PyErr_Format(PyExc_TypeError, "Unexpected event size: %zd < %zu",
1418 				    sizeof(pevent->event), copy_size);
1419 	}
1420 
1421 	pevent = PyObject_New(struct pyrf_event, pyrf_event__type[event->header.type]);
1422 	if (pevent == NULL)
1423 		return PyErr_NoMemory();
1424 
1425 	/* Copy the event for memory safety and initialize variables. */
1426 	memcpy(&pevent->event, event, copy_size);
1427 	if (copy_size < sizeof(pevent->event))
1428 		memset((char *)&pevent->event + copy_size, 0, sizeof(pevent->event) - copy_size);
1429 
1430 	if (event->header.type == PERF_RECORD_MMAP2)
1431 		pevent->event.mmap2.filename[sizeof(pevent->event.mmap2.filename) - 1] = '\0';
1432 
1433 	perf_sample__init(&pevent->sample, /*all=*/true);
1434 	pevent->callchain = NULL;
1435 	pevent->brstack = NULL;
1436 	pevent->al_resolved = false;
1437 	addr_location__init(&pevent->al);
1438 
1439 	if (!evsel)
1440 		return (PyObject *)pevent;
1441 
1442 	/* Parse the sample again so that pointers are within the copied event. */
1443 	needs_swap = evsel->needs_swap;
1444 
1445 	evsel->needs_swap = false;
1446 	err = evsel__parse_sample(evsel, &pevent->event, &pevent->sample);
1447 	evsel->needs_swap = needs_swap;
1448 	if (err < 0) {
1449 		Py_DECREF(pevent);
1450 		return PyErr_Format(PyExc_OSError,
1451 				    "perf: can't parse sample, err=%d", err);
1452 	}
1453 	sample = &pevent->sample;
1454 	if (machine && sample->callchain) {
1455 		struct addr_location al;
1456 		struct callchain_cursor *cursor;
1457 		u64 i;
1458 		struct pyrf_callchain *pchain;
1459 
1460 		addr_location__init(&al);
1461 		if (machine__resolve(machine, &al, sample) >= 0) {
1462 			cursor = get_tls_callchain_cursor();
1463 			if (thread__resolve_callchain(al.thread, cursor, sample,
1464 						      NULL, NULL, PERF_MAX_STACK_DEPTH) == 0) {
1465 				callchain_cursor_commit(cursor);
1466 
1467 				pchain = PyObject_New(struct pyrf_callchain, &pyrf_callchain__type);
1468 				if (!pchain) {
1469 					addr_location__exit(&al);
1470 					Py_DECREF(pevent);
1471 					return NULL;
1472 				}
1473 				pchain->nr_frames = cursor->nr;
1474 				pchain->frames = calloc(pchain->nr_frames,
1475 							sizeof(*pchain->frames));
1476 				if (!pchain->frames) {
1477 					Py_DECREF(pchain);
1478 					addr_location__exit(&al);
1479 					Py_DECREF(pevent);
1480 					return PyErr_NoMemory();
1481 				}
1482 				struct callchain_cursor_node *node;
1483 
1484 				for (i = 0; i < pchain->nr_frames; i++) {
1485 					node = callchain_cursor_current(cursor);
1486 					pchain->frames[i].ip = node->ip;
1487 					pchain->frames[i].map =
1488 						map__get(node->ms.map);
1489 					pchain->frames[i].sym = node->ms.sym;
1490 					callchain_cursor_advance(cursor);
1491 				}
1492 				pevent->callchain = (PyObject *)pchain;
1493 			}
1494 			addr_location__exit(&al);
1495 		}
1496 	}
1497 	if (sample->branch_stack) {
1498 		struct branch_stack *bs = sample->branch_stack;
1499 		struct branch_entry *entries = perf_sample__branch_entries(sample);
1500 		struct pyrf_branch_stack *pstack;
1501 
1502 		pstack = PyObject_New(struct pyrf_branch_stack, &pyrf_branch_stack__type);
1503 		if (!pstack) {
1504 			Py_DECREF(pevent);
1505 			return NULL;
1506 		}
1507 		pstack->nr = bs->nr;
1508 		pstack->entries = calloc(bs->nr, sizeof(struct branch_entry));
1509 		if (!pstack->entries) {
1510 			Py_DECREF(pstack);
1511 			Py_DECREF(pevent);
1512 			return PyErr_NoMemory();
1513 		}
1514 		memcpy(pstack->entries, entries,
1515 		       bs->nr * sizeof(struct branch_entry));
1516 		pevent->brstack = (PyObject *)pstack;
1517 	}
1518 	return (PyObject *)pevent;
1519 }
1520 
1521 struct pyrf_cpu_map {
1522 	PyObject_HEAD
1523 
1524 	struct perf_cpu_map *cpus;
1525 };
1526 
1527 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
1528 			      PyObject *args, PyObject *kwargs)
1529 {
1530 	static char *kwlist[] = { "cpustr", NULL };
1531 	char *cpustr = NULL;
1532 
1533 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
1534 					 kwlist, &cpustr))
1535 		return -1;
1536 
1537 	pcpus->cpus = perf_cpu_map__new(cpustr);
1538 	if (pcpus->cpus == NULL)
1539 		return -1;
1540 	return 0;
1541 }
1542 
1543 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
1544 {
1545 	perf_cpu_map__put(pcpus->cpus);
1546 	Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
1547 }
1548 
1549 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
1550 {
1551 	struct pyrf_cpu_map *pcpus = (void *)obj;
1552 
1553 	return perf_cpu_map__nr(pcpus->cpus);
1554 }
1555 
1556 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
1557 {
1558 	struct pyrf_cpu_map *pcpus = (void *)obj;
1559 
1560 	if (i >= perf_cpu_map__nr(pcpus->cpus)) {
1561 		PyErr_SetString(PyExc_IndexError, "Index out of range");
1562 		return NULL;
1563 	}
1564 
1565 	return Py_BuildValue("i", perf_cpu_map__cpu(pcpus->cpus, i).cpu);
1566 }
1567 
1568 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
1569 	.sq_length = pyrf_cpu_map__length,
1570 	.sq_item   = pyrf_cpu_map__item,
1571 };
1572 
1573 static const char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
1574 
1575 static PyTypeObject pyrf_cpu_map__type = {
1576 	PyVarObject_HEAD_INIT(NULL, 0)
1577 	.tp_name	= "perf.cpu_map",
1578 	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
1579 	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
1580 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1581 	.tp_doc		= pyrf_cpu_map__doc,
1582 	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
1583 	.tp_init	= (initproc)pyrf_cpu_map__init,
1584 };
1585 
1586 static int pyrf_cpu_map__setup_types(void)
1587 {
1588 	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
1589 	return PyType_Ready(&pyrf_cpu_map__type);
1590 }
1591 
1592 struct pyrf_thread_map {
1593 	PyObject_HEAD
1594 
1595 	struct perf_thread_map *threads;
1596 };
1597 
1598 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
1599 				 PyObject *args, PyObject *kwargs)
1600 {
1601 	static char *kwlist[] = { "pid", "tid", NULL };
1602 	int pid = -1, tid = -1;
1603 
1604 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
1605 					 kwlist, &pid, &tid))
1606 		return -1;
1607 
1608 	pthreads->threads = thread_map__new(pid, tid);
1609 	if (pthreads->threads == NULL)
1610 		return -1;
1611 	return 0;
1612 }
1613 
1614 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
1615 {
1616 	perf_thread_map__put(pthreads->threads);
1617 	Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
1618 }
1619 
1620 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
1621 {
1622 	struct pyrf_thread_map *pthreads = (void *)obj;
1623 
1624 	return perf_thread_map__nr(pthreads->threads);
1625 }
1626 
1627 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
1628 {
1629 	struct pyrf_thread_map *pthreads = (void *)obj;
1630 
1631 	if (i >= perf_thread_map__nr(pthreads->threads)) {
1632 		PyErr_SetString(PyExc_IndexError, "Index out of range");
1633 		return NULL;
1634 	}
1635 
1636 	return Py_BuildValue("i", perf_thread_map__pid(pthreads->threads, i));
1637 }
1638 
1639 static PySequenceMethods pyrf_thread_map__sequence_methods = {
1640 	.sq_length = pyrf_thread_map__length,
1641 	.sq_item   = pyrf_thread_map__item,
1642 };
1643 
1644 static const char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
1645 
1646 static PyTypeObject pyrf_thread_map__type = {
1647 	PyVarObject_HEAD_INIT(NULL, 0)
1648 	.tp_name	= "perf.thread_map",
1649 	.tp_basicsize	= sizeof(struct pyrf_thread_map),
1650 	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
1651 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1652 	.tp_doc		= pyrf_thread_map__doc,
1653 	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
1654 	.tp_init	= (initproc)pyrf_thread_map__init,
1655 };
1656 
1657 static int pyrf_thread_map__setup_types(void)
1658 {
1659 	pyrf_thread_map__type.tp_new = PyType_GenericNew;
1660 	return PyType_Ready(&pyrf_thread_map__type);
1661 }
1662 
1663 /**
1664  * A python wrapper for perf_pmus that are globally owned by the pmus.c code.
1665  */
1666 struct pyrf_pmu {
1667 	PyObject_HEAD
1668 
1669 	struct perf_pmu *pmu;
1670 };
1671 
1672 static void pyrf_pmu__delete(struct pyrf_pmu *ppmu)
1673 {
1674 	Py_TYPE(ppmu)->tp_free((PyObject *)ppmu);
1675 }
1676 
1677 static PyObject *pyrf_pmu__name(PyObject *self)
1678 {
1679 	struct pyrf_pmu *ppmu = (void *)self;
1680 
1681 	CHECK_INITIALIZED(ppmu->pmu, "pmu");
1682 	return PyUnicode_FromString(ppmu->pmu->name);
1683 }
1684 
1685 static bool add_to_dict(PyObject *dict, const char *key, const char *value)
1686 {
1687 	PyObject *pkey, *pvalue;
1688 	bool ret;
1689 
1690 	if (value == NULL)
1691 		return true;
1692 
1693 	pkey = PyUnicode_FromString(key);
1694 	pvalue = PyUnicode_FromString(value);
1695 
1696 	ret = pkey && pvalue && PyDict_SetItem(dict, pkey, pvalue) == 0;
1697 	Py_XDECREF(pkey);
1698 	Py_XDECREF(pvalue);
1699 	return ret;
1700 }
1701 
1702 static int pyrf_pmu__events_cb(void *state, struct pmu_event_info *info)
1703 {
1704 	PyObject *py_list = state;
1705 	PyObject *dict = PyDict_New();
1706 
1707 	if (!dict)
1708 		return -ENOMEM;
1709 
1710 	if (!add_to_dict(dict, "name", info->name) ||
1711 	    !add_to_dict(dict, "alias", info->alias) ||
1712 	    !add_to_dict(dict, "scale_unit", info->scale_unit) ||
1713 	    !add_to_dict(dict, "desc", info->desc) ||
1714 	    !add_to_dict(dict, "long_desc", info->long_desc) ||
1715 	    !add_to_dict(dict, "encoding_desc", info->encoding_desc) ||
1716 	    !add_to_dict(dict, "topic", info->topic) ||
1717 	    !add_to_dict(dict, "event_type_desc", info->event_type_desc) ||
1718 	    !add_to_dict(dict, "str", info->str) ||
1719 	    !add_to_dict(dict, "deprecated", info->deprecated ? "deprecated" : NULL) ||
1720 	    PyList_Append(py_list, dict) != 0) {
1721 		Py_DECREF(dict);
1722 		return -ENOMEM;
1723 	}
1724 	Py_DECREF(dict);
1725 	return 0;
1726 }
1727 
1728 static PyObject *pyrf_pmu__events(PyObject *self)
1729 {
1730 	struct pyrf_pmu *ppmu = (void *)self;
1731 	PyObject *py_list;
1732 	int ret;
1733 
1734 	CHECK_INITIALIZED(ppmu->pmu, "pmu");
1735 
1736 	py_list = PyList_New(0);
1737 	if (!py_list)
1738 		return NULL;
1739 
1740 	ret = perf_pmu__for_each_event(ppmu->pmu,
1741 				       /*skip_duplicate_pmus=*/false,
1742 				       py_list,
1743 				       pyrf_pmu__events_cb);
1744 	if (ret) {
1745 		Py_DECREF(py_list);
1746 		errno = -ret;
1747 		PyErr_SetFromErrno(PyExc_OSError);
1748 		return NULL;
1749 	}
1750 	return py_list;
1751 }
1752 
1753 static PyObject *pyrf_pmu__repr(PyObject *self)
1754 {
1755 	struct pyrf_pmu *ppmu = (void *)self;
1756 
1757 	CHECK_INITIALIZED(ppmu->pmu, "pmu");
1758 	return PyUnicode_FromFormat("pmu(%s)", ppmu->pmu->name);
1759 }
1760 
1761 static const char pyrf_pmu__doc[] = PyDoc_STR("perf Performance Monitoring Unit (PMU) object.");
1762 
1763 static PyMethodDef pyrf_pmu__methods[] = {
1764 	{
1765 		.ml_name  = "events",
1766 		.ml_meth  = (PyCFunction)pyrf_pmu__events,
1767 		.ml_flags = METH_NOARGS,
1768 		.ml_doc	  = PyDoc_STR("Returns a sequence of events encoded as a dictionaries.")
1769 	},
1770 	{
1771 		.ml_name  = "name",
1772 		.ml_meth  = (PyCFunction)pyrf_pmu__name,
1773 		.ml_flags = METH_NOARGS,
1774 		.ml_doc	  = PyDoc_STR("Name of the PMU including suffixes.")
1775 	},
1776 	{ .ml_name = NULL, }
1777 };
1778 
1779 /** The python type for a perf.pmu. */
1780 static PyTypeObject pyrf_pmu__type = {
1781 	PyVarObject_HEAD_INIT(NULL, 0)
1782 	.tp_name	= "perf.pmu",
1783 	.tp_basicsize	= sizeof(struct pyrf_pmu),
1784 	.tp_dealloc	= (destructor)pyrf_pmu__delete,
1785 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1786 	.tp_doc		= pyrf_pmu__doc,
1787 	.tp_methods	= pyrf_pmu__methods,
1788 	.tp_str         = pyrf_pmu__name,
1789 	.tp_repr        = pyrf_pmu__repr,
1790 };
1791 
1792 static int pyrf_pmu__setup_types(void)
1793 {
1794 	pyrf_pmu__type.tp_new = PyType_GenericNew;
1795 	return PyType_Ready(&pyrf_pmu__type);
1796 }
1797 
1798 
1799 /** A python iterator for pmus that has no equivalent in the C code. */
1800 struct pyrf_pmu_iterator {
1801 	PyObject_HEAD
1802 	struct perf_pmu *pmu;
1803 };
1804 
1805 static void pyrf_pmu_iterator__dealloc(struct pyrf_pmu_iterator *self)
1806 {
1807 	Py_TYPE(self)->tp_free((PyObject *) self);
1808 }
1809 
1810 static PyObject *pyrf_pmu_iterator__new(PyTypeObject *type, PyObject *args __maybe_unused,
1811 					PyObject *kwds __maybe_unused)
1812 {
1813 	struct pyrf_pmu_iterator *itr = (void *)type->tp_alloc(type, 0);
1814 
1815 	if (itr != NULL)
1816 		itr->pmu = perf_pmus__scan(/*pmu=*/NULL);
1817 
1818 	return (PyObject *) itr;
1819 }
1820 
1821 static PyObject *pyrf_pmu_iterator__iter(PyObject *self)
1822 {
1823 	Py_INCREF(self);
1824 	return self;
1825 }
1826 
1827 static PyObject *pyrf_pmu_iterator__iternext(PyObject *self)
1828 {
1829 	struct pyrf_pmu_iterator *itr = (void *)self;
1830 	struct pyrf_pmu *ppmu;
1831 
1832 	if (itr->pmu == NULL) {
1833 		PyErr_SetNone(PyExc_StopIteration);
1834 		return NULL;
1835 	}
1836 	// Create object to return.
1837 	ppmu = PyObject_New(struct pyrf_pmu, &pyrf_pmu__type);
1838 	if (ppmu) {
1839 		ppmu->pmu = itr->pmu;
1840 		// Advance iterator.
1841 		itr->pmu = perf_pmus__scan(itr->pmu);
1842 	}
1843 	return (PyObject *)ppmu;
1844 }
1845 
1846 /** The python type for the PMU iterator. */
1847 static PyTypeObject pyrf_pmu_iterator__type = {
1848 	PyVarObject_HEAD_INIT(NULL, 0)
1849 	.tp_name = "pmus.iterator",
1850 	.tp_doc = "Iterator for the pmus string sequence.",
1851 	.tp_basicsize = sizeof(struct pyrf_pmu_iterator),
1852 	.tp_itemsize = 0,
1853 	.tp_flags = Py_TPFLAGS_DEFAULT,
1854 	.tp_new = pyrf_pmu_iterator__new,
1855 	.tp_dealloc = (destructor) pyrf_pmu_iterator__dealloc,
1856 	.tp_iter = pyrf_pmu_iterator__iter,
1857 	.tp_iternext = pyrf_pmu_iterator__iternext,
1858 };
1859 
1860 static int pyrf_pmu_iterator__setup_types(void)
1861 {
1862 	return PyType_Ready(&pyrf_pmu_iterator__type);
1863 }
1864 
1865 static PyObject *pyrf__pmus(PyObject *self, PyObject *args)
1866 {
1867 	// Calling the class creates an instance of the iterator.
1868 	return PyObject_CallObject((PyObject *) &pyrf_pmu_iterator__type, /*args=*/NULL);
1869 }
1870 
1871 struct pyrf_counts_values {
1872 	PyObject_HEAD
1873 
1874 	struct perf_counts_values values;
1875 };
1876 
1877 static const char pyrf_counts_values__doc[] = PyDoc_STR("perf counts values object.");
1878 
1879 static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values)
1880 {
1881 	Py_TYPE(pcounts_values)->tp_free((PyObject *)pcounts_values);
1882 }
1883 
1884 #define counts_values_member_def(member, ptype, help) \
1885 	{ #member, ptype, \
1886 	  offsetof(struct pyrf_counts_values, values.member), \
1887 	  0, help }
1888 
1889 static PyMemberDef pyrf_counts_values_members[] = {
1890 	counts_values_member_def(val, T_ULONGLONG, "Value of event"),
1891 	counts_values_member_def(ena, T_ULONGLONG, "Time for which enabled"),
1892 	counts_values_member_def(run, T_ULONGLONG, "Time for which running"),
1893 	counts_values_member_def(id, T_ULONGLONG, "Unique ID for an event"),
1894 	counts_values_member_def(lost, T_ULONGLONG, "Num of lost samples"),
1895 	{ .name = NULL, },
1896 };
1897 
1898 static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self, void *closure)
1899 {
1900 	PyObject *vals = PyList_New(5);
1901 
1902 	if (!vals)
1903 		return NULL;
1904 	for (int i = 0; i < 5; i++) {
1905 		PyObject *val = PyLong_FromUnsignedLongLong(self->values.values[i]);
1906 
1907 		if (!val) {
1908 			Py_DECREF(vals);
1909 			return NULL;
1910 		}
1911 		PyList_SetItem(vals, i, val);
1912 	}
1913 
1914 	return vals;
1915 }
1916 
1917 static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObject *list,
1918 					 void *closure)
1919 {
1920 	Py_ssize_t size;
1921 	PyObject *item = NULL;
1922 
1923 	if (list == NULL) {
1924 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
1925 		return -1;
1926 	}
1927 
1928 	if (!PyList_Check(list)) {
1929 		PyErr_SetString(PyExc_TypeError, "Value assigned must be a list");
1930 		return -1;
1931 	}
1932 
1933 	size = PyList_Size(list);
1934 	if (size != 5) {
1935 		PyErr_SetString(PyExc_ValueError, "List must have exactly 5 entries");
1936 		return -1;
1937 	}
1938 
1939 	for (Py_ssize_t i = 0; i < size; i++) {
1940 		unsigned long long val;
1941 
1942 		item = PyList_GetItem(list, i);
1943 		if (!PyLong_Check(item)) {
1944 			PyErr_SetString(PyExc_TypeError, "List members should be numbers");
1945 			return -1;
1946 		}
1947 		val = PyLong_AsUnsignedLongLong(item);
1948 		if (val == (unsigned long long)-1 && PyErr_Occurred())
1949 			return -1;
1950 		self->values.values[i] = val;
1951 	}
1952 
1953 	return 0;
1954 }
1955 
1956 static PyGetSetDef pyrf_counts_values_getset[] = {
1957 	{"values", (getter)pyrf_counts_values_get_values, (setter)pyrf_counts_values_set_values,
1958 		"Name field", NULL},
1959 	{ .name = NULL, },
1960 };
1961 
1962 static PyTypeObject pyrf_counts_values__type = {
1963 	PyVarObject_HEAD_INIT(NULL, 0)
1964 	.tp_name	= "perf.counts_values",
1965 	.tp_basicsize	= sizeof(struct pyrf_counts_values),
1966 	.tp_dealloc	= (destructor)pyrf_counts_values__delete,
1967 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1968 	.tp_doc		= pyrf_counts_values__doc,
1969 	.tp_members	= pyrf_counts_values_members,
1970 	.tp_getset	= pyrf_counts_values_getset,
1971 };
1972 
1973 static int pyrf_counts_values__setup_types(void)
1974 {
1975 	pyrf_counts_values__type.tp_new = PyType_GenericNew;
1976 	return PyType_Ready(&pyrf_counts_values__type);
1977 }
1978 
1979 struct pyrf_evsel {
1980 	PyObject_HEAD
1981 
1982 	struct evsel *evsel;
1983 };
1984 
1985 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
1986 			    PyObject *args, PyObject *kwargs)
1987 {
1988 	struct perf_event_attr attr = {
1989 		.type = PERF_TYPE_HARDWARE,
1990 		.config = PERF_COUNT_HW_CPU_CYCLES,
1991 		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
1992 	};
1993 	static char *kwlist[] = {
1994 		"type",
1995 		"config",
1996 		"sample_freq",
1997 		"sample_period",
1998 		"sample_type",
1999 		"read_format",
2000 		"disabled",
2001 		"inherit",
2002 		"pinned",
2003 		"exclusive",
2004 		"exclude_user",
2005 		"exclude_kernel",
2006 		"exclude_hv",
2007 		"exclude_idle",
2008 		"mmap",
2009 		"context_switch",
2010 		"comm",
2011 		"freq",
2012 		"inherit_stat",
2013 		"enable_on_exec",
2014 		"task",
2015 		"watermark",
2016 		"precise_ip",
2017 		"mmap_data",
2018 		"sample_id_all",
2019 		"wakeup_events",
2020 		"bp_type",
2021 		"bp_addr",
2022 		"bp_len",
2023 		"idx",
2024 		 NULL
2025 	};
2026 	u64 sample_period = 0;
2027 	u32 disabled = 0,
2028 	    inherit = 0,
2029 	    pinned = 0,
2030 	    exclusive = 0,
2031 	    exclude_user = 0,
2032 	    exclude_kernel = 0,
2033 	    exclude_hv = 0,
2034 	    exclude_idle = 0,
2035 	    mmap = 0,
2036 	    context_switch = 0,
2037 	    comm = 0,
2038 	    freq = 1,
2039 	    inherit_stat = 0,
2040 	    enable_on_exec = 0,
2041 	    task = 0,
2042 	    watermark = 0,
2043 	    precise_ip = 0,
2044 	    mmap_data = 0,
2045 	    sample_id_all = 1,
2046 	    idx = 0;
2047 
2048 	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
2049 					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKKi", kwlist,
2050 					 &attr.type, &attr.config, &attr.sample_freq,
2051 					 &sample_period, &attr.sample_type,
2052 					 &attr.read_format, &disabled, &inherit,
2053 					 &pinned, &exclusive, &exclude_user,
2054 					 &exclude_kernel, &exclude_hv, &exclude_idle,
2055 					 &mmap, &context_switch, &comm, &freq, &inherit_stat,
2056 					 &enable_on_exec, &task, &watermark,
2057 					 &precise_ip, &mmap_data, &sample_id_all,
2058 					 &attr.wakeup_events, &attr.bp_type,
2059 					 &attr.bp_addr, &attr.bp_len, &idx))
2060 		return -1;
2061 
2062 	/* union... */
2063 	if (sample_period != 0) {
2064 		if (attr.sample_freq != 0)
2065 			return -1; /* FIXME: throw right exception */
2066 		attr.sample_period = sample_period;
2067 	}
2068 
2069 	/* Bitfields */
2070 	attr.disabled	    = disabled;
2071 	attr.inherit	    = inherit;
2072 	attr.pinned	    = pinned;
2073 	attr.exclusive	    = exclusive;
2074 	attr.exclude_user   = exclude_user;
2075 	attr.exclude_kernel = exclude_kernel;
2076 	attr.exclude_hv	    = exclude_hv;
2077 	attr.exclude_idle   = exclude_idle;
2078 	attr.mmap	    = mmap;
2079 	attr.context_switch = context_switch;
2080 	attr.comm	    = comm;
2081 	attr.freq	    = freq;
2082 	attr.inherit_stat   = inherit_stat;
2083 	attr.enable_on_exec = enable_on_exec;
2084 	attr.task	    = task;
2085 	attr.watermark	    = watermark;
2086 	attr.precise_ip	    = precise_ip;
2087 	attr.mmap_data	    = mmap_data;
2088 	attr.sample_id_all  = sample_id_all;
2089 	attr.size	    = sizeof(attr);
2090 
2091 	evsel__put(pevsel->evsel);
2092 	pevsel->evsel = evsel__new(&attr);
2093 	if (!pevsel->evsel) {
2094 		PyErr_NoMemory();
2095 		return -1;
2096 	}
2097 	return 0;
2098 }
2099 
2100 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
2101 {
2102 	evsel__put(pevsel->evsel);
2103 	Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
2104 }
2105 
2106 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
2107 				  PyObject *args, PyObject *kwargs)
2108 {
2109 	struct evsel *evsel = pevsel->evsel;
2110 	struct perf_cpu_map *cpus = NULL;
2111 	struct perf_thread_map *threads = NULL;
2112 	PyObject *pcpus = NULL, *pthreads = NULL;
2113 	int group = 0, inherit = 0;
2114 	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
2115 
2116 	CHECK_INITIALIZED(evsel, "evsel");
2117 
2118 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
2119 					 &pcpus, &pthreads, &group, &inherit))
2120 		return NULL;
2121 
2122 	if (pthreads != NULL && pthreads != Py_None) {
2123 		if (!PyObject_TypeCheck(pthreads, &pyrf_thread_map__type)) {
2124 			PyErr_SetString(PyExc_TypeError, "threads must be a thread_map");
2125 			return NULL;
2126 		}
2127 		threads = ((struct pyrf_thread_map *)pthreads)->threads;
2128 	}
2129 
2130 	if (pcpus != NULL && pcpus != Py_None) {
2131 		if (!PyObject_TypeCheck(pcpus, &pyrf_cpu_map__type)) {
2132 			PyErr_SetString(PyExc_TypeError, "cpus must be a cpu_map");
2133 			return NULL;
2134 		}
2135 		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
2136 	}
2137 
2138 	evsel->core.attr.inherit = inherit;
2139 	/*
2140 	 * This will group just the fds for this single evsel, to group
2141 	 * multiple events, use evlist.open().
2142 	 */
2143 	if (evsel__open(evsel, cpus, threads) < 0) {
2144 		PyErr_SetFromErrno(PyExc_OSError);
2145 		return NULL;
2146 	}
2147 
2148 	Py_INCREF(Py_None);
2149 	return Py_None;
2150 }
2151 
2152 static PyObject *pyrf_evsel__cpus(struct pyrf_evsel *pevsel)
2153 {
2154 	struct pyrf_cpu_map *pcpu_map;
2155 
2156 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2157 
2158 	pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
2159 	if (pcpu_map)
2160 		pcpu_map->cpus = perf_cpu_map__get(pevsel->evsel->core.cpus);
2161 
2162 	return (PyObject *)pcpu_map;
2163 }
2164 
2165 static PyObject *pyrf_evsel__threads(struct pyrf_evsel *pevsel)
2166 {
2167 	struct pyrf_thread_map *pthread_map;
2168 
2169 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2170 
2171 	pthread_map = PyObject_New(struct pyrf_thread_map, &pyrf_thread_map__type);
2172 	if (pthread_map)
2173 		pthread_map->threads = perf_thread_map__get(pevsel->evsel->core.threads);
2174 
2175 	return (PyObject *)pthread_map;
2176 }
2177 
2178 /*
2179  * Ensure evsel's counts and prev_raw_counts are allocated, the latter
2180  * used by tool PMUs to compute the cumulative count as expected by
2181  * stat's process_counter_values.
2182  */
2183 static int evsel__ensure_counts(struct evsel *evsel)
2184 {
2185 	int nthreads, ncpus;
2186 
2187 	if (evsel->counts != NULL)
2188 		return 0;
2189 
2190 	nthreads = perf_thread_map__nr(evsel->core.threads);
2191 	ncpus = perf_cpu_map__nr(evsel->core.cpus);
2192 
2193 	evsel->counts = perf_counts__new(ncpus, nthreads);
2194 	if (evsel->counts == NULL)
2195 		return -ENOMEM;
2196 
2197 	evsel->prev_raw_counts = perf_counts__new(ncpus, nthreads);
2198 	if (evsel->prev_raw_counts == NULL)
2199 		return -ENOMEM;
2200 
2201 	return 0;
2202 }
2203 
2204 static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel,
2205 				  PyObject *args, PyObject *kwargs)
2206 {
2207 	struct evsel *evsel = pevsel->evsel;
2208 	int cpu = 0, cpu_idx, thread = 0, thread_idx;
2209 	struct perf_counts_values *old_count, *new_count;
2210 	struct pyrf_counts_values *count_values;
2211 
2212 	CHECK_INITIALIZED(evsel, "evsel");
2213 
2214 	if (!PyArg_ParseTuple(args, "ii", &cpu, &thread))
2215 		return NULL;
2216 
2217 	cpu_idx = perf_cpu_map__idx(evsel->core.cpus, (struct perf_cpu){.cpu = cpu});
2218 	if (cpu_idx < 0) {
2219 		PyErr_Format(PyExc_TypeError, "CPU %d is not part of evsel's CPUs", cpu);
2220 		return NULL;
2221 	}
2222 	thread_idx = perf_thread_map__idx(evsel->core.threads, thread);
2223 	if (thread_idx < 0) {
2224 		PyErr_Format(PyExc_TypeError, "Thread %d is not part of evsel's threads",
2225 			     thread);
2226 		return NULL;
2227 	}
2228 
2229 	if (evsel__ensure_counts(evsel))
2230 		return PyErr_NoMemory();
2231 
2232 	count_values = PyObject_New(struct pyrf_counts_values, &pyrf_counts_values__type);
2233 	if (!count_values)
2234 		return NULL;
2235 
2236 	/* Set up pointers to the old and newly read counter values. */
2237 	old_count = perf_counts(evsel->prev_raw_counts, cpu_idx, thread_idx);
2238 	new_count = perf_counts(evsel->counts, cpu_idx, thread_idx);
2239 	/* Update the value in evsel->counts. */
2240 	evsel__read_counter(evsel, cpu_idx, thread_idx);
2241 	/* Copy the value and turn it into the delta from old_count. */
2242 	count_values->values = *new_count;
2243 	count_values->values.val -= old_count->val;
2244 	count_values->values.ena -= old_count->ena;
2245 	count_values->values.run -= old_count->run;
2246 	/* Save the new count over the old_count for the next read. */
2247 	*old_count = *new_count;
2248 	return (PyObject *)count_values;
2249 }
2250 
2251 static PyObject *pyrf_evsel__str(PyObject *self)
2252 {
2253 	struct pyrf_evsel *pevsel = (void *)self;
2254 	struct evsel *evsel = pevsel->evsel;
2255 
2256 	if (!evsel)
2257 		return PyUnicode_FromString("evsel(uninitialized)");
2258 
2259 	return PyUnicode_FromFormat("evsel(%s)", evsel__name(evsel));
2260 }
2261 
2262 static PyMethodDef pyrf_evsel__methods[] = {
2263 	{
2264 		.ml_name  = "open",
2265 		.ml_meth  = (PyCFunction)pyrf_evsel__open,
2266 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
2267 		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
2268 	},
2269 	{
2270 		.ml_name  = "cpus",
2271 		.ml_meth  = (PyCFunction)pyrf_evsel__cpus,
2272 		.ml_flags = METH_NOARGS,
2273 		.ml_doc	  = PyDoc_STR("CPUs the event is to be used with.")
2274 	},
2275 	{
2276 		.ml_name  = "threads",
2277 		.ml_meth  = (PyCFunction)pyrf_evsel__threads,
2278 		.ml_flags = METH_NOARGS,
2279 		.ml_doc	  = PyDoc_STR("threads the event is to be used with.")
2280 	},
2281 	{
2282 		.ml_name  = "read",
2283 		.ml_meth  = (PyCFunction)pyrf_evsel__read,
2284 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
2285 		.ml_doc	  = PyDoc_STR("read counters")
2286 	},
2287 	{ .ml_name = NULL, }
2288 };
2289 
2290 static PyObject *pyrf_evsel__get_tracking(PyObject *self, void *closure __maybe_unused)
2291 {
2292 	struct pyrf_evsel *pevsel = (void *)self;
2293 
2294 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2295 
2296 	if (pevsel->evsel->tracking)
2297 		Py_RETURN_TRUE;
2298 	else
2299 		Py_RETURN_FALSE;
2300 }
2301 
2302 static int pyrf_evsel__set_tracking(PyObject *self, PyObject *val, void *closure __maybe_unused)
2303 {
2304 	struct pyrf_evsel *pevsel = (void *)self;
2305 	int is_true;
2306 
2307 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2308 
2309 	if (val == NULL) {
2310 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2311 		return -1;
2312 	}
2313 
2314 	is_true = PyObject_IsTrue(val);
2315 	if (is_true < 0)
2316 		return -1;
2317 
2318 	pevsel->evsel->tracking = is_true;
2319 	return 0;
2320 }
2321 
2322 static int pyrf_evsel__set_attr_config(PyObject *self, PyObject *val, void *closure __maybe_unused)
2323 {
2324 	struct pyrf_evsel *pevsel = (void *)self;
2325 	unsigned long long new_val;
2326 
2327 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2328 
2329 	if (val == NULL) {
2330 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2331 		return -1;
2332 	}
2333 
2334 	new_val = PyLong_AsUnsignedLongLong(val);
2335 	if (PyErr_Occurred())
2336 		return -1;
2337 
2338 	pevsel->evsel->core.attr.config = new_val;
2339 	return 0;
2340 }
2341 
2342 static PyObject *pyrf_evsel__get_attr_config(PyObject *self, void *closure __maybe_unused)
2343 {
2344 	struct pyrf_evsel *pevsel = (void *)self;
2345 
2346 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2347 
2348 	return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.config);
2349 }
2350 
2351 static int pyrf_evsel__set_attr_read_format(PyObject *self, PyObject *val, void *closure __maybe_unused)
2352 {
2353 	struct pyrf_evsel *pevsel = (void *)self;
2354 	unsigned long long new_val;
2355 
2356 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2357 
2358 	if (val == NULL) {
2359 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2360 		return -1;
2361 	}
2362 
2363 	new_val = PyLong_AsUnsignedLongLong(val);
2364 	if (PyErr_Occurred())
2365 		return -1;
2366 
2367 	pevsel->evsel->core.attr.read_format = new_val;
2368 	return 0;
2369 }
2370 
2371 static PyObject *pyrf_evsel__get_attr_read_format(PyObject *self, void *closure __maybe_unused)
2372 {
2373 	struct pyrf_evsel *pevsel = (void *)self;
2374 
2375 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2376 
2377 	return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.read_format);
2378 }
2379 
2380 static int pyrf_evsel__set_attr_sample_period(PyObject *self, PyObject *val, void *closure __maybe_unused)
2381 {
2382 	struct pyrf_evsel *pevsel = (void *)self;
2383 	unsigned long long new_val;
2384 
2385 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2386 
2387 	if (val == NULL) {
2388 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2389 		return -1;
2390 	}
2391 
2392 	new_val = PyLong_AsUnsignedLongLong(val);
2393 	if (PyErr_Occurred())
2394 		return -1;
2395 
2396 	pevsel->evsel->core.attr.sample_period = new_val;
2397 	return 0;
2398 }
2399 
2400 static PyObject *pyrf_evsel__get_attr_sample_period(PyObject *self, void *closure __maybe_unused)
2401 {
2402 	struct pyrf_evsel *pevsel = (void *)self;
2403 
2404 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2405 
2406 	return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_period);
2407 }
2408 
2409 static int pyrf_evsel__set_attr_sample_type(PyObject *self, PyObject *val, void *closure __maybe_unused)
2410 {
2411 	struct pyrf_evsel *pevsel = (void *)self;
2412 	unsigned long long new_val;
2413 
2414 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2415 
2416 	if (val == NULL) {
2417 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2418 		return -1;
2419 	}
2420 
2421 	new_val = PyLong_AsUnsignedLongLong(val);
2422 	if (PyErr_Occurred())
2423 		return -1;
2424 
2425 	pevsel->evsel->core.attr.sample_type = new_val;
2426 	return 0;
2427 }
2428 
2429 static PyObject *pyrf_evsel__get_attr_sample_type(PyObject *self, void *closure __maybe_unused)
2430 {
2431 	struct pyrf_evsel *pevsel = (void *)self;
2432 
2433 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2434 
2435 	return PyLong_FromUnsignedLongLong(pevsel->evsel->core.attr.sample_type);
2436 }
2437 
2438 static PyObject *pyrf_evsel__get_attr_size(PyObject *self, void *closure __maybe_unused)
2439 {
2440 	struct pyrf_evsel *pevsel = (void *)self;
2441 
2442 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2443 
2444 	return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.size);
2445 }
2446 
2447 static int pyrf_evsel__set_attr_type(PyObject *self, PyObject *val, void *closure __maybe_unused)
2448 {
2449 	struct pyrf_evsel *pevsel = (void *)self;
2450 	unsigned long new_val;
2451 
2452 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2453 
2454 	if (val == NULL) {
2455 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2456 		return -1;
2457 	}
2458 
2459 	new_val = PyLong_AsUnsignedLong(val);
2460 	if (PyErr_Occurred())
2461 		return -1;
2462 
2463 	pevsel->evsel->core.attr.type = new_val;
2464 	return 0;
2465 }
2466 
2467 static PyObject *pyrf_evsel__get_attr_type(PyObject *self, void *closure __maybe_unused)
2468 {
2469 	struct pyrf_evsel *pevsel = (void *)self;
2470 
2471 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2472 
2473 	return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.type);
2474 }
2475 
2476 static int pyrf_evsel__set_attr_wakeup_events(PyObject *self, PyObject *val, void *closure __maybe_unused)
2477 {
2478 	struct pyrf_evsel *pevsel = (void *)self;
2479 	unsigned long new_val;
2480 
2481 	CHECK_INITIALIZED_INT(pevsel->evsel, "evsel");
2482 
2483 	if (val == NULL) {
2484 		PyErr_SetString(PyExc_TypeError, "cannot delete attribute");
2485 		return -1;
2486 	}
2487 
2488 	new_val = PyLong_AsUnsignedLong(val);
2489 	if (PyErr_Occurred())
2490 		return -1;
2491 
2492 	pevsel->evsel->core.attr.wakeup_events = new_val;
2493 	return 0;
2494 }
2495 
2496 static PyObject *pyrf_evsel__get_attr_wakeup_events(PyObject *self, void *closure __maybe_unused)
2497 {
2498 	struct pyrf_evsel *pevsel = (void *)self;
2499 
2500 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2501 
2502 	return PyLong_FromUnsignedLong(pevsel->evsel->core.attr.wakeup_events);
2503 }
2504 
2505 static PyObject *pyrf_evsel__get_ids(struct pyrf_evsel *pevsel, void *closure __maybe_unused)
2506 {
2507 	struct evsel *evsel;
2508 	PyObject *list;
2509 
2510 	CHECK_INITIALIZED(pevsel->evsel, "evsel");
2511 
2512 	evsel = pevsel->evsel;
2513 	list = PyList_New(0);
2514 
2515 	if (!list)
2516 		return NULL;
2517 
2518 	for (u32 i = 0; i < evsel->core.ids; i++) {
2519 		PyObject *id = PyLong_FromUnsignedLongLong(evsel->core.id[i]);
2520 		int ret;
2521 
2522 		if (!id) {
2523 			Py_DECREF(list);
2524 			return NULL;
2525 		}
2526 		ret = PyList_Append(list, id);
2527 		Py_DECREF(id);
2528 		if (ret < 0) {
2529 			Py_DECREF(list);
2530 			return NULL;
2531 		}
2532 	}
2533 
2534 	return list;
2535 }
2536 
2537 static PyGetSetDef pyrf_evsel__getset[] = {
2538 	{
2539 		.name = "ids",
2540 		.get = (getter)pyrf_evsel__get_ids,
2541 		.set = NULL,
2542 		.doc = "event IDs.",
2543 	},
2544 	{
2545 		.name = "tracking",
2546 		.get = pyrf_evsel__get_tracking,
2547 		.set = pyrf_evsel__set_tracking,
2548 		.doc = "tracking event.",
2549 	},
2550 	{
2551 		.name = "config",
2552 		.get = pyrf_evsel__get_attr_config,
2553 		.set = pyrf_evsel__set_attr_config,
2554 		.doc = "attribute config.",
2555 	},
2556 	{
2557 		.name = "read_format",
2558 		.get = pyrf_evsel__get_attr_read_format,
2559 		.set = pyrf_evsel__set_attr_read_format,
2560 		.doc = "attribute read_format.",
2561 	},
2562 	{
2563 		.name = "sample_period",
2564 		.get = pyrf_evsel__get_attr_sample_period,
2565 		.set = pyrf_evsel__set_attr_sample_period,
2566 		.doc = "attribute sample_period.",
2567 	},
2568 	{
2569 		.name = "sample_type",
2570 		.get = pyrf_evsel__get_attr_sample_type,
2571 		.set = pyrf_evsel__set_attr_sample_type,
2572 		.doc = "attribute sample_type.",
2573 	},
2574 	{
2575 		.name = "size",
2576 		.get = pyrf_evsel__get_attr_size,
2577 		.doc = "attribute size.",
2578 	},
2579 	{
2580 		.name = "type",
2581 		.get = pyrf_evsel__get_attr_type,
2582 		.set = pyrf_evsel__set_attr_type,
2583 		.doc = "attribute type.",
2584 	},
2585 	{
2586 		.name = "wakeup_events",
2587 		.get = pyrf_evsel__get_attr_wakeup_events,
2588 		.set = pyrf_evsel__set_attr_wakeup_events,
2589 		.doc = "attribute wakeup_events.",
2590 	},
2591 	{ .name = NULL},
2592 };
2593 
2594 static const char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
2595 
2596 static PyObject *pyrf_evsel__getattro(struct pyrf_evsel *pevsel, PyObject *attr_name)
2597 {
2598 	if (!pevsel->evsel) {
2599 		PyErr_SetString(PyExc_ValueError, "evsel not initialized");
2600 		return NULL;
2601 	}
2602 	return PyObject_GenericGetAttr((PyObject *) pevsel, attr_name);
2603 }
2604 
2605 static int pyrf_evsel__setattro(struct pyrf_evsel *pevsel, PyObject *attr_name, PyObject *value)
2606 {
2607 	if (!pevsel->evsel) {
2608 		PyErr_SetString(PyExc_ValueError, "evsel not initialized");
2609 		return -1;
2610 	}
2611 	return PyObject_GenericSetAttr((PyObject *) pevsel, attr_name, value);
2612 }
2613 
2614 static PyTypeObject pyrf_evsel__type = {
2615 	PyVarObject_HEAD_INIT(NULL, 0)
2616 	.tp_name	= "perf.evsel",
2617 	.tp_basicsize	= sizeof(struct pyrf_evsel),
2618 	.tp_dealloc	= (destructor)pyrf_evsel__delete,
2619 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
2620 	.tp_doc		= pyrf_evsel__doc,
2621 	.tp_getset	= pyrf_evsel__getset,
2622 	.tp_methods	= pyrf_evsel__methods,
2623 	.tp_init	= (initproc)pyrf_evsel__init,
2624 	.tp_str         = pyrf_evsel__str,
2625 	.tp_repr        = pyrf_evsel__str,
2626 	.tp_getattro	= (getattrofunc) pyrf_evsel__getattro,
2627 	.tp_setattro	= (setattrofunc) pyrf_evsel__setattro,
2628 };
2629 
2630 static PyObject *pyrf_evsel__new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
2631 {
2632 	struct pyrf_evsel *pevsel;
2633 
2634 	pevsel = (struct pyrf_evsel *)PyType_GenericNew(type, args, kwargs);
2635 	if (pevsel)
2636 		pevsel->evsel = NULL;
2637 	return (PyObject *)pevsel;
2638 }
2639 
2640 static int pyrf_evsel__setup_types(void)
2641 {
2642 	pyrf_evsel__type.tp_new = pyrf_evsel__new;
2643 	return PyType_Ready(&pyrf_evsel__type);
2644 }
2645 
2646 struct pyrf_evlist {
2647 	PyObject_HEAD
2648 
2649 	struct evlist *evlist;
2650 };
2651 
2652 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
2653 			     PyObject *args, PyObject *kwargs __maybe_unused)
2654 {
2655 	PyObject *pcpus = NULL, *pthreads = NULL;
2656 	struct perf_cpu_map *cpus;
2657 	struct perf_thread_map *threads;
2658 
2659 	if (!PyArg_ParseTuple(args, "O!O!",
2660 			      &pyrf_cpu_map__type, &pcpus,
2661 			      &pyrf_thread_map__type, &pthreads))
2662 		return -1;
2663 
2664 	evlist__put(pevlist->evlist);
2665 	pevlist->evlist = evlist__new();
2666 	if (!pevlist->evlist) {
2667 		PyErr_NoMemory();
2668 		return -1;
2669 	}
2670 	threads = ((struct pyrf_thread_map *)pthreads)->threads;
2671 	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
2672 	perf_evlist__set_maps(evlist__core(pevlist->evlist), cpus, threads);
2673 
2674 	return 0;
2675 }
2676 
2677 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
2678 {
2679 	evlist__put(pevlist->evlist);
2680 	Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
2681 }
2682 
2683 static PyObject *pyrf_evlist__all_cpus(struct pyrf_evlist *pevlist)
2684 {
2685 	struct pyrf_cpu_map *pcpu_map;
2686 
2687 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2688 
2689 	pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
2690 	if (pcpu_map)
2691 		pcpu_map->cpus = perf_cpu_map__get(evlist__core(pevlist->evlist)->all_cpus);
2692 
2693 	return (PyObject *)pcpu_map;
2694 }
2695 
2696 static PyObject *pyrf_evlist__metrics(struct pyrf_evlist *pevlist)
2697 {
2698 	PyObject *list;
2699 	struct rb_node *node;
2700 
2701 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2702 
2703 	list = PyList_New(/*len=*/0);
2704 	if (!list)
2705 		return NULL;
2706 
2707 	for (node = rb_first_cached(&evlist__metric_events(pevlist->evlist)->entries); node;
2708 	     node = rb_next(node)) {
2709 		struct metric_event *me = container_of(node, struct metric_event, nd);
2710 		struct list_head *pos;
2711 
2712 		list_for_each(pos, &me->head) {
2713 			struct metric_expr *expr = container_of(pos, struct metric_expr, nd);
2714 			PyObject *str = PyUnicode_FromString(expr->metric_name);
2715 
2716 			if (!str || PyList_Append(list, str) != 0) {
2717 				Py_DECREF(list);
2718 				return NULL;
2719 			}
2720 			Py_DECREF(str);
2721 		}
2722 	}
2723 	return list;
2724 }
2725 
2726 static int prepare_metric(const struct metric_expr *mexp,
2727 			  const struct evsel *evsel,
2728 			  struct expr_parse_ctx *pctx,
2729 			  int cpu_idx, int thread_idx)
2730 {
2731 	struct evsel * const *metric_events = mexp->metric_events;
2732 	struct metric_ref *metric_refs = mexp->metric_refs;
2733 
2734 	for (int i = 0; metric_events[i]; i++) {
2735 		struct evsel *cur = metric_events[i];
2736 		double val, ena, run;
2737 		int ret, source_count = 0;
2738 		struct perf_counts_values *old_count, *new_count;
2739 		char *n = strdup(evsel__metric_id(cur));
2740 
2741 		if (!n)
2742 			return -ENOMEM;
2743 
2744 		/*
2745 		 * If there are multiple uncore PMUs and we're not reading the
2746 		 * leader's stats, determine the stats for the appropriate
2747 		 * uncore PMU.
2748 		 */
2749 		if (evsel && evsel->metric_leader &&
2750 		    evsel->pmu != evsel->metric_leader->pmu &&
2751 		    cur->pmu == evsel->metric_leader->pmu) {
2752 			struct evsel *pos;
2753 
2754 			evlist__for_each_entry(evsel->evlist, pos) {
2755 				if (pos->pmu != evsel->pmu)
2756 					continue;
2757 				if (pos->metric_leader != cur)
2758 					continue;
2759 				cur = pos;
2760 				source_count = 1;
2761 				break;
2762 			}
2763 		}
2764 
2765 		if (source_count == 0)
2766 			source_count = evsel__source_count(cur);
2767 
2768 		ret = evsel__ensure_counts(cur);
2769 		if (ret)
2770 			return ret;
2771 
2772 		/* Set up pointers to the old and newly read counter values. */
2773 		old_count = perf_counts(cur->prev_raw_counts, cpu_idx, thread_idx);
2774 		new_count = perf_counts(cur->counts, cpu_idx, thread_idx);
2775 		/* Update the value in cur->counts. */
2776 		evsel__read_counter(cur, cpu_idx, thread_idx);
2777 
2778 		val = new_count->val - old_count->val;
2779 		ena = new_count->ena - old_count->ena;
2780 		run = new_count->run - old_count->run;
2781 
2782 		if (ena != run && run != 0)
2783 			val = val * ena / run;
2784 		ret = expr__add_id_val_source_count(pctx, n, val, source_count);
2785 		if (ret)
2786 			return ret;
2787 	}
2788 
2789 	for (int i = 0; metric_refs && metric_refs[i].metric_name; i++) {
2790 		int ret = expr__add_ref(pctx, &metric_refs[i]);
2791 
2792 		if (ret)
2793 			return ret;
2794 	}
2795 
2796 	return 0;
2797 }
2798 
2799 static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist,
2800 					     PyObject *args, PyObject *kwargs)
2801 {
2802 	int ret, cpu = 0, cpu_idx = 0, thread = 0, thread_idx = 0;
2803 	const char *metric;
2804 	struct rb_node *node;
2805 	struct metric_expr *mexp = NULL;
2806 	struct expr_parse_ctx *pctx;
2807 	double result = 0;
2808 	struct evsel *metric_evsel = NULL;
2809 
2810 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2811 
2812 	if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread))
2813 		return NULL;
2814 
2815 	for (node = rb_first_cached(&evlist__metric_events(pevlist->evlist)->entries);
2816 	     mexp == NULL && node;
2817 	     node = rb_next(node)) {
2818 		struct metric_event *me = container_of(node, struct metric_event, nd);
2819 		struct list_head *pos;
2820 
2821 		list_for_each(pos, &me->head) {
2822 			struct metric_expr *e = container_of(pos, struct metric_expr, nd);
2823 			struct evsel *pos2;
2824 
2825 			if (strcmp(e->metric_name, metric))
2826 				continue;
2827 
2828 			if (e->metric_events[0] == NULL)
2829 				continue;
2830 
2831 			evlist__for_each_entry(pevlist->evlist, pos2) {
2832 				if (pos2->metric_leader != e->metric_events[0])
2833 					continue;
2834 				cpu_idx = perf_cpu_map__idx(pos2->core.cpus,
2835 							    (struct perf_cpu){.cpu = cpu});
2836 				if (cpu_idx < 0)
2837 					continue;
2838 
2839 				thread_idx = perf_thread_map__idx(pos2->core.threads, thread);
2840 				if (thread_idx < 0)
2841 					continue;
2842 				metric_evsel = pos2;
2843 				mexp = e;
2844 				goto done;
2845 			}
2846 		}
2847 	}
2848 done:
2849 	if (!mexp) {
2850 		PyErr_Format(PyExc_TypeError, "Unknown metric '%s' for CPU '%d' and thread '%d'",
2851 			     metric, cpu, thread);
2852 		return NULL;
2853 	}
2854 
2855 	pctx = expr__ctx_new();
2856 	if (!pctx)
2857 		return PyErr_NoMemory();
2858 
2859 	ret = prepare_metric(mexp, metric_evsel, pctx, cpu_idx, thread_idx);
2860 	if (ret) {
2861 		expr__ctx_free(pctx);
2862 		errno = -ret;
2863 		PyErr_SetFromErrno(PyExc_OSError);
2864 		return NULL;
2865 	}
2866 	if (expr__parse(&result, pctx, mexp->metric_expr))
2867 		result = 0.0;
2868 
2869 	expr__ctx_free(pctx);
2870 	return PyFloat_FromDouble(result);
2871 }
2872 
2873 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
2874 				   PyObject *args, PyObject *kwargs)
2875 {
2876 	struct evlist *evlist;
2877 	static char *kwlist[] = { "pages", "overwrite", NULL };
2878 	int pages = 128, overwrite = false;
2879 
2880 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2881 
2882 	evlist = pevlist->evlist;
2883 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
2884 					 &pages, &overwrite))
2885 		return NULL;
2886 
2887 	if (evlist__do_mmap(evlist, pages) < 0) {
2888 		PyErr_SetFromErrno(PyExc_OSError);
2889 		return NULL;
2890 	}
2891 
2892 	Py_INCREF(Py_None);
2893 	return Py_None;
2894 }
2895 
2896 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
2897 				   PyObject *args, PyObject *kwargs)
2898 {
2899 	struct evlist *evlist;
2900 	static char *kwlist[] = { "timeout", NULL };
2901 	int timeout = -1, n;
2902 
2903 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2904 
2905 	evlist = pevlist->evlist;
2906 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
2907 		return NULL;
2908 
2909 	n = evlist__poll(evlist, timeout);
2910 	if (n < 0) {
2911 		PyErr_SetFromErrno(PyExc_OSError);
2912 		return NULL;
2913 	}
2914 
2915 	return Py_BuildValue("i", n);
2916 }
2917 
2918 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
2919 					 PyObject *args __maybe_unused,
2920 					 PyObject *kwargs __maybe_unused)
2921 {
2922 	struct evlist *evlist;
2923 	PyObject *list;
2924 	int i;
2925 
2926 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2927 
2928 	evlist = pevlist->evlist;
2929 	list = PyList_New(0);
2930 	if (!list)
2931 		return NULL;
2932 
2933 	for (i = 0; i < evlist__core(evlist)->pollfd.nr; ++i) {
2934 		PyObject *file;
2935 		file = PyFile_FromFd(evlist__core(evlist)->pollfd.entries[i].fd, "perf", "r", -1,
2936 				     NULL, NULL, NULL, 0);
2937 		if (file == NULL)
2938 			goto free_list;
2939 
2940 		if (PyList_Append(list, file) != 0) {
2941 			Py_DECREF(file);
2942 			goto free_list;
2943 		}
2944 
2945 		Py_DECREF(file);
2946 	}
2947 
2948 	return list;
2949 free_list:
2950 	Py_XDECREF(list);
2951 	return PyErr_NoMemory();
2952 }
2953 
2954 
2955 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
2956 				  PyObject *args,
2957 				  PyObject *kwargs __maybe_unused)
2958 {
2959 	struct evlist *evlist;
2960 	PyObject *pevsel;
2961 	struct evsel *evsel;
2962 
2963 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
2964 
2965 	evlist = pevlist->evlist;
2966 	if (!PyArg_ParseTuple(args, "O!", &pyrf_evsel__type, &pevsel))
2967 		return NULL;
2968 
2969 	CHECK_INITIALIZED(((struct pyrf_evsel *)pevsel)->evsel, "evsel");
2970 
2971 	evsel = ((struct pyrf_evsel *)pevsel)->evsel;
2972 	CHECK_INITIALIZED(evsel, "evsel");
2973 
2974 	evsel->core.idx = evlist__nr_entries(evlist);
2975 	evlist__add(evlist, evsel__get(evsel));
2976 
2977 	return Py_BuildValue("i", evlist__nr_entries(evlist));
2978 }
2979 
2980 static struct mmap *get_md(struct evlist *evlist, int cpu)
2981 {
2982 	int i;
2983 
2984 	for (i = 0; i < evlist__core(evlist)->nr_mmaps; i++) {
2985 		struct mmap *md = &evlist__mmap(evlist)[i];
2986 
2987 		if (md->core.cpu.cpu == cpu)
2988 			return md;
2989 	}
2990 
2991 	return NULL;
2992 }
2993 
2994 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
2995 					  PyObject *args, PyObject *kwargs)
2996 {
2997 	struct evlist *evlist;
2998 	union perf_event *event;
2999 	struct evsel *evsel;
3000 	int sample_id_all = 1, cpu;
3001 	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
3002 	struct mmap *md;
3003 	PyObject *pyevent;
3004 	int err;
3005 
3006 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3007 
3008 	evlist = pevlist->evlist;
3009 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
3010 					 &cpu, &sample_id_all))
3011 		return NULL;
3012 
3013 	md = get_md(evlist, cpu);
3014 	if (!md)
3015 		return PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu);
3016 
3017 	err = perf_mmap__read_init(&md->core);
3018 	if (err < 0) {
3019 		if (err == -EAGAIN)
3020 			Py_RETURN_NONE;
3021 		return PyErr_Format(PyExc_OSError,
3022 				    "perf: error mmap read init, err=%d", err);
3023 	}
3024 
3025 	event = perf_mmap__read_event(&md->core);
3026 	if (event == NULL)
3027 		Py_RETURN_NONE;
3028 
3029 	evsel = evlist__event2evsel(evlist, event);
3030 	if (!evsel) {
3031 		/* Unknown evsel. */
3032 		perf_mmap__consume(&md->core);
3033 		Py_RETURN_NONE;
3034 	}
3035 	pyevent = pyrf_event__new(event, evsel, evlist__session(evlist), /*machine=*/NULL);
3036 	perf_mmap__consume(&md->core);
3037 	if (pyevent == NULL)
3038 		return PyErr_Occurred() ? NULL : PyErr_NoMemory();
3039 
3040 	return pyevent;
3041 }
3042 
3043 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
3044 				   PyObject *args, PyObject *kwargs)
3045 {
3046 	struct evlist *evlist;
3047 
3048 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3049 
3050 	evlist = pevlist->evlist;
3051 	if (evlist__open(evlist) < 0) {
3052 		PyErr_SetFromErrno(PyExc_OSError);
3053 		return NULL;
3054 	}
3055 
3056 	Py_INCREF(Py_None);
3057 	return Py_None;
3058 }
3059 
3060 static PyObject *pyrf_evlist__close(struct pyrf_evlist *pevlist)
3061 {
3062 	struct evlist *evlist;
3063 
3064 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3065 
3066 	evlist = pevlist->evlist;
3067 	evlist__close(evlist);
3068 
3069 	Py_INCREF(Py_None);
3070 	return Py_None;
3071 }
3072 
3073 static PyObject *pyrf_evlist__config(struct pyrf_evlist *pevlist)
3074 {
3075 	struct record_opts opts = {
3076 		.sample_time	     = true,
3077 		.mmap_pages	     = UINT_MAX,
3078 		.user_freq	     = UINT_MAX,
3079 		.user_interval	     = ULLONG_MAX,
3080 		.freq		     = 4000,
3081 		.target		     = {
3082 			.uses_mmap   = true,
3083 			.default_per_cpu = true,
3084 		},
3085 		.nr_threads_synthesize = 1,
3086 		.ctl_fd              = -1,
3087 		.ctl_fd_ack          = -1,
3088 		.no_buffering        = true,
3089 		.no_inherit          = true,
3090 	};
3091 	struct evlist *evlist;
3092 
3093 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3094 
3095 	evlist = pevlist->evlist;
3096 	evlist__config(evlist, &opts, &callchain_param);
3097 	Py_INCREF(Py_None);
3098 	return Py_None;
3099 }
3100 
3101 static PyObject *pyrf_evlist__disable(struct pyrf_evlist *pevlist)
3102 {
3103 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3104 	evlist__disable(pevlist->evlist);
3105 	Py_INCREF(Py_None);
3106 	return Py_None;
3107 }
3108 
3109 static PyObject *pyrf_evlist__enable(struct pyrf_evlist *pevlist)
3110 {
3111 	CHECK_INITIALIZED(pevlist->evlist, "evlist");
3112 	evlist__enable(pevlist->evlist);
3113 	Py_INCREF(Py_None);
3114 	return Py_None;
3115 }
3116 
3117 static PyMethodDef pyrf_evlist__methods[] = {
3118 	{
3119 		.ml_name  = "all_cpus",
3120 		.ml_meth  = (PyCFunction)pyrf_evlist__all_cpus,
3121 		.ml_flags = METH_NOARGS,
3122 		.ml_doc	  = PyDoc_STR("CPU map union of all evsel CPU maps.")
3123 	},
3124 	{
3125 		.ml_name  = "metrics",
3126 		.ml_meth  = (PyCFunction)pyrf_evlist__metrics,
3127 		.ml_flags = METH_NOARGS,
3128 		.ml_doc	  = PyDoc_STR("List of metric names within the evlist.")
3129 	},
3130 	{
3131 		.ml_name  = "compute_metric",
3132 		.ml_meth  = (PyCFunction)pyrf_evlist__compute_metric,
3133 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3134 		.ml_doc	  = PyDoc_STR("compute metric for given name, cpu and thread")
3135 	},
3136 	{
3137 		.ml_name  = "mmap",
3138 		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
3139 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3140 		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
3141 	},
3142 	{
3143 		.ml_name  = "open",
3144 		.ml_meth  = (PyCFunction)pyrf_evlist__open,
3145 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3146 		.ml_doc	  = PyDoc_STR("open the file descriptors.")
3147 	},
3148 	{
3149 		.ml_name  = "close",
3150 		.ml_meth  = (PyCFunction)pyrf_evlist__close,
3151 		.ml_flags = METH_NOARGS,
3152 		.ml_doc	  = PyDoc_STR("close the file descriptors.")
3153 	},
3154 	{
3155 		.ml_name  = "poll",
3156 		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
3157 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3158 		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
3159 	},
3160 	{
3161 		.ml_name  = "get_pollfd",
3162 		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
3163 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3164 		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
3165 	},
3166 	{
3167 		.ml_name  = "add",
3168 		.ml_meth  = (PyCFunction)pyrf_evlist__add,
3169 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3170 		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
3171 	},
3172 	{
3173 		.ml_name  = "read_on_cpu",
3174 		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
3175 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
3176 		.ml_doc	  = PyDoc_STR("reads an event.")
3177 	},
3178 	{
3179 		.ml_name  = "config",
3180 		.ml_meth  = (PyCFunction)pyrf_evlist__config,
3181 		.ml_flags = METH_NOARGS,
3182 		.ml_doc	  = PyDoc_STR("Apply default record options to the evlist.")
3183 	},
3184 	{
3185 		.ml_name  = "disable",
3186 		.ml_meth  = (PyCFunction)pyrf_evlist__disable,
3187 		.ml_flags = METH_NOARGS,
3188 		.ml_doc	  = PyDoc_STR("Disable the evsels in the evlist.")
3189 	},
3190 	{
3191 		.ml_name  = "enable",
3192 		.ml_meth  = (PyCFunction)pyrf_evlist__enable,
3193 		.ml_flags = METH_NOARGS,
3194 		.ml_doc	  = PyDoc_STR("Enable the evsels in the evlist.")
3195 	},
3196 	{ .ml_name = NULL, }
3197 };
3198 
3199 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
3200 {
3201 	struct pyrf_evlist *pevlist = (void *)obj;
3202 
3203 	if (!pevlist->evlist)
3204 		return 0;
3205 
3206 	return evlist__nr_entries(pevlist->evlist);
3207 }
3208 
3209 static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
3210 {
3211 	struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type);
3212 
3213 	if (!pevsel)
3214 		return NULL;
3215 
3216 	pevsel->evsel = evsel__get(evsel);
3217 	return (PyObject *)pevsel;
3218 }
3219 
3220 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
3221 {
3222 	struct pyrf_evlist *pevlist = (void *)obj;
3223 	struct evsel *pos;
3224 
3225 	if (!pevlist->evlist || i >= evlist__nr_entries(pevlist->evlist)) {
3226 		PyErr_SetString(PyExc_IndexError, "Index out of range");
3227 		return NULL;
3228 	}
3229 
3230 	evlist__for_each_entry(pevlist->evlist, pos) {
3231 		if (i-- == 0)
3232 			break;
3233 	}
3234 	return pyrf_evsel__from_evsel(pos);
3235 }
3236 
3237 static PyObject *pyrf_evlist__str(PyObject *self)
3238 {
3239 	struct pyrf_evlist *pevlist = (void *)self;
3240 	struct evsel *pos;
3241 	struct strbuf sb = STRBUF_INIT;
3242 	bool first = true;
3243 	PyObject *result;
3244 
3245 	if (!pevlist->evlist)
3246 		return PyUnicode_FromString("evlist(uninitialized)");
3247 
3248 	strbuf_addstr(&sb, "evlist([");
3249 	evlist__for_each_entry(pevlist->evlist, pos) {
3250 		if (!first)
3251 			strbuf_addch(&sb, ',');
3252 		strbuf_addstr(&sb, evsel__name(pos));
3253 		first = false;
3254 	}
3255 	strbuf_addstr(&sb, "])");
3256 	result = PyUnicode_FromString(sb.buf);
3257 	strbuf_release(&sb);
3258 	return result;
3259 }
3260 
3261 static PySequenceMethods pyrf_evlist__sequence_methods = {
3262 	.sq_length = pyrf_evlist__length,
3263 	.sq_item   = pyrf_evlist__item,
3264 };
3265 
3266 static const char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
3267 
3268 static PyObject *pyrf_evlist__getattro(struct pyrf_evlist *pevlist, PyObject *attr_name)
3269 {
3270 	if (!pevlist->evlist) {
3271 		PyErr_SetString(PyExc_ValueError, "evlist not initialized");
3272 		return NULL;
3273 	}
3274 	return PyObject_GenericGetAttr((PyObject *) pevlist, attr_name);
3275 }
3276 
3277 static int pyrf_evlist__setattro(struct pyrf_evlist *pevlist, PyObject *attr_name, PyObject *value)
3278 {
3279 	if (!pevlist->evlist) {
3280 		PyErr_SetString(PyExc_ValueError, "evlist not initialized");
3281 		return -1;
3282 	}
3283 	return PyObject_GenericSetAttr((PyObject *) pevlist, attr_name, value);
3284 }
3285 
3286 static PyTypeObject pyrf_evlist__type = {
3287 	PyVarObject_HEAD_INIT(NULL, 0)
3288 	.tp_name	= "perf.evlist",
3289 	.tp_basicsize	= sizeof(struct pyrf_evlist),
3290 	.tp_dealloc	= (destructor)pyrf_evlist__delete,
3291 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
3292 	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
3293 	.tp_doc		= pyrf_evlist__doc,
3294 	.tp_methods	= pyrf_evlist__methods,
3295 	.tp_init	= (initproc)pyrf_evlist__init,
3296 	.tp_repr        = pyrf_evlist__str,
3297 	.tp_str         = pyrf_evlist__str,
3298 	.tp_getattro	= (getattrofunc) pyrf_evlist__getattro,
3299 	.tp_setattro	= (setattrofunc) pyrf_evlist__setattro,
3300 };
3301 
3302 static PyObject *pyrf_evlist__new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3303 {
3304 	struct pyrf_evlist *pevlist;
3305 
3306 	pevlist = (struct pyrf_evlist *)PyType_GenericNew(type, args, kwargs);
3307 	if (pevlist)
3308 		pevlist->evlist = NULL;
3309 	return (PyObject *)pevlist;
3310 }
3311 
3312 static int pyrf_evlist__setup_types(void)
3313 {
3314 	pyrf_evlist__type.tp_new = pyrf_evlist__new;
3315 	return PyType_Ready(&pyrf_evlist__type);
3316 }
3317 
3318 #define PERF_CONST(name) { #name, PERF_##name }
3319 
3320 struct perf_constant {
3321 	const char *name;
3322 	int	    value;
3323 };
3324 
3325 static const struct perf_constant perf__constants[] = {
3326 	PERF_CONST(TYPE_HARDWARE),
3327 	PERF_CONST(TYPE_SOFTWARE),
3328 	PERF_CONST(TYPE_TRACEPOINT),
3329 	PERF_CONST(TYPE_HW_CACHE),
3330 	PERF_CONST(TYPE_RAW),
3331 	PERF_CONST(TYPE_BREAKPOINT),
3332 
3333 	PERF_CONST(COUNT_HW_CPU_CYCLES),
3334 	PERF_CONST(COUNT_HW_REF_CPU_CYCLES),
3335 	PERF_CONST(COUNT_HW_INSTRUCTIONS),
3336 	PERF_CONST(COUNT_HW_CACHE_REFERENCES),
3337 	PERF_CONST(COUNT_HW_CACHE_MISSES),
3338 	PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
3339 	PERF_CONST(COUNT_HW_BRANCH_MISSES),
3340 	PERF_CONST(COUNT_HW_BUS_CYCLES),
3341 	PERF_CONST(COUNT_HW_CACHE_L1D),
3342 	PERF_CONST(COUNT_HW_CACHE_L1I),
3343 	PERF_CONST(COUNT_HW_CACHE_LL),
3344 	PERF_CONST(COUNT_HW_CACHE_DTLB),
3345 	PERF_CONST(COUNT_HW_CACHE_ITLB),
3346 	PERF_CONST(COUNT_HW_CACHE_BPU),
3347 	PERF_CONST(COUNT_HW_CACHE_OP_READ),
3348 	PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
3349 	PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
3350 	PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
3351 	PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
3352 
3353 	PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
3354 	PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
3355 
3356 	PERF_CONST(COUNT_SW_CPU_CLOCK),
3357 	PERF_CONST(COUNT_SW_TASK_CLOCK),
3358 	PERF_CONST(COUNT_SW_PAGE_FAULTS),
3359 	PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
3360 	PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
3361 	PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
3362 	PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
3363 	PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
3364 	PERF_CONST(COUNT_SW_EMULATION_FAULTS),
3365 	PERF_CONST(COUNT_SW_DUMMY),
3366 
3367 	PERF_CONST(SAMPLE_IP),
3368 	PERF_CONST(SAMPLE_TID),
3369 	PERF_CONST(SAMPLE_TIME),
3370 	PERF_CONST(SAMPLE_ADDR),
3371 	PERF_CONST(SAMPLE_READ),
3372 	PERF_CONST(SAMPLE_CALLCHAIN),
3373 	PERF_CONST(SAMPLE_ID),
3374 	PERF_CONST(SAMPLE_CPU),
3375 	PERF_CONST(SAMPLE_PERIOD),
3376 	PERF_CONST(SAMPLE_STREAM_ID),
3377 	PERF_CONST(SAMPLE_RAW),
3378 
3379 	PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
3380 	PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
3381 	PERF_CONST(FORMAT_ID),
3382 	PERF_CONST(FORMAT_GROUP),
3383 
3384 	PERF_CONST(RECORD_MMAP),
3385 	PERF_CONST(RECORD_LOST),
3386 	PERF_CONST(RECORD_COMM),
3387 	PERF_CONST(RECORD_EXIT),
3388 	PERF_CONST(RECORD_THROTTLE),
3389 	PERF_CONST(RECORD_UNTHROTTLE),
3390 	PERF_CONST(RECORD_FORK),
3391 	PERF_CONST(RECORD_READ),
3392 	PERF_CONST(RECORD_SAMPLE),
3393 	PERF_CONST(RECORD_MMAP2),
3394 	PERF_CONST(RECORD_AUX),
3395 	PERF_CONST(RECORD_ITRACE_START),
3396 	PERF_CONST(RECORD_LOST_SAMPLES),
3397 	PERF_CONST(RECORD_SWITCH),
3398 	PERF_CONST(RECORD_SWITCH_CPU_WIDE),
3399 	PERF_CONST(RECORD_STAT),
3400 	PERF_CONST(RECORD_STAT_ROUND),
3401 
3402 	PERF_CONST(RECORD_MISC_SWITCH_OUT),
3403 	{ .name = NULL, },
3404 };
3405 
3406 static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
3407 				  PyObject *args, PyObject *kwargs)
3408 {
3409 	static char *kwlist[] = { "sys", "name", NULL };
3410 	char *sys  = NULL;
3411 	char *name = NULL;
3412 
3413 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
3414 					 &sys, &name))
3415 		return NULL;
3416 
3417 	return PyLong_FromLong(tp_pmu__id(sys, name));
3418 }
3419 
3420 static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist)
3421 {
3422 	struct pyrf_evlist *pevlist = PyObject_New(struct pyrf_evlist, &pyrf_evlist__type);
3423 
3424 	if (!pevlist)
3425 		return NULL;
3426 
3427 	pevlist->evlist = evlist__get(evlist);
3428 	return (PyObject *)pevlist;
3429 }
3430 
3431 static PyObject *pyrf__parse_events(PyObject *self, PyObject *args)
3432 {
3433 	const char *input;
3434 	struct evlist *evlist = evlist__new();
3435 	struct parse_events_error err;
3436 	PyObject *result;
3437 	PyObject *pcpus = NULL, *pthreads = NULL;
3438 	struct perf_cpu_map *cpus;
3439 	struct perf_thread_map *threads;
3440 
3441 	if (!evlist)
3442 		return PyErr_NoMemory();
3443 
3444 	if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads)) {
3445 		evlist__put(evlist);
3446 		return NULL;
3447 	}
3448 
3449 	if (pthreads && pthreads != Py_None &&
3450 	    !PyObject_TypeCheck(pthreads, &pyrf_thread_map__type)) {
3451 		PyErr_SetString(PyExc_TypeError, "threads must be a perf.thread_map or None");
3452 		evlist__put(evlist);
3453 		return NULL;
3454 	}
3455 
3456 	if (pcpus && pcpus != Py_None &&
3457 	    !PyObject_TypeCheck(pcpus, &pyrf_cpu_map__type)) {
3458 		PyErr_SetString(PyExc_TypeError, "cpus must be a perf.cpu_map or None");
3459 		evlist__put(evlist);
3460 		return NULL;
3461 	}
3462 
3463 	threads = (pthreads && pthreads != Py_None) ?
3464 			((struct pyrf_thread_map *)pthreads)->threads : NULL;
3465 	cpus = (pcpus && pcpus != Py_None) ?
3466 			((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
3467 
3468 	parse_events_error__init(&err);
3469 	perf_evlist__set_maps(evlist__core(evlist), cpus, threads);
3470 	if (parse_events(evlist, input, &err)) {
3471 		parse_events_error__print(&err, input);
3472 		PyErr_SetFromErrno(PyExc_OSError);
3473 		evlist__put(evlist);
3474 		return NULL;
3475 	}
3476 	result = pyrf_evlist__from_evlist(evlist);
3477 	evlist__put(evlist);
3478 	return result;
3479 }
3480 
3481 static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args)
3482 {
3483 	const char *input, *pmu = NULL;
3484 	struct evlist *evlist = evlist__new();
3485 	PyObject *result;
3486 	PyObject *pcpus = NULL, *pthreads = NULL;
3487 	struct perf_cpu_map *cpus;
3488 	struct perf_thread_map *threads;
3489 	int ret;
3490 
3491 	if (!evlist)
3492 		return PyErr_NoMemory();
3493 
3494 	if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads)) {
3495 		evlist__put(evlist);
3496 		return NULL;
3497 	}
3498 
3499 	if (pthreads && pthreads != Py_None &&
3500 	    !PyObject_TypeCheck(pthreads, &pyrf_thread_map__type)) {
3501 		PyErr_SetString(PyExc_TypeError, "threads must be a perf.thread_map or None");
3502 		evlist__put(evlist);
3503 		return NULL;
3504 	}
3505 
3506 	if (pcpus && pcpus != Py_None &&
3507 	    !PyObject_TypeCheck(pcpus, &pyrf_cpu_map__type)) {
3508 		PyErr_SetString(PyExc_TypeError, "cpus must be a perf.cpu_map or None");
3509 		evlist__put(evlist);
3510 		return NULL;
3511 	}
3512 
3513 	threads = (pthreads && pthreads != Py_None) ?
3514 			((struct pyrf_thread_map *)pthreads)->threads : NULL;
3515 	cpus = (pcpus && pcpus != Py_None) ?
3516 			((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
3517 
3518 	perf_evlist__set_maps(evlist__core(evlist), cpus, threads);
3519 	ret = metricgroup__parse_groups(evlist, pmu ?: "all",
3520 					/*cputype_filter=*/false, input,
3521 					/*metric_no_group=*/ false,
3522 					/*metric_no_merge=*/ false,
3523 					/*metric_no_threshold=*/ true,
3524 					/*user_requested_cpu_list=*/ NULL,
3525 					/*system_wide=*/true,
3526 					/*hardware_aware_grouping=*/ false);
3527 	if (ret) {
3528 		evlist__put(evlist);
3529 		errno = -ret;
3530 		PyErr_SetFromErrno(PyExc_OSError);
3531 		return NULL;
3532 	}
3533 	result = pyrf_evlist__from_evlist(evlist);
3534 	evlist__put(evlist);
3535 	return result;
3536 }
3537 
3538 static PyObject *pyrf__metrics_groups(const struct pmu_metric *pm)
3539 {
3540 	PyObject *groups = PyList_New(/*len=*/0);
3541 	const char *mg = pm->metric_group;
3542 
3543 	if (!groups)
3544 		return NULL;
3545 
3546 	while (mg) {
3547 		PyObject *val = NULL;
3548 		const char *sep = strchr(mg, ';');
3549 		size_t len = sep ? (size_t)(sep - mg) : strlen(mg);
3550 
3551 		if (len > 0) {
3552 			val = PyUnicode_FromStringAndSize(mg, len);
3553 			if (val)
3554 				PyList_Append(groups, val);
3555 
3556 			Py_XDECREF(val);
3557 		}
3558 		mg = sep ? sep + 1 : NULL;
3559 	}
3560 	return groups;
3561 }
3562 
3563 static int pyrf__metrics_cb(const struct pmu_metric *pm,
3564 			    const struct pmu_metrics_table *table __maybe_unused,
3565 			    void *vdata)
3566 {
3567 	PyObject *py_list = vdata;
3568 	PyObject *dict = PyDict_New();
3569 	PyObject *key = dict ? PyUnicode_FromString("MetricGroup") : NULL;
3570 	PyObject *value = key ? pyrf__metrics_groups(pm) : NULL;
3571 
3572 	if (!value || PyDict_SetItem(dict, key, value) != 0) {
3573 		Py_XDECREF(key);
3574 		Py_XDECREF(value);
3575 		Py_XDECREF(dict);
3576 		return -ENOMEM;
3577 	}
3578 	Py_DECREF(key);
3579 	Py_DECREF(value);
3580 
3581 	if (!add_to_dict(dict, "MetricName", pm->metric_name) ||
3582 	    !add_to_dict(dict, "PMU", pm->pmu) ||
3583 	    !add_to_dict(dict, "MetricExpr", pm->metric_expr) ||
3584 	    !add_to_dict(dict, "MetricThreshold", pm->metric_threshold) ||
3585 	    !add_to_dict(dict, "ScaleUnit", pm->unit) ||
3586 	    !add_to_dict(dict, "Compat", pm->compat) ||
3587 	    !add_to_dict(dict, "BriefDescription", pm->desc) ||
3588 	    !add_to_dict(dict, "PublicDescription", pm->long_desc) ||
3589 	    PyList_Append(py_list, dict) != 0) {
3590 		Py_DECREF(dict);
3591 		return -ENOMEM;
3592 	}
3593 	Py_DECREF(dict);
3594 	return 0;
3595 }
3596 
3597 static PyObject *pyrf__metrics(PyObject *self, PyObject *args)
3598 {
3599 	const struct pmu_metrics_table *table = pmu_metrics_table__find();
3600 	PyObject *list = PyList_New(/*len=*/0);
3601 	int ret;
3602 
3603 	if (!list)
3604 		return NULL;
3605 
3606 	ret = pmu_metrics_table__for_each_metric(table, pyrf__metrics_cb, list);
3607 	if (!ret)
3608 		ret = pmu_for_each_sys_metric(pyrf__metrics_cb, list);
3609 
3610 	if (ret) {
3611 		Py_DECREF(list);
3612 		errno = -ret;
3613 		PyErr_SetFromErrno(PyExc_OSError);
3614 		return NULL;
3615 	}
3616 	return list;
3617 }
3618 
3619 struct pyrf_data {
3620 	PyObject_HEAD
3621 
3622 	struct perf_data data;
3623 };
3624 
3625 static int pyrf_data__init(struct pyrf_data *pdata, PyObject *args, PyObject *kwargs)
3626 {
3627 	static char *kwlist[] = { "path", "fd", NULL };
3628 	char *path = NULL;
3629 	int fd = -1;
3630 
3631 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|si", kwlist, &path, &fd))
3632 		return -1;
3633 
3634 	if (pdata->data.open)
3635 		perf_data__close(&pdata->data);
3636 	free((char *)pdata->data.path);
3637 	memset(&pdata->data, 0, sizeof(pdata->data));
3638 
3639 	if (fd != -1) {
3640 		struct stat st;
3641 
3642 		if (fstat(fd, &st) < 0 || !S_ISFIFO(st.st_mode)) {
3643 			PyErr_SetString(PyExc_ValueError,
3644 					"fd argument is only supported for pipes");
3645 			return -1;
3646 		}
3647 		if (!path)
3648 			path = "-";
3649 		else if (strcmp(path, "-") != 0) {
3650 			PyErr_SetString(PyExc_ValueError,
3651 					"path must be '-' when fd is provided");
3652 			return -1;
3653 		}
3654 		fd = dup(fd);
3655 		if (fd < 0) {
3656 			PyErr_SetFromErrno(PyExc_OSError);
3657 			return -1;
3658 		}
3659 	} else if (path && strcmp(path, "-") == 0) {
3660 		fd = dup(0);
3661 		if (fd < 0) {
3662 			PyErr_SetFromErrno(PyExc_OSError);
3663 			return -1;
3664 		}
3665 	}
3666 
3667 	if (!path)
3668 		path = "perf.data";
3669 
3670 	pdata->data.path = strdup(path);
3671 	if (!pdata->data.path) {
3672 		if (fd != -1)
3673 			close(fd);
3674 		PyErr_NoMemory();
3675 		return -1;
3676 	}
3677 
3678 	pdata->data.mode = PERF_DATA_MODE_READ;
3679 	pdata->data.file.fd = fd;
3680 	if (perf_data__open(&pdata->data) < 0) {
3681 		PyErr_Format(PyExc_IOError, "Failed to open perf data: %s",
3682 			     pdata->data.path ? pdata->data.path : "perf.data");
3683 		return -1;
3684 	}
3685 	return 0;
3686 }
3687 
3688 static void pyrf_data__delete(struct pyrf_data *pdata)
3689 {
3690 	perf_data__close(&pdata->data);
3691 	free((char *)pdata->data.path);
3692 	Py_TYPE(pdata)->tp_free((PyObject *)pdata);
3693 }
3694 
3695 static PyObject *pyrf_data__str(PyObject *self)
3696 {
3697 	const struct pyrf_data *pdata = (const struct pyrf_data *)self;
3698 
3699 	if (!pdata->data.path)
3700 		return PyUnicode_FromString("[uninitialized]");
3701 	return PyUnicode_FromString(pdata->data.path);
3702 }
3703 
3704 static PyObject *pyrf_data__new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3705 {
3706 	struct pyrf_data *pdata;
3707 
3708 	pdata = (struct pyrf_data *)PyType_GenericNew(type, args, kwargs);
3709 	if (pdata)
3710 		memset(&pdata->data, 0, sizeof(pdata->data));
3711 	return (PyObject *)pdata;
3712 }
3713 
3714 static const char pyrf_data__doc[] = PyDoc_STR("perf data file object.");
3715 
3716 static PyTypeObject pyrf_data__type = {
3717 	PyVarObject_HEAD_INIT(NULL, 0)
3718 	.tp_name	= "perf.data",
3719 	.tp_basicsize	= sizeof(struct pyrf_data),
3720 	.tp_dealloc	= (destructor)pyrf_data__delete,
3721 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
3722 	.tp_doc		= pyrf_data__doc,
3723 	.tp_init	= (initproc)pyrf_data__init,
3724 	.tp_repr	= pyrf_data__str,
3725 	.tp_str		= pyrf_data__str,
3726 };
3727 
3728 static int pyrf_data__setup_types(void)
3729 {
3730 	pyrf_data__type.tp_new = pyrf_data__new;
3731 	return PyType_Ready(&pyrf_data__type);
3732 }
3733 
3734 struct pyrf_thread {
3735 	PyObject_HEAD
3736 
3737 	struct thread *thread;
3738 };
3739 
3740 static void pyrf_thread__delete(struct pyrf_thread *pthread)
3741 {
3742 	thread__put(pthread->thread);
3743 	Py_TYPE(pthread)->tp_free((PyObject *)pthread);
3744 }
3745 
3746 static PyObject *pyrf_thread__comm(PyObject *obj)
3747 {
3748 	struct pyrf_thread *pthread = (void *)obj;
3749 	const char *str;
3750 
3751 	CHECK_INITIALIZED(pthread->thread, "perf.thread");
3752 
3753 	str = thread__comm_str(pthread->thread);
3754 
3755 	if (!str)
3756 		Py_RETURN_NONE;
3757 
3758 	return PyUnicode_FromString(str);
3759 }
3760 
3761 static PyMethodDef pyrf_thread__methods[] = {
3762 	{
3763 		.ml_name  = "comm",
3764 		.ml_meth  = (PyCFunction)pyrf_thread__comm,
3765 		.ml_flags = METH_NOARGS,
3766 		.ml_doc	  = PyDoc_STR("Comm(and) associated with this thread.")
3767 	},
3768 	{ .ml_name = NULL, }
3769 };
3770 
3771 static PyObject *pyrf_thread__get_pid(struct pyrf_thread *pthread, void *closure __maybe_unused)
3772 {
3773 	CHECK_INITIALIZED(pthread->thread, "thread");
3774 	return PyLong_FromLong(thread__pid(pthread->thread));
3775 }
3776 
3777 static PyObject *pyrf_thread__get_tid(struct pyrf_thread *pthread, void *closure __maybe_unused)
3778 {
3779 	CHECK_INITIALIZED(pthread->thread, "thread");
3780 	return PyLong_FromLong(thread__tid(pthread->thread));
3781 }
3782 
3783 static PyObject *pyrf_thread__get_ppid(struct pyrf_thread *pthread, void *closure __maybe_unused)
3784 {
3785 	CHECK_INITIALIZED(pthread->thread, "thread");
3786 	return PyLong_FromLong(thread__ppid(pthread->thread));
3787 }
3788 
3789 static PyObject *pyrf_thread__get_cpu(struct pyrf_thread *pthread, void *closure __maybe_unused)
3790 {
3791 	CHECK_INITIALIZED(pthread->thread, "thread");
3792 	return PyLong_FromLong(thread__cpu(pthread->thread));
3793 }
3794 
3795 static PyGetSetDef pyrf_thread__getset[] = {
3796 	{ .name = "pid", .get = (getter)pyrf_thread__get_pid, .doc = "process ID" },
3797 	{ .name = "tid", .get = (getter)pyrf_thread__get_tid, .doc = "thread ID" },
3798 	{ .name = "ppid", .get = (getter)pyrf_thread__get_ppid, .doc = "parent process ID" },
3799 	{ .name = "cpu", .get = (getter)pyrf_thread__get_cpu, .doc = "cpu number" },
3800 	{ .name = NULL }
3801 };
3802 
3803 static const char pyrf_thread__doc[] = PyDoc_STR("perf thread object.");
3804 
3805 static PyTypeObject pyrf_thread__type = {
3806 	PyVarObject_HEAD_INIT(NULL, 0)
3807 	.tp_name	= "perf.thread",
3808 	.tp_basicsize	= sizeof(struct pyrf_thread),
3809 	.tp_dealloc	= (destructor)pyrf_thread__delete,
3810 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
3811 	.tp_methods	= pyrf_thread__methods,
3812 	.tp_getset	= pyrf_thread__getset,
3813 	.tp_doc		= pyrf_thread__doc,
3814 };
3815 
3816 static int pyrf_thread__setup_types(void)
3817 {
3818 	return PyType_Ready(&pyrf_thread__type);
3819 }
3820 
3821 static PyObject *pyrf_thread__from_thread(struct thread *thread)
3822 {
3823 	struct pyrf_thread *pthread = PyObject_New(struct pyrf_thread, &pyrf_thread__type);
3824 
3825 	if (!pthread)
3826 		return NULL;
3827 
3828 	pthread->thread = thread__get(thread);
3829 	return (PyObject *)pthread;
3830 }
3831 
3832 struct pyrf_session {
3833 	PyObject_HEAD
3834 
3835 	struct perf_session *session;
3836 	struct perf_tool tool;
3837 	struct pyrf_data *pdata;
3838 	PyObject *sample;
3839 	PyObject *stat;
3840 };
3841 
3842 static int pyrf_session_tool__sample(const struct perf_tool *tool,
3843 				     union perf_event *event,
3844 				     struct perf_sample *sample,
3845 				     struct machine *machine)
3846 {
3847 	struct pyrf_session *psession = container_of(tool, struct pyrf_session, tool);
3848 	PyObject *pyevent = pyrf_event__new(event, sample->evsel, psession->session, machine);
3849 	PyObject *ret;
3850 
3851 	if (pyevent == NULL)
3852 		return -ENOMEM;
3853 
3854 	ret = PyObject_CallFunction(psession->sample, "O", pyevent);
3855 	if (!ret) {
3856 		Py_DECREF(pyevent);
3857 		return -1;
3858 	}
3859 	Py_DECREF(ret);
3860 	Py_DECREF(pyevent);
3861 	return 0;
3862 }
3863 
3864 static int pyrf_session_tool__stat(const struct perf_tool *tool,
3865 				   struct perf_session *session,
3866 				   union perf_event *event)
3867 {
3868 	struct pyrf_session *psession = container_of(tool, struct pyrf_session, tool);
3869 	struct evsel *evsel = evlist__id2evsel(session->evlist, event->stat.id);
3870 	PyObject *pyevent = pyrf_event__new(event, /*evsel=*/NULL, psession->session,
3871 					    /*machine=*/NULL);
3872 	const char *name = evsel ? evsel__name(evsel) : "unknown";
3873 	PyObject *ret;
3874 
3875 	if (pyevent == NULL)
3876 		return -ENOMEM;
3877 
3878 	ret = PyObject_CallFunction(psession->stat, "Oz", pyevent, name);
3879 	if (!ret) {
3880 		Py_DECREF(pyevent);
3881 		return -1;
3882 	}
3883 	Py_DECREF(ret);
3884 	Py_DECREF(pyevent);
3885 	return 0;
3886 }
3887 
3888 static int pyrf_session_tool__stat_round(const struct perf_tool *tool,
3889 					 struct perf_session *session __maybe_unused,
3890 					 union perf_event *event)
3891 {
3892 	struct pyrf_session *psession = container_of(tool, struct pyrf_session, tool);
3893 	PyObject *pyevent = pyrf_event__new(event, /*evsel=*/NULL, psession->session,
3894 					    /*machine=*/NULL);
3895 	PyObject *ret;
3896 
3897 	if (pyevent == NULL)
3898 		return -ENOMEM;
3899 
3900 	ret = PyObject_CallFunction(psession->stat, "Oz", pyevent, NULL);
3901 	if (!ret) {
3902 		Py_DECREF(pyevent);
3903 		return -1;
3904 	}
3905 	Py_DECREF(ret);
3906 	Py_DECREF(pyevent);
3907 	return 0;
3908 }
3909 
3910 static PyObject *pyrf_session__find_thread(struct pyrf_session *psession, PyObject *args)
3911 {
3912 	struct machine *machine;
3913 	struct thread *thread = NULL;
3914 	PyObject *result;
3915 	int pid;
3916 
3917 	CHECK_INITIALIZED(psession->session, "session");
3918 
3919 	if (!PyArg_ParseTuple(args, "i", &pid))
3920 		return NULL;
3921 
3922 	machine = &psession->session->machines.host;
3923 	thread = machine__find_thread(machine, pid, pid);
3924 
3925 	if (!thread) {
3926 		machine = perf_session__find_machine(psession->session, pid);
3927 		if (machine)
3928 			thread = machine__find_thread(machine, pid, pid);
3929 	}
3930 
3931 	if (!thread) {
3932 		PyErr_Format(PyExc_TypeError, "Failed to find thread %d", pid);
3933 		return NULL;
3934 	}
3935 	result = pyrf_thread__from_thread(thread);
3936 	thread__put(thread);
3937 	return result;
3938 }
3939 
3940 static PyObject *pyrf_session__new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
3941 {
3942 	struct pyrf_data *pdata;
3943 	PyObject *sample = NULL, *stat = NULL;
3944 	static char *kwlist[] = { "data", "sample", "stat", NULL };
3945 	struct pyrf_session *psession;
3946 	struct perf_session *session;
3947 
3948 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!|OO", kwlist, &pyrf_data__type, &pdata,
3949 					 &sample, &stat))
3950 		return NULL;
3951 
3952 	psession = PyObject_New(struct pyrf_session, type);
3953 	if (!psession)
3954 		return NULL;
3955 
3956 	psession->session = NULL;
3957 	psession->sample = NULL;
3958 	psession->stat = NULL;
3959 	psession->pdata = NULL;
3960 
3961 	Py_INCREF(pdata);
3962 	psession->pdata = pdata;
3963 
3964 	perf_tool__init(&psession->tool, /*ordered_events=*/true);
3965 	psession->tool.ordering_requires_timestamps = true;
3966 
3967 	#define ADD_TOOL(name)						\
3968 	do {								\
3969 		if (name) {						\
3970 			if (!PyCallable_Check(name)) {			\
3971 				PyErr_SetString(PyExc_TypeError, #name " must be callable"); \
3972 				goto err_out;				\
3973 			}						\
3974 			psession->tool.name = pyrf_session_tool__##name; \
3975 			Py_INCREF(name);				\
3976 			psession->name = name;				\
3977 		}							\
3978 	} while (0)
3979 
3980 	ADD_TOOL(sample);
3981 	ADD_TOOL(stat);
3982 	#undef ADD_TOOL
3983 
3984 	if (stat)
3985 		psession->tool.stat_round = pyrf_session_tool__stat_round;
3986 
3987 
3988 	psession->tool.comm		= perf_event__process_comm;
3989 	psession->tool.mmap		= perf_event__process_mmap;
3990 	psession->tool.mmap2            = perf_event__process_mmap2;
3991 	psession->tool.namespaces       = perf_event__process_namespaces;
3992 	psession->tool.cgroup           = perf_event__process_cgroup;
3993 	psession->tool.exit             = perf_event__process_exit;
3994 	psession->tool.fork             = perf_event__process_fork;
3995 	psession->tool.ksymbol          = perf_event__process_ksymbol;
3996 	psession->tool.text_poke        = perf_event__process_text_poke;
3997 	psession->tool.build_id         = perf_event__process_build_id;
3998 	psession->tool.attr		= perf_event__process_attr;
3999 	psession->tool.feature		= perf_event__process_feature;
4000 
4001 	session = perf_session__new(&pdata->data, &psession->tool);
4002 	if (IS_ERR(session)) {
4003 		PyErr_Format(PyExc_IOError, "failed to create session: %ld", PTR_ERR(session));
4004 		goto err_out;
4005 	}
4006 	psession->session = session;
4007 
4008 	symbol_conf.use_callchain = true;
4009 	symbol_conf.show_kernel_path = true;
4010 	symbol_conf.inline_name = false;
4011 	if (symbol__init(perf_session__env(session)) < 0) {
4012 		PyErr_SetString(PyExc_OSError, "perf: symbol__init failed");
4013 		goto err_out;
4014 	}
4015 
4016 
4017 
4018 	return (PyObject *)psession;
4019 err_out:
4020 	Py_DECREF(psession);
4021 	return NULL;
4022 }
4023 
4024 static void pyrf_session__delete(struct pyrf_session *psession)
4025 {
4026 	perf_session__delete(psession->session);
4027 	Py_XDECREF(psession->pdata);
4028 	Py_XDECREF(psession->sample);
4029 	Py_XDECREF(psession->stat);
4030 	Py_TYPE(psession)->tp_free((PyObject *)psession);
4031 }
4032 
4033 static PyObject *pyrf_session__find_thread_events(struct pyrf_session *psession)
4034 {
4035 	int err;
4036 
4037 	CHECK_INITIALIZED(psession->session, "session");
4038 
4039 	err = perf_session__process_events(psession->session);
4040 
4041 	if (PyErr_Occurred())
4042 		return NULL;
4043 
4044 	if (err < 0) {
4045 		PyErr_Format(PyExc_OSError, "Process events failed: %d", err);
4046 		return NULL;
4047 	}
4048 
4049 	Py_RETURN_NONE;
4050 }
4051 
4052 static PyMethodDef pyrf_session__methods[] = {
4053 	{
4054 		.ml_name  = "process_events",
4055 		.ml_meth  = (PyCFunction)pyrf_session__find_thread_events,
4056 		.ml_flags = METH_NOARGS,
4057 		.ml_doc	  = PyDoc_STR("Iterate and process events.")
4058 	},
4059 	{
4060 		.ml_name  = "find_thread",
4061 		.ml_meth  = (PyCFunction)pyrf_session__find_thread,
4062 		.ml_flags = METH_VARARGS,
4063 		.ml_doc	  = PyDoc_STR("Returns the thread associated with a pid.")
4064 	},
4065 	{ .ml_name = NULL, }
4066 };
4067 
4068 static const char pyrf_session__doc[] = PyDoc_STR("perf session object.");
4069 
4070 static PyObject *pyrf_session__getattro(struct pyrf_session *psession, PyObject *attr_name)
4071 {
4072 	if (!psession->session) {
4073 		PyErr_SetString(PyExc_ValueError, "session not initialized");
4074 		return NULL;
4075 	}
4076 	return PyObject_GenericGetAttr((PyObject *) psession, attr_name);
4077 }
4078 
4079 static int pyrf_session__setattro(struct pyrf_session *psession, PyObject *attr_name,
4080 				  PyObject *value)
4081 {
4082 	if (!psession->session) {
4083 		PyErr_SetString(PyExc_ValueError, "session not initialized");
4084 		return -1;
4085 	}
4086 	return PyObject_GenericSetAttr((PyObject *) psession, attr_name, value);
4087 }
4088 
4089 static PyTypeObject pyrf_session__type = {
4090 	PyVarObject_HEAD_INIT(NULL, 0)
4091 	.tp_name	= "perf.session",
4092 	.tp_basicsize	= sizeof(struct pyrf_session),
4093 	.tp_dealloc	= (destructor)pyrf_session__delete,
4094 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
4095 	.tp_methods	= pyrf_session__methods,
4096 	.tp_doc		= pyrf_session__doc,
4097 	.tp_new		= pyrf_session__new,
4098 	.tp_getattro	= (getattrofunc) pyrf_session__getattro,
4099 	.tp_setattro	= (setattrofunc) pyrf_session__setattro,
4100 };
4101 
4102 static int pyrf_session__setup_types(void)
4103 {
4104 	return PyType_Ready(&pyrf_session__type);
4105 }
4106 
4107 static PyObject *pyrf__syscall_name(PyObject *self, PyObject *args, PyObject *kwargs)
4108 {
4109 	const char *name;
4110 	int id;
4111 	int elf_machine = EM_HOST;
4112 	static char *kwlist[] = { "id", "elf_machine", NULL };
4113 
4114 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|$i", kwlist, &id, &elf_machine))
4115 		return NULL;
4116 
4117 	name = syscalltbl__name(elf_machine, id);
4118 	if (!name)
4119 		Py_RETURN_NONE;
4120 	return PyUnicode_FromString(name);
4121 }
4122 
4123 static PyObject *pyrf__syscall_id(PyObject *self, PyObject *args, PyObject *kwargs)
4124 {
4125 	const char *name;
4126 	int id;
4127 	int elf_machine = EM_HOST;
4128 	static char *kwlist[] = { "name", "elf_machine", NULL };
4129 
4130 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|$i", kwlist, &name, &elf_machine))
4131 		return NULL;
4132 
4133 	id = syscalltbl__id(elf_machine, name);
4134 	if (id < 0) {
4135 		PyErr_Format(PyExc_ValueError, "Failed to find syscall %s", name);
4136 		return NULL;
4137 	}
4138 	return PyLong_FromLong(id);
4139 }
4140 
4141 static PyObject *pyrf__config_get(PyObject *self, PyObject *args)
4142 {
4143 	const char *config_name, *val;
4144 
4145 	if (!PyArg_ParseTuple(args, "s", &config_name))
4146 		return NULL;
4147 
4148 	val = perf_config_get(config_name);
4149 	if (!val)
4150 		Py_RETURN_NONE;
4151 	return PyUnicode_FromString(val);
4152 }
4153 
4154 static PyMethodDef perf__methods[] = {
4155 	{
4156 		.ml_name  = "config_get",
4157 		.ml_meth  = (PyCFunction) pyrf__config_get,
4158 		.ml_flags = METH_VARARGS,
4159 		.ml_doc	  = PyDoc_STR("Get a perf config value.")
4160 	},
4161 	{
4162 		.ml_name  = "metrics",
4163 		.ml_meth  = (PyCFunction) pyrf__metrics,
4164 		.ml_flags = METH_NOARGS,
4165 		.ml_doc	  = PyDoc_STR(
4166 			"Returns a list of metrics represented as string values in dictionaries.")
4167 	},
4168 	{
4169 		.ml_name  = "tracepoint",
4170 		.ml_meth  = (PyCFunction) pyrf__tracepoint,
4171 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
4172 		.ml_doc	  = PyDoc_STR("Get tracepoint config.")
4173 	},
4174 	{
4175 		.ml_name  = "parse_events",
4176 		.ml_meth  = (PyCFunction) pyrf__parse_events,
4177 		.ml_flags = METH_VARARGS,
4178 		.ml_doc	  = PyDoc_STR("Parse a string of events and return an evlist.")
4179 	},
4180 	{
4181 		.ml_name  = "parse_metrics",
4182 		.ml_meth  = (PyCFunction) pyrf__parse_metrics,
4183 		.ml_flags = METH_VARARGS,
4184 		.ml_doc	  = PyDoc_STR(
4185 			"Parse a string of metrics or metric groups and return an evlist.")
4186 	},
4187 	{
4188 		.ml_name  = "pmus",
4189 		.ml_meth  = (PyCFunction) pyrf__pmus,
4190 		.ml_flags = METH_NOARGS,
4191 		.ml_doc	  = PyDoc_STR("Returns a sequence of pmus.")
4192 	},
4193 	{
4194 		.ml_name  = "syscall_name",
4195 		.ml_meth  = (PyCFunction) pyrf__syscall_name,
4196 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
4197 		.ml_doc	  = PyDoc_STR("Turns a syscall number to a string.")
4198 	},
4199 	{
4200 		.ml_name  = "syscall_id",
4201 		.ml_meth  = (PyCFunction) pyrf__syscall_id,
4202 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
4203 		.ml_doc	  = PyDoc_STR("Turns a syscall name to a number.")
4204 	},
4205 	{ .ml_name = NULL, }
4206 };
4207 
4208 PyMODINIT_FUNC PyInit_perf(void)
4209 {
4210 	PyObject *obj;
4211 	int i;
4212 	PyObject *dict;
4213 	static struct PyModuleDef moduledef = {
4214 		PyModuleDef_HEAD_INIT,
4215 		"perf",			/* m_name */
4216 		"",			/* m_doc */
4217 		-1,			/* m_size */
4218 		perf__methods,		/* m_methods */
4219 		NULL,			/* m_reload */
4220 		NULL,			/* m_traverse */
4221 		NULL,			/* m_clear */
4222 		NULL,			/* m_free */
4223 	};
4224 	PyObject *module = PyModule_Create(&moduledef);
4225 
4226 	if (module == NULL)
4227 		return NULL;
4228 
4229 	if (pyrf_event__setup_types() < 0 ||
4230 	    pyrf_evlist__setup_types() < 0 ||
4231 	    pyrf_evsel__setup_types() < 0 ||
4232 	    pyrf_thread_map__setup_types() < 0 ||
4233 	    pyrf_cpu_map__setup_types() < 0 ||
4234 	    pyrf_pmu_iterator__setup_types() < 0 ||
4235 	    pyrf_pmu__setup_types() < 0 ||
4236 	    pyrf_counts_values__setup_types() < 0 ||
4237 	    pyrf_data__setup_types() < 0 ||
4238 	    pyrf_session__setup_types() < 0 ||
4239 	    pyrf_thread__setup_types() < 0) {
4240 		Py_DECREF(module);
4241 		return NULL;
4242 	}
4243 
4244 	/* The page_size is placed in util object. */
4245 	page_size = sysconf(_SC_PAGE_SIZE);
4246 
4247 	Py_INCREF(&pyrf_evlist__type);
4248 	PyModule_AddObject(module, "evlist", (PyObject *)&pyrf_evlist__type);
4249 
4250 	Py_INCREF(&pyrf_evsel__type);
4251 	PyModule_AddObject(module, "evsel", (PyObject *)&pyrf_evsel__type);
4252 
4253 	Py_INCREF(&pyrf_thread__type);
4254 	PyModule_AddObject(module, "thread", (PyObject *)&pyrf_thread__type);
4255 
4256 	Py_INCREF(&pyrf_callchain__type);
4257 	PyModule_AddObject(module, "callchain", (PyObject *)&pyrf_callchain__type);
4258 
4259 	Py_INCREF(&pyrf_callchain_node__type);
4260 	PyModule_AddObject(module, "callchain_node", (PyObject *)&pyrf_callchain_node__type);
4261 
4262 	Py_INCREF(&pyrf_mmap_event__type);
4263 	PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
4264 
4265 	Py_INCREF(&pyrf_mmap2_event__type);
4266 	PyModule_AddObject(module, "mmap2_event", (PyObject *)&pyrf_mmap2_event__type);
4267 
4268 	Py_INCREF(&pyrf_lost_event__type);
4269 	PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
4270 
4271 	Py_INCREF(&pyrf_comm_event__type);
4272 	PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
4273 
4274 	Py_INCREF(&pyrf_task_event__type);
4275 	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
4276 
4277 	Py_INCREF(&pyrf_throttle_event__type);
4278 	PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
4279 
4280 	Py_INCREF(&pyrf_task_event__type);
4281 	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
4282 
4283 	Py_INCREF(&pyrf_read_event__type);
4284 	PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
4285 
4286 	Py_INCREF(&pyrf_sample_event__type);
4287 	PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
4288 
4289 	Py_INCREF(&pyrf_context_switch_event__type);
4290 	PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
4291 
4292 	Py_INCREF(&pyrf_stat_event__type);
4293 	PyModule_AddObject(module, "stat_event", (PyObject *)&pyrf_stat_event__type);
4294 
4295 	Py_INCREF(&pyrf_stat_round_event__type);
4296 	PyModule_AddObject(module, "stat_round_event", (PyObject *)&pyrf_stat_round_event__type);
4297 
4298 	Py_INCREF(&pyrf_thread_map__type);
4299 	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
4300 
4301 	Py_INCREF(&pyrf_cpu_map__type);
4302 	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
4303 
4304 	Py_INCREF(&pyrf_counts_values__type);
4305 	PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);
4306 
4307 	Py_INCREF(&pyrf_data__type);
4308 	PyModule_AddObject(module, "data", (PyObject *)&pyrf_data__type);
4309 
4310 	Py_INCREF(&pyrf_session__type);
4311 	PyModule_AddObject(module, "session", (PyObject *)&pyrf_session__type);
4312 
4313 	Py_INCREF(&pyrf_branch_entry__type);
4314 	if (PyModule_AddObject(module, "branch_entry", (PyObject *)&pyrf_branch_entry__type) < 0) {
4315 		Py_DECREF(&pyrf_branch_entry__type);
4316 		goto error;
4317 	}
4318 
4319 	Py_INCREF(&pyrf_branch_stack__type);
4320 	if (PyModule_AddObject(module, "branch_stack", (PyObject *)&pyrf_branch_stack__type) < 0) {
4321 		Py_DECREF(&pyrf_branch_stack__type);
4322 		goto error;
4323 	}
4324 
4325 	dict = PyModule_GetDict(module);
4326 	if (dict == NULL)
4327 		goto error;
4328 
4329 	for (i = 0; perf__constants[i].name != NULL; i++) {
4330 		obj = PyLong_FromLong(perf__constants[i].value);
4331 		if (obj == NULL)
4332 			goto error;
4333 		PyDict_SetItemString(dict, perf__constants[i].name, obj);
4334 		Py_DECREF(obj);
4335 	}
4336 
4337 error:
4338 	if (PyErr_Occurred()) {
4339 		Py_XDECREF(module);
4340 		return NULL;
4341 	}
4342 	return module;
4343 }
4344