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