xref: /linux/tools/perf/util/python.c (revision 5758960353d179f0541226764a1e47eff01666ff)
1 #include <Python.h>
2 #include <structmember.h>
3 #include <inttypes.h>
4 #include <poll.h>
5 #include "evlist.h"
6 #include "evsel.h"
7 #include "event.h"
8 #include "cpumap.h"
9 #include "thread_map.h"
10 
11 /* Define PyVarObject_HEAD_INIT for python 2.5 */
12 #ifndef PyVarObject_HEAD_INIT
13 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
14 #endif
15 
16 struct throttle_event {
17 	struct perf_event_header header;
18 	u64			 time;
19 	u64			 id;
20 	u64			 stream_id;
21 };
22 
23 PyMODINIT_FUNC initperf(void);
24 
25 #define member_def(type, member, ptype, help) \
26 	{ #member, ptype, \
27 	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
28 	  0, help }
29 
30 #define sample_member_def(name, member, ptype, help) \
31 	{ #name, ptype, \
32 	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
33 	  0, help }
34 
35 struct pyrf_event {
36 	PyObject_HEAD
37 	struct perf_sample sample;
38 	union perf_event   event;
39 };
40 
41 #define sample_members \
42 	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
43 	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
44 	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
45 	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
46 	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
47 	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
48 	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
49 	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
50 	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
51 
52 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
53 
54 static PyMemberDef pyrf_mmap_event__members[] = {
55 	sample_members
56 	member_def(perf_event_header, type, T_UINT, "event type"),
57 	member_def(mmap_event, pid, T_UINT, "event pid"),
58 	member_def(mmap_event, tid, T_UINT, "event tid"),
59 	member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
60 	member_def(mmap_event, len, T_ULONGLONG, "map length"),
61 	member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
62 	member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
63 	{ .name = NULL, },
64 };
65 
66 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
67 {
68 	PyObject *ret;
69 	char *s;
70 
71 	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
72 			 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
73 			 "filename: %s }",
74 		     pevent->event.mmap.pid, pevent->event.mmap.tid,
75 		     pevent->event.mmap.start, pevent->event.mmap.len,
76 		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
77 		ret = PyErr_NoMemory();
78 	} else {
79 		ret = PyString_FromString(s);
80 		free(s);
81 	}
82 	return ret;
83 }
84 
85 static PyTypeObject pyrf_mmap_event__type = {
86 	PyVarObject_HEAD_INIT(NULL, 0)
87 	.tp_name	= "perf.mmap_event",
88 	.tp_basicsize	= sizeof(struct pyrf_event),
89 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
90 	.tp_doc		= pyrf_mmap_event__doc,
91 	.tp_members	= pyrf_mmap_event__members,
92 	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
93 };
94 
95 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
96 
97 static PyMemberDef pyrf_task_event__members[] = {
98 	sample_members
99 	member_def(perf_event_header, type, T_UINT, "event type"),
100 	member_def(fork_event, pid, T_UINT, "event pid"),
101 	member_def(fork_event, ppid, T_UINT, "event ppid"),
102 	member_def(fork_event, tid, T_UINT, "event tid"),
103 	member_def(fork_event, ptid, T_UINT, "event ptid"),
104 	member_def(fork_event, time, T_ULONGLONG, "timestamp"),
105 	{ .name = NULL, },
106 };
107 
108 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
109 {
110 	return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
111 				   "ptid: %u, time: %" PRIu64 "}",
112 				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
113 				   pevent->event.fork.pid,
114 				   pevent->event.fork.ppid,
115 				   pevent->event.fork.tid,
116 				   pevent->event.fork.ptid,
117 				   pevent->event.fork.time);
118 }
119 
120 static PyTypeObject pyrf_task_event__type = {
121 	PyVarObject_HEAD_INIT(NULL, 0)
122 	.tp_name	= "perf.task_event",
123 	.tp_basicsize	= sizeof(struct pyrf_event),
124 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
125 	.tp_doc		= pyrf_task_event__doc,
126 	.tp_members	= pyrf_task_event__members,
127 	.tp_repr	= (reprfunc)pyrf_task_event__repr,
128 };
129 
130 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
131 
132 static PyMemberDef pyrf_comm_event__members[] = {
133 	sample_members
134 	member_def(perf_event_header, type, T_UINT, "event type"),
135 	member_def(comm_event, pid, T_UINT, "event pid"),
136 	member_def(comm_event, tid, T_UINT, "event tid"),
137 	member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
138 	{ .name = NULL, },
139 };
140 
141 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
142 {
143 	return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
144 				   pevent->event.comm.pid,
145 				   pevent->event.comm.tid,
146 				   pevent->event.comm.comm);
147 }
148 
149 static PyTypeObject pyrf_comm_event__type = {
150 	PyVarObject_HEAD_INIT(NULL, 0)
151 	.tp_name	= "perf.comm_event",
152 	.tp_basicsize	= sizeof(struct pyrf_event),
153 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
154 	.tp_doc		= pyrf_comm_event__doc,
155 	.tp_members	= pyrf_comm_event__members,
156 	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
157 };
158 
159 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
160 
161 static PyMemberDef pyrf_throttle_event__members[] = {
162 	sample_members
163 	member_def(perf_event_header, type, T_UINT, "event type"),
164 	member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
165 	member_def(throttle_event, id, T_ULONGLONG, "event id"),
166 	member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
167 	{ .name = NULL, },
168 };
169 
170 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
171 {
172 	struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
173 
174 	return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
175 				   ", stream_id: %" PRIu64 " }",
176 				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
177 				   te->time, te->id, te->stream_id);
178 }
179 
180 static PyTypeObject pyrf_throttle_event__type = {
181 	PyVarObject_HEAD_INIT(NULL, 0)
182 	.tp_name	= "perf.throttle_event",
183 	.tp_basicsize	= sizeof(struct pyrf_event),
184 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
185 	.tp_doc		= pyrf_throttle_event__doc,
186 	.tp_members	= pyrf_throttle_event__members,
187 	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
188 };
189 
190 static int pyrf_event__setup_types(void)
191 {
192 	int err;
193 	pyrf_mmap_event__type.tp_new =
194 	pyrf_task_event__type.tp_new =
195 	pyrf_comm_event__type.tp_new =
196 	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
197 	err = PyType_Ready(&pyrf_mmap_event__type);
198 	if (err < 0)
199 		goto out;
200 	err = PyType_Ready(&pyrf_task_event__type);
201 	if (err < 0)
202 		goto out;
203 	err = PyType_Ready(&pyrf_comm_event__type);
204 	if (err < 0)
205 		goto out;
206 	err = PyType_Ready(&pyrf_throttle_event__type);
207 	if (err < 0)
208 		goto out;
209 out:
210 	return err;
211 }
212 
213 static PyTypeObject *pyrf_event__type[] = {
214 	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
215 	[PERF_RECORD_LOST]	 = &pyrf_mmap_event__type,
216 	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
217 	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
218 	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
219 	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
220 	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
221 	[PERF_RECORD_READ]	 = &pyrf_mmap_event__type,
222 	[PERF_RECORD_SAMPLE]	 = &pyrf_mmap_event__type,
223 };
224 
225 static PyObject *pyrf_event__new(union perf_event *event)
226 {
227 	struct pyrf_event *pevent;
228 	PyTypeObject *ptype;
229 
230 	if (event->header.type < PERF_RECORD_MMAP ||
231 	    event->header.type > PERF_RECORD_SAMPLE)
232 		return NULL;
233 
234 	ptype = pyrf_event__type[event->header.type];
235 	pevent = PyObject_New(struct pyrf_event, ptype);
236 	if (pevent != NULL)
237 		memcpy(&pevent->event, event, event->header.size);
238 	return (PyObject *)pevent;
239 }
240 
241 struct pyrf_cpu_map {
242 	PyObject_HEAD
243 
244 	struct cpu_map *cpus;
245 };
246 
247 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
248 			      PyObject *args, PyObject *kwargs)
249 {
250 	static char *kwlist[] = { "cpustr", NULL };
251 	char *cpustr = NULL;
252 
253 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
254 					 kwlist, &cpustr))
255 		return -1;
256 
257 	pcpus->cpus = cpu_map__new(cpustr);
258 	if (pcpus->cpus == NULL)
259 		return -1;
260 	return 0;
261 }
262 
263 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
264 {
265 	cpu_map__delete(pcpus->cpus);
266 	pcpus->ob_type->tp_free((PyObject*)pcpus);
267 }
268 
269 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
270 {
271 	struct pyrf_cpu_map *pcpus = (void *)obj;
272 
273 	return pcpus->cpus->nr;
274 }
275 
276 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
277 {
278 	struct pyrf_cpu_map *pcpus = (void *)obj;
279 
280 	if (i >= pcpus->cpus->nr)
281 		return NULL;
282 
283 	return Py_BuildValue("i", pcpus->cpus->map[i]);
284 }
285 
286 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
287 	.sq_length = pyrf_cpu_map__length,
288 	.sq_item   = pyrf_cpu_map__item,
289 };
290 
291 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
292 
293 static PyTypeObject pyrf_cpu_map__type = {
294 	PyVarObject_HEAD_INIT(NULL, 0)
295 	.tp_name	= "perf.cpu_map",
296 	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
297 	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
298 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
299 	.tp_doc		= pyrf_cpu_map__doc,
300 	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
301 	.tp_init	= (initproc)pyrf_cpu_map__init,
302 };
303 
304 static int pyrf_cpu_map__setup_types(void)
305 {
306 	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
307 	return PyType_Ready(&pyrf_cpu_map__type);
308 }
309 
310 struct pyrf_thread_map {
311 	PyObject_HEAD
312 
313 	struct thread_map *threads;
314 };
315 
316 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
317 				 PyObject *args, PyObject *kwargs)
318 {
319 	static char *kwlist[] = { "pid", "tid", NULL };
320 	int pid = -1, tid = -1;
321 
322 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
323 					 kwlist, &pid, &tid))
324 		return -1;
325 
326 	pthreads->threads = thread_map__new(pid, tid);
327 	if (pthreads->threads == NULL)
328 		return -1;
329 	return 0;
330 }
331 
332 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
333 {
334 	thread_map__delete(pthreads->threads);
335 	pthreads->ob_type->tp_free((PyObject*)pthreads);
336 }
337 
338 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
339 {
340 	struct pyrf_thread_map *pthreads = (void *)obj;
341 
342 	return pthreads->threads->nr;
343 }
344 
345 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
346 {
347 	struct pyrf_thread_map *pthreads = (void *)obj;
348 
349 	if (i >= pthreads->threads->nr)
350 		return NULL;
351 
352 	return Py_BuildValue("i", pthreads->threads->map[i]);
353 }
354 
355 static PySequenceMethods pyrf_thread_map__sequence_methods = {
356 	.sq_length = pyrf_thread_map__length,
357 	.sq_item   = pyrf_thread_map__item,
358 };
359 
360 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
361 
362 static PyTypeObject pyrf_thread_map__type = {
363 	PyVarObject_HEAD_INIT(NULL, 0)
364 	.tp_name	= "perf.thread_map",
365 	.tp_basicsize	= sizeof(struct pyrf_thread_map),
366 	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
367 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
368 	.tp_doc		= pyrf_thread_map__doc,
369 	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
370 	.tp_init	= (initproc)pyrf_thread_map__init,
371 };
372 
373 static int pyrf_thread_map__setup_types(void)
374 {
375 	pyrf_thread_map__type.tp_new = PyType_GenericNew;
376 	return PyType_Ready(&pyrf_thread_map__type);
377 }
378 
379 struct pyrf_evsel {
380 	PyObject_HEAD
381 
382 	struct perf_evsel evsel;
383 };
384 
385 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
386 			    PyObject *args, PyObject *kwargs)
387 {
388 	struct perf_event_attr attr = {
389 		.type = PERF_TYPE_HARDWARE,
390 		.config = PERF_COUNT_HW_CPU_CYCLES,
391 		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
392 	};
393 	static char *kwlist[] = {
394 		"type",
395 		"config",
396 		"sample_freq",
397 		"sample_period",
398 		"sample_type",
399 		"read_format",
400 		"disabled",
401 		"inherit",
402 		"pinned",
403 		"exclusive",
404 		"exclude_user",
405 		"exclude_kernel",
406 		"exclude_hv",
407 		"exclude_idle",
408 		"mmap",
409 		"comm",
410 		"freq",
411 		"inherit_stat",
412 		"enable_on_exec",
413 		"task",
414 		"watermark",
415 		"precise_ip",
416 		"mmap_data",
417 		"sample_id_all",
418 		"wakeup_events",
419 		"bp_type",
420 		"bp_addr",
421 		"bp_len",
422 		 NULL
423 	};
424 	u64 sample_period = 0;
425 	u32 disabled = 0,
426 	    inherit = 0,
427 	    pinned = 0,
428 	    exclusive = 0,
429 	    exclude_user = 0,
430 	    exclude_kernel = 0,
431 	    exclude_hv = 0,
432 	    exclude_idle = 0,
433 	    mmap = 0,
434 	    comm = 0,
435 	    freq = 1,
436 	    inherit_stat = 0,
437 	    enable_on_exec = 0,
438 	    task = 0,
439 	    watermark = 0,
440 	    precise_ip = 0,
441 	    mmap_data = 0,
442 	    sample_id_all = 1;
443 	int idx = 0;
444 
445 	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
446 					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
447 					 &attr.type, &attr.config, &attr.sample_freq,
448 					 &sample_period, &attr.sample_type,
449 					 &attr.read_format, &disabled, &inherit,
450 					 &pinned, &exclusive, &exclude_user,
451 					 &exclude_kernel, &exclude_hv, &exclude_idle,
452 					 &mmap, &comm, &freq, &inherit_stat,
453 					 &enable_on_exec, &task, &watermark,
454 					 &precise_ip, &mmap_data, &sample_id_all,
455 					 &attr.wakeup_events, &attr.bp_type,
456 					 &attr.bp_addr, &attr.bp_len, &idx))
457 		return -1;
458 
459 	/* union... */
460 	if (sample_period != 0) {
461 		if (attr.sample_freq != 0)
462 			return -1; /* FIXME: throw right exception */
463 		attr.sample_period = sample_period;
464 	}
465 
466 	/* Bitfields */
467 	attr.disabled	    = disabled;
468 	attr.inherit	    = inherit;
469 	attr.pinned	    = pinned;
470 	attr.exclusive	    = exclusive;
471 	attr.exclude_user   = exclude_user;
472 	attr.exclude_kernel = exclude_kernel;
473 	attr.exclude_hv	    = exclude_hv;
474 	attr.exclude_idle   = exclude_idle;
475 	attr.mmap	    = mmap;
476 	attr.comm	    = comm;
477 	attr.freq	    = freq;
478 	attr.inherit_stat   = inherit_stat;
479 	attr.enable_on_exec = enable_on_exec;
480 	attr.task	    = task;
481 	attr.watermark	    = watermark;
482 	attr.precise_ip	    = precise_ip;
483 	attr.mmap_data	    = mmap_data;
484 	attr.sample_id_all  = sample_id_all;
485 
486 	perf_evsel__init(&pevsel->evsel, &attr, idx);
487 	return 0;
488 }
489 
490 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
491 {
492 	perf_evsel__exit(&pevsel->evsel);
493 	pevsel->ob_type->tp_free((PyObject*)pevsel);
494 }
495 
496 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
497 				  PyObject *args, PyObject *kwargs)
498 {
499 	struct perf_evsel *evsel = &pevsel->evsel;
500 	struct cpu_map *cpus = NULL;
501 	struct thread_map *threads = NULL;
502 	PyObject *pcpus = NULL, *pthreads = NULL;
503 	int group = 0, inherit = 0;
504 	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
505 
506 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
507 					 &pcpus, &pthreads, &group, &inherit))
508 		return NULL;
509 
510 	if (pthreads != NULL)
511 		threads = ((struct pyrf_thread_map *)pthreads)->threads;
512 
513 	if (pcpus != NULL)
514 		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
515 
516 	evsel->attr.inherit = inherit;
517 	if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
518 		PyErr_SetFromErrno(PyExc_OSError);
519 		return NULL;
520 	}
521 
522 	Py_INCREF(Py_None);
523 	return Py_None;
524 }
525 
526 static PyMethodDef pyrf_evsel__methods[] = {
527 	{
528 		.ml_name  = "open",
529 		.ml_meth  = (PyCFunction)pyrf_evsel__open,
530 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
531 		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
532 	},
533 	{ .ml_name = NULL, }
534 };
535 
536 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
537 
538 static PyTypeObject pyrf_evsel__type = {
539 	PyVarObject_HEAD_INIT(NULL, 0)
540 	.tp_name	= "perf.evsel",
541 	.tp_basicsize	= sizeof(struct pyrf_evsel),
542 	.tp_dealloc	= (destructor)pyrf_evsel__delete,
543 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
544 	.tp_doc		= pyrf_evsel__doc,
545 	.tp_methods	= pyrf_evsel__methods,
546 	.tp_init	= (initproc)pyrf_evsel__init,
547 };
548 
549 static int pyrf_evsel__setup_types(void)
550 {
551 	pyrf_evsel__type.tp_new = PyType_GenericNew;
552 	return PyType_Ready(&pyrf_evsel__type);
553 }
554 
555 struct pyrf_evlist {
556 	PyObject_HEAD
557 
558 	struct perf_evlist evlist;
559 };
560 
561 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
562 			     PyObject *args, PyObject *kwargs __used)
563 {
564 	PyObject *pcpus = NULL, *pthreads = NULL;
565 	struct cpu_map *cpus;
566 	struct thread_map *threads;
567 
568 	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
569 		return -1;
570 
571 	threads = ((struct pyrf_thread_map *)pthreads)->threads;
572 	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
573 	perf_evlist__init(&pevlist->evlist, cpus, threads);
574 	return 0;
575 }
576 
577 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
578 {
579 	perf_evlist__exit(&pevlist->evlist);
580 	pevlist->ob_type->tp_free((PyObject*)pevlist);
581 }
582 
583 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
584 				   PyObject *args, PyObject *kwargs)
585 {
586 	struct perf_evlist *evlist = &pevlist->evlist;
587 	static char *kwlist[] = { "pages", "overwrite", NULL };
588 	int pages = 128, overwrite = false;
589 
590 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
591 					 &pages, &overwrite))
592 		return NULL;
593 
594 	if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
595 		PyErr_SetFromErrno(PyExc_OSError);
596 		return NULL;
597 	}
598 
599 	Py_INCREF(Py_None);
600 	return Py_None;
601 }
602 
603 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
604 				   PyObject *args, PyObject *kwargs)
605 {
606 	struct perf_evlist *evlist = &pevlist->evlist;
607 	static char *kwlist[] = { "timeout", NULL };
608 	int timeout = -1, n;
609 
610 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
611 		return NULL;
612 
613 	n = poll(evlist->pollfd, evlist->nr_fds, timeout);
614 	if (n < 0) {
615 		PyErr_SetFromErrno(PyExc_OSError);
616 		return NULL;
617 	}
618 
619 	return Py_BuildValue("i", n);
620 }
621 
622 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
623 					 PyObject *args __used, PyObject *kwargs __used)
624 {
625 	struct perf_evlist *evlist = &pevlist->evlist;
626         PyObject *list = PyList_New(0);
627 	int i;
628 
629 	for (i = 0; i < evlist->nr_fds; ++i) {
630 		PyObject *file;
631 		FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
632 
633 		if (fp == NULL)
634 			goto free_list;
635 
636 		file = PyFile_FromFile(fp, "perf", "r", NULL);
637 		if (file == NULL)
638 			goto free_list;
639 
640 		if (PyList_Append(list, file) != 0) {
641 			Py_DECREF(file);
642 			goto free_list;
643 		}
644 
645 		Py_DECREF(file);
646 	}
647 
648 	return list;
649 free_list:
650 	return PyErr_NoMemory();
651 }
652 
653 
654 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
655 				  PyObject *args, PyObject *kwargs __used)
656 {
657 	struct perf_evlist *evlist = &pevlist->evlist;
658 	PyObject *pevsel;
659 	struct perf_evsel *evsel;
660 
661 	if (!PyArg_ParseTuple(args, "O", &pevsel))
662 		return NULL;
663 
664 	Py_INCREF(pevsel);
665 	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
666 	evsel->idx = evlist->nr_entries;
667 	perf_evlist__add(evlist, evsel);
668 
669 	return Py_BuildValue("i", evlist->nr_entries);
670 }
671 
672 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
673 					  PyObject *args, PyObject *kwargs)
674 {
675 	struct perf_evlist *evlist = &pevlist->evlist;
676 	union perf_event *event;
677 	int sample_id_all = 1, cpu;
678 	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
679 	int err;
680 
681 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
682 					 &cpu, &sample_id_all))
683 		return NULL;
684 
685 	event = perf_evlist__mmap_read(evlist, cpu);
686 	if (event != NULL) {
687 		struct perf_evsel *first;
688 		PyObject *pyevent = pyrf_event__new(event);
689 		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
690 
691 		if (pyevent == NULL)
692 			return PyErr_NoMemory();
693 
694 		first = list_entry(evlist->entries.next, struct perf_evsel, node);
695 		err = perf_event__parse_sample(event, first->attr.sample_type,
696 					       perf_evsel__sample_size(first),
697 					       sample_id_all, &pevent->sample);
698 		if (err)
699 			return PyErr_Format(PyExc_OSError,
700 					    "perf: can't parse sample, err=%d", err);
701 		return pyevent;
702 	}
703 
704 	Py_INCREF(Py_None);
705 	return Py_None;
706 }
707 
708 static PyMethodDef pyrf_evlist__methods[] = {
709 	{
710 		.ml_name  = "mmap",
711 		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
712 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
713 		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
714 	},
715 	{
716 		.ml_name  = "poll",
717 		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
718 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
719 		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
720 	},
721 	{
722 		.ml_name  = "get_pollfd",
723 		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
724 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
725 		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
726 	},
727 	{
728 		.ml_name  = "add",
729 		.ml_meth  = (PyCFunction)pyrf_evlist__add,
730 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
731 		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
732 	},
733 	{
734 		.ml_name  = "read_on_cpu",
735 		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
736 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
737 		.ml_doc	  = PyDoc_STR("reads an event.")
738 	},
739 	{ .ml_name = NULL, }
740 };
741 
742 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
743 {
744 	struct pyrf_evlist *pevlist = (void *)obj;
745 
746 	return pevlist->evlist.nr_entries;
747 }
748 
749 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
750 {
751 	struct pyrf_evlist *pevlist = (void *)obj;
752 	struct perf_evsel *pos;
753 
754 	if (i >= pevlist->evlist.nr_entries)
755 		return NULL;
756 
757 	list_for_each_entry(pos, &pevlist->evlist.entries, node)
758 		if (i-- == 0)
759 			break;
760 
761 	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
762 }
763 
764 static PySequenceMethods pyrf_evlist__sequence_methods = {
765 	.sq_length = pyrf_evlist__length,
766 	.sq_item   = pyrf_evlist__item,
767 };
768 
769 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
770 
771 static PyTypeObject pyrf_evlist__type = {
772 	PyVarObject_HEAD_INIT(NULL, 0)
773 	.tp_name	= "perf.evlist",
774 	.tp_basicsize	= sizeof(struct pyrf_evlist),
775 	.tp_dealloc	= (destructor)pyrf_evlist__delete,
776 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
777 	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
778 	.tp_doc		= pyrf_evlist__doc,
779 	.tp_methods	= pyrf_evlist__methods,
780 	.tp_init	= (initproc)pyrf_evlist__init,
781 };
782 
783 static int pyrf_evlist__setup_types(void)
784 {
785 	pyrf_evlist__type.tp_new = PyType_GenericNew;
786 	return PyType_Ready(&pyrf_evlist__type);
787 }
788 
789 static struct {
790 	const char *name;
791 	int	    value;
792 } perf__constants[] = {
793 	{ "TYPE_HARDWARE",   PERF_TYPE_HARDWARE },
794 	{ "TYPE_SOFTWARE",   PERF_TYPE_SOFTWARE },
795 	{ "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
796 	{ "TYPE_HW_CACHE",   PERF_TYPE_HW_CACHE },
797 	{ "TYPE_RAW",	     PERF_TYPE_RAW },
798 	{ "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
799 
800 	{ "COUNT_HW_CPU_CYCLES",	  PERF_COUNT_HW_CPU_CYCLES },
801 	{ "COUNT_HW_INSTRUCTIONS",	  PERF_COUNT_HW_INSTRUCTIONS },
802 	{ "COUNT_HW_CACHE_REFERENCES",	  PERF_COUNT_HW_CACHE_REFERENCES },
803 	{ "COUNT_HW_CACHE_MISSES",	  PERF_COUNT_HW_CACHE_MISSES },
804 	{ "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
805 	{ "COUNT_HW_BRANCH_MISSES",	  PERF_COUNT_HW_BRANCH_MISSES },
806 	{ "COUNT_HW_BUS_CYCLES",	  PERF_COUNT_HW_BUS_CYCLES },
807 	{ "COUNT_HW_CACHE_L1D",		  PERF_COUNT_HW_CACHE_L1D },
808 	{ "COUNT_HW_CACHE_L1I",		  PERF_COUNT_HW_CACHE_L1I },
809 	{ "COUNT_HW_CACHE_LL",	  	  PERF_COUNT_HW_CACHE_LL },
810 	{ "COUNT_HW_CACHE_DTLB",	  PERF_COUNT_HW_CACHE_DTLB },
811 	{ "COUNT_HW_CACHE_ITLB",	  PERF_COUNT_HW_CACHE_ITLB },
812 	{ "COUNT_HW_CACHE_BPU",		  PERF_COUNT_HW_CACHE_BPU },
813 	{ "COUNT_HW_CACHE_OP_READ",	  PERF_COUNT_HW_CACHE_OP_READ },
814 	{ "COUNT_HW_CACHE_OP_WRITE",	  PERF_COUNT_HW_CACHE_OP_WRITE },
815 	{ "COUNT_HW_CACHE_OP_PREFETCH",	  PERF_COUNT_HW_CACHE_OP_PREFETCH },
816 	{ "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
817 	{ "COUNT_HW_CACHE_RESULT_MISS",   PERF_COUNT_HW_CACHE_RESULT_MISS },
818 
819 	{ "COUNT_HW_STALLED_CYCLES_FRONTEND",	  PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
820 	{ "COUNT_HW_STALLED_CYCLES_BACKEND",	  PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
821 
822 	{ "COUNT_SW_CPU_CLOCK",	       PERF_COUNT_SW_CPU_CLOCK },
823 	{ "COUNT_SW_TASK_CLOCK",       PERF_COUNT_SW_TASK_CLOCK },
824 	{ "COUNT_SW_PAGE_FAULTS",      PERF_COUNT_SW_PAGE_FAULTS },
825 	{ "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
826 	{ "COUNT_SW_CPU_MIGRATIONS",   PERF_COUNT_SW_CPU_MIGRATIONS },
827 	{ "COUNT_SW_PAGE_FAULTS_MIN",  PERF_COUNT_SW_PAGE_FAULTS_MIN },
828 	{ "COUNT_SW_PAGE_FAULTS_MAJ",  PERF_COUNT_SW_PAGE_FAULTS_MAJ },
829 	{ "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
830 	{ "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
831 
832 	{ "SAMPLE_IP",	      PERF_SAMPLE_IP },
833 	{ "SAMPLE_TID",	      PERF_SAMPLE_TID },
834 	{ "SAMPLE_TIME",      PERF_SAMPLE_TIME },
835 	{ "SAMPLE_ADDR",      PERF_SAMPLE_ADDR },
836 	{ "SAMPLE_READ",      PERF_SAMPLE_READ },
837 	{ "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
838 	{ "SAMPLE_ID",	      PERF_SAMPLE_ID },
839 	{ "SAMPLE_CPU",	      PERF_SAMPLE_CPU },
840 	{ "SAMPLE_PERIOD",    PERF_SAMPLE_PERIOD },
841 	{ "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
842 	{ "SAMPLE_RAW",	      PERF_SAMPLE_RAW },
843 
844 	{ "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
845 	{ "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
846 	{ "FORMAT_ID",		       PERF_FORMAT_ID },
847 	{ "FORMAT_GROUP",	       PERF_FORMAT_GROUP },
848 
849 	{ "RECORD_MMAP",       PERF_RECORD_MMAP },
850 	{ "RECORD_LOST",       PERF_RECORD_LOST },
851 	{ "RECORD_COMM",       PERF_RECORD_COMM },
852 	{ "RECORD_EXIT",       PERF_RECORD_EXIT },
853 	{ "RECORD_THROTTLE",   PERF_RECORD_THROTTLE },
854 	{ "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
855 	{ "RECORD_FORK",       PERF_RECORD_FORK },
856 	{ "RECORD_READ",       PERF_RECORD_READ },
857 	{ "RECORD_SAMPLE",     PERF_RECORD_SAMPLE },
858 	{ .name = NULL, },
859 };
860 
861 static PyMethodDef perf__methods[] = {
862 	{ .ml_name = NULL, }
863 };
864 
865 PyMODINIT_FUNC initperf(void)
866 {
867 	PyObject *obj;
868 	int i;
869 	PyObject *dict, *module = Py_InitModule("perf", perf__methods);
870 
871 	if (module == NULL ||
872 	    pyrf_event__setup_types() < 0 ||
873 	    pyrf_evlist__setup_types() < 0 ||
874 	    pyrf_evsel__setup_types() < 0 ||
875 	    pyrf_thread_map__setup_types() < 0 ||
876 	    pyrf_cpu_map__setup_types() < 0)
877 		return;
878 
879 	Py_INCREF(&pyrf_evlist__type);
880 	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
881 
882 	Py_INCREF(&pyrf_evsel__type);
883 	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
884 
885 	Py_INCREF(&pyrf_thread_map__type);
886 	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
887 
888 	Py_INCREF(&pyrf_cpu_map__type);
889 	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
890 
891 	dict = PyModule_GetDict(module);
892 	if (dict == NULL)
893 		goto error;
894 
895 	for (i = 0; perf__constants[i].name != NULL; i++) {
896 		obj = PyInt_FromLong(perf__constants[i].value);
897 		if (obj == NULL)
898 			goto error;
899 		PyDict_SetItemString(dict, perf__constants[i].name, obj);
900 		Py_DECREF(obj);
901 	}
902 
903 error:
904 	if (PyErr_Occurred())
905 		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
906 }
907