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/*
12 * Support debug printing even though util/debug.c is not linked.  That means
13 * implementing 'verbose' and 'eprintf'.
14 */
15int verbose;
16
17int eprintf(int level, int var, const char *fmt, ...)
18{
19	va_list args;
20	int ret = 0;
21
22	if (var >= level) {
23		va_start(args, fmt);
24		ret = vfprintf(stderr, fmt, args);
25		va_end(args);
26	}
27
28	return ret;
29}
30
31/* Define PyVarObject_HEAD_INIT for python 2.5 */
32#ifndef PyVarObject_HEAD_INIT
33# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
34#endif
35
36PyMODINIT_FUNC initperf(void);
37
38#define member_def(type, member, ptype, help) \
39	{ #member, ptype, \
40	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
41	  0, help }
42
43#define sample_member_def(name, member, ptype, help) \
44	{ #name, ptype, \
45	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
46	  0, help }
47
48struct pyrf_event {
49	PyObject_HEAD
50	struct perf_sample sample;
51	union perf_event   event;
52};
53
54#define sample_members \
55	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
56	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
57	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
58	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
59	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
60	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
61	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
62	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
63	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
64
65static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
66
67static PyMemberDef pyrf_mmap_event__members[] = {
68	sample_members
69	member_def(perf_event_header, type, T_UINT, "event type"),
70	member_def(perf_event_header, misc, T_UINT, "event misc"),
71	member_def(mmap_event, pid, T_UINT, "event pid"),
72	member_def(mmap_event, tid, T_UINT, "event tid"),
73	member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
74	member_def(mmap_event, len, T_ULONGLONG, "map length"),
75	member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
76	member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
77	{ .name = NULL, },
78};
79
80static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
81{
82	PyObject *ret;
83	char *s;
84
85	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
86			 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
87			 "filename: %s }",
88		     pevent->event.mmap.pid, pevent->event.mmap.tid,
89		     pevent->event.mmap.start, pevent->event.mmap.len,
90		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
91		ret = PyErr_NoMemory();
92	} else {
93		ret = PyString_FromString(s);
94		free(s);
95	}
96	return ret;
97}
98
99static PyTypeObject pyrf_mmap_event__type = {
100	PyVarObject_HEAD_INIT(NULL, 0)
101	.tp_name	= "perf.mmap_event",
102	.tp_basicsize	= sizeof(struct pyrf_event),
103	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
104	.tp_doc		= pyrf_mmap_event__doc,
105	.tp_members	= pyrf_mmap_event__members,
106	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
107};
108
109static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
110
111static PyMemberDef pyrf_task_event__members[] = {
112	sample_members
113	member_def(perf_event_header, type, T_UINT, "event type"),
114	member_def(fork_event, pid, T_UINT, "event pid"),
115	member_def(fork_event, ppid, T_UINT, "event ppid"),
116	member_def(fork_event, tid, T_UINT, "event tid"),
117	member_def(fork_event, ptid, T_UINT, "event ptid"),
118	member_def(fork_event, time, T_ULONGLONG, "timestamp"),
119	{ .name = NULL, },
120};
121
122static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
123{
124	return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
125				   "ptid: %u, time: %" PRIu64 "}",
126				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
127				   pevent->event.fork.pid,
128				   pevent->event.fork.ppid,
129				   pevent->event.fork.tid,
130				   pevent->event.fork.ptid,
131				   pevent->event.fork.time);
132}
133
134static PyTypeObject pyrf_task_event__type = {
135	PyVarObject_HEAD_INIT(NULL, 0)
136	.tp_name	= "perf.task_event",
137	.tp_basicsize	= sizeof(struct pyrf_event),
138	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
139	.tp_doc		= pyrf_task_event__doc,
140	.tp_members	= pyrf_task_event__members,
141	.tp_repr	= (reprfunc)pyrf_task_event__repr,
142};
143
144static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
145
146static PyMemberDef pyrf_comm_event__members[] = {
147	sample_members
148	member_def(perf_event_header, type, T_UINT, "event type"),
149	member_def(comm_event, pid, T_UINT, "event pid"),
150	member_def(comm_event, tid, T_UINT, "event tid"),
151	member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
152	{ .name = NULL, },
153};
154
155static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
156{
157	return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
158				   pevent->event.comm.pid,
159				   pevent->event.comm.tid,
160				   pevent->event.comm.comm);
161}
162
163static PyTypeObject pyrf_comm_event__type = {
164	PyVarObject_HEAD_INIT(NULL, 0)
165	.tp_name	= "perf.comm_event",
166	.tp_basicsize	= sizeof(struct pyrf_event),
167	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
168	.tp_doc		= pyrf_comm_event__doc,
169	.tp_members	= pyrf_comm_event__members,
170	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
171};
172
173static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
174
175static PyMemberDef pyrf_throttle_event__members[] = {
176	sample_members
177	member_def(perf_event_header, type, T_UINT, "event type"),
178	member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
179	member_def(throttle_event, id, T_ULONGLONG, "event id"),
180	member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
181	{ .name = NULL, },
182};
183
184static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
185{
186	struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
187
188	return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
189				   ", stream_id: %" PRIu64 " }",
190				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
191				   te->time, te->id, te->stream_id);
192}
193
194static PyTypeObject pyrf_throttle_event__type = {
195	PyVarObject_HEAD_INIT(NULL, 0)
196	.tp_name	= "perf.throttle_event",
197	.tp_basicsize	= sizeof(struct pyrf_event),
198	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
199	.tp_doc		= pyrf_throttle_event__doc,
200	.tp_members	= pyrf_throttle_event__members,
201	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
202};
203
204static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
205
206static PyMemberDef pyrf_lost_event__members[] = {
207	sample_members
208	member_def(lost_event, id, T_ULONGLONG, "event id"),
209	member_def(lost_event, lost, T_ULONGLONG, "number of lost events"),
210	{ .name = NULL, },
211};
212
213static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
214{
215	PyObject *ret;
216	char *s;
217
218	if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", "
219			 "lost: %#" PRIx64 " }",
220		     pevent->event.lost.id, pevent->event.lost.lost) < 0) {
221		ret = PyErr_NoMemory();
222	} else {
223		ret = PyString_FromString(s);
224		free(s);
225	}
226	return ret;
227}
228
229static PyTypeObject pyrf_lost_event__type = {
230	PyVarObject_HEAD_INIT(NULL, 0)
231	.tp_name	= "perf.lost_event",
232	.tp_basicsize	= sizeof(struct pyrf_event),
233	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
234	.tp_doc		= pyrf_lost_event__doc,
235	.tp_members	= pyrf_lost_event__members,
236	.tp_repr	= (reprfunc)pyrf_lost_event__repr,
237};
238
239static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
240
241static PyMemberDef pyrf_read_event__members[] = {
242	sample_members
243	member_def(read_event, pid, T_UINT, "event pid"),
244	member_def(read_event, tid, T_UINT, "event tid"),
245	{ .name = NULL, },
246};
247
248static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
249{
250	return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
251				   pevent->event.read.pid,
252				   pevent->event.read.tid);
253	/*
254 	 * FIXME: return the array of read values,
255 	 * making this method useful ;-)
256 	 */
257}
258
259static PyTypeObject pyrf_read_event__type = {
260	PyVarObject_HEAD_INIT(NULL, 0)
261	.tp_name	= "perf.read_event",
262	.tp_basicsize	= sizeof(struct pyrf_event),
263	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
264	.tp_doc		= pyrf_read_event__doc,
265	.tp_members	= pyrf_read_event__members,
266	.tp_repr	= (reprfunc)pyrf_read_event__repr,
267};
268
269static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
270
271static PyMemberDef pyrf_sample_event__members[] = {
272	sample_members
273	member_def(perf_event_header, type, T_UINT, "event type"),
274	{ .name = NULL, },
275};
276
277static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
278{
279	PyObject *ret;
280	char *s;
281
282	if (asprintf(&s, "{ type: sample }") < 0) {
283		ret = PyErr_NoMemory();
284	} else {
285		ret = PyString_FromString(s);
286		free(s);
287	}
288	return ret;
289}
290
291static PyTypeObject pyrf_sample_event__type = {
292	PyVarObject_HEAD_INIT(NULL, 0)
293	.tp_name	= "perf.sample_event",
294	.tp_basicsize	= sizeof(struct pyrf_event),
295	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
296	.tp_doc		= pyrf_sample_event__doc,
297	.tp_members	= pyrf_sample_event__members,
298	.tp_repr	= (reprfunc)pyrf_sample_event__repr,
299};
300
301static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
302
303static PyMemberDef pyrf_context_switch_event__members[] = {
304	sample_members
305	member_def(perf_event_header, type, T_UINT, "event type"),
306	member_def(context_switch_event, next_prev_pid, T_UINT, "next/prev pid"),
307	member_def(context_switch_event, next_prev_tid, T_UINT, "next/prev tid"),
308	{ .name = NULL, },
309};
310
311static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
312{
313	PyObject *ret;
314	char *s;
315
316	if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
317		     pevent->event.context_switch.next_prev_pid,
318		     pevent->event.context_switch.next_prev_tid,
319		     !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
320		ret = PyErr_NoMemory();
321	} else {
322		ret = PyString_FromString(s);
323		free(s);
324	}
325	return ret;
326}
327
328static PyTypeObject pyrf_context_switch_event__type = {
329	PyVarObject_HEAD_INIT(NULL, 0)
330	.tp_name	= "perf.context_switch_event",
331	.tp_basicsize	= sizeof(struct pyrf_event),
332	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
333	.tp_doc		= pyrf_context_switch_event__doc,
334	.tp_members	= pyrf_context_switch_event__members,
335	.tp_repr	= (reprfunc)pyrf_context_switch_event__repr,
336};
337
338static int pyrf_event__setup_types(void)
339{
340	int err;
341	pyrf_mmap_event__type.tp_new =
342	pyrf_task_event__type.tp_new =
343	pyrf_comm_event__type.tp_new =
344	pyrf_lost_event__type.tp_new =
345	pyrf_read_event__type.tp_new =
346	pyrf_sample_event__type.tp_new =
347	pyrf_context_switch_event__type.tp_new =
348	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
349	err = PyType_Ready(&pyrf_mmap_event__type);
350	if (err < 0)
351		goto out;
352	err = PyType_Ready(&pyrf_lost_event__type);
353	if (err < 0)
354		goto out;
355	err = PyType_Ready(&pyrf_task_event__type);
356	if (err < 0)
357		goto out;
358	err = PyType_Ready(&pyrf_comm_event__type);
359	if (err < 0)
360		goto out;
361	err = PyType_Ready(&pyrf_throttle_event__type);
362	if (err < 0)
363		goto out;
364	err = PyType_Ready(&pyrf_read_event__type);
365	if (err < 0)
366		goto out;
367	err = PyType_Ready(&pyrf_sample_event__type);
368	if (err < 0)
369		goto out;
370	err = PyType_Ready(&pyrf_context_switch_event__type);
371	if (err < 0)
372		goto out;
373out:
374	return err;
375}
376
377static PyTypeObject *pyrf_event__type[] = {
378	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
379	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,
380	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
381	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
382	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
383	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
384	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
385	[PERF_RECORD_READ]	 = &pyrf_read_event__type,
386	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,
387	[PERF_RECORD_SWITCH]	 = &pyrf_context_switch_event__type,
388	[PERF_RECORD_SWITCH_CPU_WIDE]  = &pyrf_context_switch_event__type,
389};
390
391static PyObject *pyrf_event__new(union perf_event *event)
392{
393	struct pyrf_event *pevent;
394	PyTypeObject *ptype;
395
396	if ((event->header.type < PERF_RECORD_MMAP ||
397	     event->header.type > PERF_RECORD_SAMPLE) &&
398	    !(event->header.type == PERF_RECORD_SWITCH ||
399	      event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
400		return NULL;
401
402	ptype = pyrf_event__type[event->header.type];
403	pevent = PyObject_New(struct pyrf_event, ptype);
404	if (pevent != NULL)
405		memcpy(&pevent->event, event, event->header.size);
406	return (PyObject *)pevent;
407}
408
409struct pyrf_cpu_map {
410	PyObject_HEAD
411
412	struct cpu_map *cpus;
413};
414
415static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
416			      PyObject *args, PyObject *kwargs)
417{
418	static char *kwlist[] = { "cpustr", NULL };
419	char *cpustr = NULL;
420
421	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
422					 kwlist, &cpustr))
423		return -1;
424
425	pcpus->cpus = cpu_map__new(cpustr);
426	if (pcpus->cpus == NULL)
427		return -1;
428	return 0;
429}
430
431static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
432{
433	cpu_map__put(pcpus->cpus);
434	pcpus->ob_type->tp_free((PyObject*)pcpus);
435}
436
437static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
438{
439	struct pyrf_cpu_map *pcpus = (void *)obj;
440
441	return pcpus->cpus->nr;
442}
443
444static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
445{
446	struct pyrf_cpu_map *pcpus = (void *)obj;
447
448	if (i >= pcpus->cpus->nr)
449		return NULL;
450
451	return Py_BuildValue("i", pcpus->cpus->map[i]);
452}
453
454static PySequenceMethods pyrf_cpu_map__sequence_methods = {
455	.sq_length = pyrf_cpu_map__length,
456	.sq_item   = pyrf_cpu_map__item,
457};
458
459static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
460
461static PyTypeObject pyrf_cpu_map__type = {
462	PyVarObject_HEAD_INIT(NULL, 0)
463	.tp_name	= "perf.cpu_map",
464	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
465	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
466	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
467	.tp_doc		= pyrf_cpu_map__doc,
468	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
469	.tp_init	= (initproc)pyrf_cpu_map__init,
470};
471
472static int pyrf_cpu_map__setup_types(void)
473{
474	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
475	return PyType_Ready(&pyrf_cpu_map__type);
476}
477
478struct pyrf_thread_map {
479	PyObject_HEAD
480
481	struct thread_map *threads;
482};
483
484static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
485				 PyObject *args, PyObject *kwargs)
486{
487	static char *kwlist[] = { "pid", "tid", "uid", NULL };
488	int pid = -1, tid = -1, uid = UINT_MAX;
489
490	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
491					 kwlist, &pid, &tid, &uid))
492		return -1;
493
494	pthreads->threads = thread_map__new(pid, tid, uid);
495	if (pthreads->threads == NULL)
496		return -1;
497	return 0;
498}
499
500static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
501{
502	thread_map__put(pthreads->threads);
503	pthreads->ob_type->tp_free((PyObject*)pthreads);
504}
505
506static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
507{
508	struct pyrf_thread_map *pthreads = (void *)obj;
509
510	return pthreads->threads->nr;
511}
512
513static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
514{
515	struct pyrf_thread_map *pthreads = (void *)obj;
516
517	if (i >= pthreads->threads->nr)
518		return NULL;
519
520	return Py_BuildValue("i", pthreads->threads->map[i]);
521}
522
523static PySequenceMethods pyrf_thread_map__sequence_methods = {
524	.sq_length = pyrf_thread_map__length,
525	.sq_item   = pyrf_thread_map__item,
526};
527
528static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
529
530static PyTypeObject pyrf_thread_map__type = {
531	PyVarObject_HEAD_INIT(NULL, 0)
532	.tp_name	= "perf.thread_map",
533	.tp_basicsize	= sizeof(struct pyrf_thread_map),
534	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
535	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
536	.tp_doc		= pyrf_thread_map__doc,
537	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
538	.tp_init	= (initproc)pyrf_thread_map__init,
539};
540
541static int pyrf_thread_map__setup_types(void)
542{
543	pyrf_thread_map__type.tp_new = PyType_GenericNew;
544	return PyType_Ready(&pyrf_thread_map__type);
545}
546
547struct pyrf_evsel {
548	PyObject_HEAD
549
550	struct perf_evsel evsel;
551};
552
553static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
554			    PyObject *args, PyObject *kwargs)
555{
556	struct perf_event_attr attr = {
557		.type = PERF_TYPE_HARDWARE,
558		.config = PERF_COUNT_HW_CPU_CYCLES,
559		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
560	};
561	static char *kwlist[] = {
562		"type",
563		"config",
564		"sample_freq",
565		"sample_period",
566		"sample_type",
567		"read_format",
568		"disabled",
569		"inherit",
570		"pinned",
571		"exclusive",
572		"exclude_user",
573		"exclude_kernel",
574		"exclude_hv",
575		"exclude_idle",
576		"mmap",
577		"context_switch",
578		"comm",
579		"freq",
580		"inherit_stat",
581		"enable_on_exec",
582		"task",
583		"watermark",
584		"precise_ip",
585		"mmap_data",
586		"sample_id_all",
587		"wakeup_events",
588		"bp_type",
589		"bp_addr",
590		"bp_len",
591		 NULL
592	};
593	u64 sample_period = 0;
594	u32 disabled = 0,
595	    inherit = 0,
596	    pinned = 0,
597	    exclusive = 0,
598	    exclude_user = 0,
599	    exclude_kernel = 0,
600	    exclude_hv = 0,
601	    exclude_idle = 0,
602	    mmap = 0,
603	    context_switch = 0,
604	    comm = 0,
605	    freq = 1,
606	    inherit_stat = 0,
607	    enable_on_exec = 0,
608	    task = 0,
609	    watermark = 0,
610	    precise_ip = 0,
611	    mmap_data = 0,
612	    sample_id_all = 1;
613	int idx = 0;
614
615	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
616					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
617					 &attr.type, &attr.config, &attr.sample_freq,
618					 &sample_period, &attr.sample_type,
619					 &attr.read_format, &disabled, &inherit,
620					 &pinned, &exclusive, &exclude_user,
621					 &exclude_kernel, &exclude_hv, &exclude_idle,
622					 &mmap, &context_switch, &comm, &freq, &inherit_stat,
623					 &enable_on_exec, &task, &watermark,
624					 &precise_ip, &mmap_data, &sample_id_all,
625					 &attr.wakeup_events, &attr.bp_type,
626					 &attr.bp_addr, &attr.bp_len, &idx))
627		return -1;
628
629	/* union... */
630	if (sample_period != 0) {
631		if (attr.sample_freq != 0)
632			return -1; /* FIXME: throw right exception */
633		attr.sample_period = sample_period;
634	}
635
636	/* Bitfields */
637	attr.disabled	    = disabled;
638	attr.inherit	    = inherit;
639	attr.pinned	    = pinned;
640	attr.exclusive	    = exclusive;
641	attr.exclude_user   = exclude_user;
642	attr.exclude_kernel = exclude_kernel;
643	attr.exclude_hv	    = exclude_hv;
644	attr.exclude_idle   = exclude_idle;
645	attr.mmap	    = mmap;
646	attr.context_switch = context_switch;
647	attr.comm	    = comm;
648	attr.freq	    = freq;
649	attr.inherit_stat   = inherit_stat;
650	attr.enable_on_exec = enable_on_exec;
651	attr.task	    = task;
652	attr.watermark	    = watermark;
653	attr.precise_ip	    = precise_ip;
654	attr.mmap_data	    = mmap_data;
655	attr.sample_id_all  = sample_id_all;
656
657	perf_evsel__init(&pevsel->evsel, &attr, idx);
658	return 0;
659}
660
661static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
662{
663	perf_evsel__exit(&pevsel->evsel);
664	pevsel->ob_type->tp_free((PyObject*)pevsel);
665}
666
667static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
668				  PyObject *args, PyObject *kwargs)
669{
670	struct perf_evsel *evsel = &pevsel->evsel;
671	struct cpu_map *cpus = NULL;
672	struct thread_map *threads = NULL;
673	PyObject *pcpus = NULL, *pthreads = NULL;
674	int group = 0, inherit = 0;
675	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
676
677	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
678					 &pcpus, &pthreads, &group, &inherit))
679		return NULL;
680
681	if (pthreads != NULL)
682		threads = ((struct pyrf_thread_map *)pthreads)->threads;
683
684	if (pcpus != NULL)
685		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
686
687	evsel->attr.inherit = inherit;
688	/*
689	 * This will group just the fds for this single evsel, to group
690	 * multiple events, use evlist.open().
691	 */
692	if (perf_evsel__open(evsel, cpus, threads) < 0) {
693		PyErr_SetFromErrno(PyExc_OSError);
694		return NULL;
695	}
696
697	Py_INCREF(Py_None);
698	return Py_None;
699}
700
701static PyMethodDef pyrf_evsel__methods[] = {
702	{
703		.ml_name  = "open",
704		.ml_meth  = (PyCFunction)pyrf_evsel__open,
705		.ml_flags = METH_VARARGS | METH_KEYWORDS,
706		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
707	},
708	{ .ml_name = NULL, }
709};
710
711static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
712
713static PyTypeObject pyrf_evsel__type = {
714	PyVarObject_HEAD_INIT(NULL, 0)
715	.tp_name	= "perf.evsel",
716	.tp_basicsize	= sizeof(struct pyrf_evsel),
717	.tp_dealloc	= (destructor)pyrf_evsel__delete,
718	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
719	.tp_doc		= pyrf_evsel__doc,
720	.tp_methods	= pyrf_evsel__methods,
721	.tp_init	= (initproc)pyrf_evsel__init,
722};
723
724static int pyrf_evsel__setup_types(void)
725{
726	pyrf_evsel__type.tp_new = PyType_GenericNew;
727	return PyType_Ready(&pyrf_evsel__type);
728}
729
730struct pyrf_evlist {
731	PyObject_HEAD
732
733	struct perf_evlist evlist;
734};
735
736static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
737			     PyObject *args, PyObject *kwargs __maybe_unused)
738{
739	PyObject *pcpus = NULL, *pthreads = NULL;
740	struct cpu_map *cpus;
741	struct thread_map *threads;
742
743	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
744		return -1;
745
746	threads = ((struct pyrf_thread_map *)pthreads)->threads;
747	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
748	perf_evlist__init(&pevlist->evlist, cpus, threads);
749	return 0;
750}
751
752static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
753{
754	perf_evlist__exit(&pevlist->evlist);
755	pevlist->ob_type->tp_free((PyObject*)pevlist);
756}
757
758static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
759				   PyObject *args, PyObject *kwargs)
760{
761	struct perf_evlist *evlist = &pevlist->evlist;
762	static char *kwlist[] = { "pages", "overwrite", NULL };
763	int pages = 128, overwrite = false;
764
765	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
766					 &pages, &overwrite))
767		return NULL;
768
769	if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
770		PyErr_SetFromErrno(PyExc_OSError);
771		return NULL;
772	}
773
774	Py_INCREF(Py_None);
775	return Py_None;
776}
777
778static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
779				   PyObject *args, PyObject *kwargs)
780{
781	struct perf_evlist *evlist = &pevlist->evlist;
782	static char *kwlist[] = { "timeout", NULL };
783	int timeout = -1, n;
784
785	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
786		return NULL;
787
788	n = perf_evlist__poll(evlist, timeout);
789	if (n < 0) {
790		PyErr_SetFromErrno(PyExc_OSError);
791		return NULL;
792	}
793
794	return Py_BuildValue("i", n);
795}
796
797static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
798					 PyObject *args __maybe_unused,
799					 PyObject *kwargs __maybe_unused)
800{
801	struct perf_evlist *evlist = &pevlist->evlist;
802        PyObject *list = PyList_New(0);
803	int i;
804
805	for (i = 0; i < evlist->pollfd.nr; ++i) {
806		PyObject *file;
807		FILE *fp = fdopen(evlist->pollfd.entries[i].fd, "r");
808
809		if (fp == NULL)
810			goto free_list;
811
812		file = PyFile_FromFile(fp, "perf", "r", NULL);
813		if (file == NULL)
814			goto free_list;
815
816		if (PyList_Append(list, file) != 0) {
817			Py_DECREF(file);
818			goto free_list;
819		}
820
821		Py_DECREF(file);
822	}
823
824	return list;
825free_list:
826	return PyErr_NoMemory();
827}
828
829
830static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
831				  PyObject *args,
832				  PyObject *kwargs __maybe_unused)
833{
834	struct perf_evlist *evlist = &pevlist->evlist;
835	PyObject *pevsel;
836	struct perf_evsel *evsel;
837
838	if (!PyArg_ParseTuple(args, "O", &pevsel))
839		return NULL;
840
841	Py_INCREF(pevsel);
842	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
843	evsel->idx = evlist->nr_entries;
844	perf_evlist__add(evlist, evsel);
845
846	return Py_BuildValue("i", evlist->nr_entries);
847}
848
849static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
850					  PyObject *args, PyObject *kwargs)
851{
852	struct perf_evlist *evlist = &pevlist->evlist;
853	union perf_event *event;
854	int sample_id_all = 1, cpu;
855	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
856	int err;
857
858	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
859					 &cpu, &sample_id_all))
860		return NULL;
861
862	event = perf_evlist__mmap_read(evlist, cpu);
863	if (event != NULL) {
864		PyObject *pyevent = pyrf_event__new(event);
865		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
866
867		perf_evlist__mmap_consume(evlist, cpu);
868
869		if (pyevent == NULL)
870			return PyErr_NoMemory();
871
872		err = perf_evlist__parse_sample(evlist, event, &pevent->sample);
873		if (err)
874			return PyErr_Format(PyExc_OSError,
875					    "perf: can't parse sample, err=%d", err);
876		return pyevent;
877	}
878
879	Py_INCREF(Py_None);
880	return Py_None;
881}
882
883static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
884				   PyObject *args, PyObject *kwargs)
885{
886	struct perf_evlist *evlist = &pevlist->evlist;
887	int group = 0;
888	static char *kwlist[] = { "group", NULL };
889
890	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
891		return NULL;
892
893	if (group)
894		perf_evlist__set_leader(evlist);
895
896	if (perf_evlist__open(evlist) < 0) {
897		PyErr_SetFromErrno(PyExc_OSError);
898		return NULL;
899	}
900
901	Py_INCREF(Py_None);
902	return Py_None;
903}
904
905static PyMethodDef pyrf_evlist__methods[] = {
906	{
907		.ml_name  = "mmap",
908		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
909		.ml_flags = METH_VARARGS | METH_KEYWORDS,
910		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
911	},
912	{
913		.ml_name  = "open",
914		.ml_meth  = (PyCFunction)pyrf_evlist__open,
915		.ml_flags = METH_VARARGS | METH_KEYWORDS,
916		.ml_doc	  = PyDoc_STR("open the file descriptors.")
917	},
918	{
919		.ml_name  = "poll",
920		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
921		.ml_flags = METH_VARARGS | METH_KEYWORDS,
922		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
923	},
924	{
925		.ml_name  = "get_pollfd",
926		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
927		.ml_flags = METH_VARARGS | METH_KEYWORDS,
928		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
929	},
930	{
931		.ml_name  = "add",
932		.ml_meth  = (PyCFunction)pyrf_evlist__add,
933		.ml_flags = METH_VARARGS | METH_KEYWORDS,
934		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
935	},
936	{
937		.ml_name  = "read_on_cpu",
938		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
939		.ml_flags = METH_VARARGS | METH_KEYWORDS,
940		.ml_doc	  = PyDoc_STR("reads an event.")
941	},
942	{ .ml_name = NULL, }
943};
944
945static Py_ssize_t pyrf_evlist__length(PyObject *obj)
946{
947	struct pyrf_evlist *pevlist = (void *)obj;
948
949	return pevlist->evlist.nr_entries;
950}
951
952static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
953{
954	struct pyrf_evlist *pevlist = (void *)obj;
955	struct perf_evsel *pos;
956
957	if (i >= pevlist->evlist.nr_entries)
958		return NULL;
959
960	evlist__for_each(&pevlist->evlist, pos) {
961		if (i-- == 0)
962			break;
963	}
964
965	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
966}
967
968static PySequenceMethods pyrf_evlist__sequence_methods = {
969	.sq_length = pyrf_evlist__length,
970	.sq_item   = pyrf_evlist__item,
971};
972
973static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
974
975static PyTypeObject pyrf_evlist__type = {
976	PyVarObject_HEAD_INIT(NULL, 0)
977	.tp_name	= "perf.evlist",
978	.tp_basicsize	= sizeof(struct pyrf_evlist),
979	.tp_dealloc	= (destructor)pyrf_evlist__delete,
980	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
981	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
982	.tp_doc		= pyrf_evlist__doc,
983	.tp_methods	= pyrf_evlist__methods,
984	.tp_init	= (initproc)pyrf_evlist__init,
985};
986
987static int pyrf_evlist__setup_types(void)
988{
989	pyrf_evlist__type.tp_new = PyType_GenericNew;
990	return PyType_Ready(&pyrf_evlist__type);
991}
992
993#define PERF_CONST(name) { #name, PERF_##name }
994
995static struct {
996	const char *name;
997	int	    value;
998} perf__constants[] = {
999	PERF_CONST(TYPE_HARDWARE),
1000	PERF_CONST(TYPE_SOFTWARE),
1001	PERF_CONST(TYPE_TRACEPOINT),
1002	PERF_CONST(TYPE_HW_CACHE),
1003	PERF_CONST(TYPE_RAW),
1004	PERF_CONST(TYPE_BREAKPOINT),
1005
1006	PERF_CONST(COUNT_HW_CPU_CYCLES),
1007	PERF_CONST(COUNT_HW_INSTRUCTIONS),
1008	PERF_CONST(COUNT_HW_CACHE_REFERENCES),
1009	PERF_CONST(COUNT_HW_CACHE_MISSES),
1010	PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
1011	PERF_CONST(COUNT_HW_BRANCH_MISSES),
1012	PERF_CONST(COUNT_HW_BUS_CYCLES),
1013	PERF_CONST(COUNT_HW_CACHE_L1D),
1014	PERF_CONST(COUNT_HW_CACHE_L1I),
1015	PERF_CONST(COUNT_HW_CACHE_LL),
1016	PERF_CONST(COUNT_HW_CACHE_DTLB),
1017	PERF_CONST(COUNT_HW_CACHE_ITLB),
1018	PERF_CONST(COUNT_HW_CACHE_BPU),
1019	PERF_CONST(COUNT_HW_CACHE_OP_READ),
1020	PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
1021	PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
1022	PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
1023	PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
1024
1025	PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
1026	PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
1027
1028	PERF_CONST(COUNT_SW_CPU_CLOCK),
1029	PERF_CONST(COUNT_SW_TASK_CLOCK),
1030	PERF_CONST(COUNT_SW_PAGE_FAULTS),
1031	PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
1032	PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
1033	PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
1034	PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
1035	PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
1036	PERF_CONST(COUNT_SW_EMULATION_FAULTS),
1037	PERF_CONST(COUNT_SW_DUMMY),
1038
1039	PERF_CONST(SAMPLE_IP),
1040	PERF_CONST(SAMPLE_TID),
1041	PERF_CONST(SAMPLE_TIME),
1042	PERF_CONST(SAMPLE_ADDR),
1043	PERF_CONST(SAMPLE_READ),
1044	PERF_CONST(SAMPLE_CALLCHAIN),
1045	PERF_CONST(SAMPLE_ID),
1046	PERF_CONST(SAMPLE_CPU),
1047	PERF_CONST(SAMPLE_PERIOD),
1048	PERF_CONST(SAMPLE_STREAM_ID),
1049	PERF_CONST(SAMPLE_RAW),
1050
1051	PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
1052	PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
1053	PERF_CONST(FORMAT_ID),
1054	PERF_CONST(FORMAT_GROUP),
1055
1056	PERF_CONST(RECORD_MMAP),
1057	PERF_CONST(RECORD_LOST),
1058	PERF_CONST(RECORD_COMM),
1059	PERF_CONST(RECORD_EXIT),
1060	PERF_CONST(RECORD_THROTTLE),
1061	PERF_CONST(RECORD_UNTHROTTLE),
1062	PERF_CONST(RECORD_FORK),
1063	PERF_CONST(RECORD_READ),
1064	PERF_CONST(RECORD_SAMPLE),
1065	PERF_CONST(RECORD_MMAP2),
1066	PERF_CONST(RECORD_AUX),
1067	PERF_CONST(RECORD_ITRACE_START),
1068	PERF_CONST(RECORD_LOST_SAMPLES),
1069	PERF_CONST(RECORD_SWITCH),
1070	PERF_CONST(RECORD_SWITCH_CPU_WIDE),
1071
1072	PERF_CONST(RECORD_MISC_SWITCH_OUT),
1073	{ .name = NULL, },
1074};
1075
1076static PyMethodDef perf__methods[] = {
1077	{ .ml_name = NULL, }
1078};
1079
1080PyMODINIT_FUNC initperf(void)
1081{
1082	PyObject *obj;
1083	int i;
1084	PyObject *dict, *module = Py_InitModule("perf", perf__methods);
1085
1086	if (module == NULL ||
1087	    pyrf_event__setup_types() < 0 ||
1088	    pyrf_evlist__setup_types() < 0 ||
1089	    pyrf_evsel__setup_types() < 0 ||
1090	    pyrf_thread_map__setup_types() < 0 ||
1091	    pyrf_cpu_map__setup_types() < 0)
1092		return;
1093
1094	/* The page_size is placed in util object. */
1095	page_size = sysconf(_SC_PAGE_SIZE);
1096
1097	Py_INCREF(&pyrf_evlist__type);
1098	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
1099
1100	Py_INCREF(&pyrf_evsel__type);
1101	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1102
1103	Py_INCREF(&pyrf_thread_map__type);
1104	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1105
1106	Py_INCREF(&pyrf_cpu_map__type);
1107	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
1108
1109	dict = PyModule_GetDict(module);
1110	if (dict == NULL)
1111		goto error;
1112
1113	for (i = 0; perf__constants[i].name != NULL; i++) {
1114		obj = PyInt_FromLong(perf__constants[i].value);
1115		if (obj == NULL)
1116			goto error;
1117		PyDict_SetItemString(dict, perf__constants[i].name, obj);
1118		Py_DECREF(obj);
1119	}
1120
1121error:
1122	if (PyErr_Occurred())
1123		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1124}
1125
1126/*
1127 * Dummy, to avoid dragging all the test_attr infrastructure in the python
1128 * binding.
1129 */
1130void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
1131                     int fd, int group_fd, unsigned long flags)
1132{
1133}
1134