xref: /linux/tools/perf/util/python.c (revision cfff2d909cbdaf8c467bd321aa0502a548ec8f7e)
1877108e4SArnaldo Carvalho de Melo #include <Python.h>
2877108e4SArnaldo Carvalho de Melo #include <structmember.h>
3877108e4SArnaldo Carvalho de Melo #include <inttypes.h>
4877108e4SArnaldo Carvalho de Melo #include <poll.h>
5877108e4SArnaldo Carvalho de Melo #include "evlist.h"
6877108e4SArnaldo Carvalho de Melo #include "evsel.h"
7877108e4SArnaldo Carvalho de Melo #include "event.h"
8877108e4SArnaldo Carvalho de Melo #include "cpumap.h"
9877108e4SArnaldo Carvalho de Melo #include "thread_map.h"
10877108e4SArnaldo Carvalho de Melo 
11*cfff2d90SFrederic Weisbecker /* Define PyVarObject_HEAD_INIT for python 2.5 */
12*cfff2d90SFrederic Weisbecker #ifndef PyVarObject_HEAD_INIT
13*cfff2d90SFrederic Weisbecker # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
14*cfff2d90SFrederic Weisbecker #endif
15*cfff2d90SFrederic Weisbecker 
16877108e4SArnaldo Carvalho de Melo struct throttle_event {
17877108e4SArnaldo Carvalho de Melo 	struct perf_event_header header;
18877108e4SArnaldo Carvalho de Melo 	u64			 time;
19877108e4SArnaldo Carvalho de Melo 	u64			 id;
20877108e4SArnaldo Carvalho de Melo 	u64			 stream_id;
21877108e4SArnaldo Carvalho de Melo };
22877108e4SArnaldo Carvalho de Melo 
23f6bbc1daSArnaldo Carvalho de Melo PyMODINIT_FUNC initperf(void);
24f6bbc1daSArnaldo Carvalho de Melo 
25877108e4SArnaldo Carvalho de Melo #define member_def(type, member, ptype, help) \
26877108e4SArnaldo Carvalho de Melo 	{ #member, ptype, \
27877108e4SArnaldo Carvalho de Melo 	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
28877108e4SArnaldo Carvalho de Melo 	  0, help }
29877108e4SArnaldo Carvalho de Melo 
30877108e4SArnaldo Carvalho de Melo #define sample_member_def(name, member, ptype, help) \
31877108e4SArnaldo Carvalho de Melo 	{ #name, ptype, \
32877108e4SArnaldo Carvalho de Melo 	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
33877108e4SArnaldo Carvalho de Melo 	  0, help }
34877108e4SArnaldo Carvalho de Melo 
35877108e4SArnaldo Carvalho de Melo struct pyrf_event {
36877108e4SArnaldo Carvalho de Melo 	PyObject_HEAD
37877108e4SArnaldo Carvalho de Melo 	struct perf_sample sample;
38877108e4SArnaldo Carvalho de Melo 	union perf_event   event;
39877108e4SArnaldo Carvalho de Melo };
40877108e4SArnaldo Carvalho de Melo 
41877108e4SArnaldo Carvalho de Melo #define sample_members \
42f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
43877108e4SArnaldo Carvalho de Melo 	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
44877108e4SArnaldo Carvalho de Melo 	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
45f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
46f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
47f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
48f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
49f6bbc1daSArnaldo Carvalho de Melo 	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
50877108e4SArnaldo Carvalho de Melo 	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
51877108e4SArnaldo Carvalho de Melo 
52877108e4SArnaldo Carvalho de Melo static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
53877108e4SArnaldo Carvalho de Melo 
54877108e4SArnaldo Carvalho de Melo static PyMemberDef pyrf_mmap_event__members[] = {
55877108e4SArnaldo Carvalho de Melo 	sample_members
56877108e4SArnaldo Carvalho de Melo 	member_def(perf_event_header, type, T_UINT, "event type"),
57877108e4SArnaldo Carvalho de Melo 	member_def(mmap_event, pid, T_UINT, "event pid"),
58877108e4SArnaldo Carvalho de Melo 	member_def(mmap_event, tid, T_UINT, "event tid"),
59f6bbc1daSArnaldo Carvalho de Melo 	member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
60f6bbc1daSArnaldo Carvalho de Melo 	member_def(mmap_event, len, T_ULONGLONG, "map length"),
61f6bbc1daSArnaldo Carvalho de Melo 	member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
62877108e4SArnaldo Carvalho de Melo 	member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
63f6bbc1daSArnaldo Carvalho de Melo 	{ .name = NULL, },
64877108e4SArnaldo Carvalho de Melo };
65877108e4SArnaldo Carvalho de Melo 
66877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
67877108e4SArnaldo Carvalho de Melo {
68877108e4SArnaldo Carvalho de Melo 	PyObject *ret;
69877108e4SArnaldo Carvalho de Melo 	char *s;
70877108e4SArnaldo Carvalho de Melo 
71877108e4SArnaldo Carvalho de Melo 	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
72877108e4SArnaldo Carvalho de Melo 			 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
73877108e4SArnaldo Carvalho de Melo 			 "filename: %s }",
74877108e4SArnaldo Carvalho de Melo 		     pevent->event.mmap.pid, pevent->event.mmap.tid,
75877108e4SArnaldo Carvalho de Melo 		     pevent->event.mmap.start, pevent->event.mmap.len,
76877108e4SArnaldo Carvalho de Melo 		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
77877108e4SArnaldo Carvalho de Melo 		ret = PyErr_NoMemory();
78877108e4SArnaldo Carvalho de Melo 	} else {
79877108e4SArnaldo Carvalho de Melo 		ret = PyString_FromString(s);
80877108e4SArnaldo Carvalho de Melo 		free(s);
81877108e4SArnaldo Carvalho de Melo 	}
82877108e4SArnaldo Carvalho de Melo 	return ret;
83877108e4SArnaldo Carvalho de Melo }
84877108e4SArnaldo Carvalho de Melo 
85877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_mmap_event__type = {
86877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
87877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.mmap_event",
88877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_event),
89877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
90877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_mmap_event__doc,
91877108e4SArnaldo Carvalho de Melo 	.tp_members	= pyrf_mmap_event__members,
92877108e4SArnaldo Carvalho de Melo 	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
93877108e4SArnaldo Carvalho de Melo };
94877108e4SArnaldo Carvalho de Melo 
95877108e4SArnaldo Carvalho de Melo static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
96877108e4SArnaldo Carvalho de Melo 
97877108e4SArnaldo Carvalho de Melo static PyMemberDef pyrf_task_event__members[] = {
98877108e4SArnaldo Carvalho de Melo 	sample_members
99877108e4SArnaldo Carvalho de Melo 	member_def(perf_event_header, type, T_UINT, "event type"),
100877108e4SArnaldo Carvalho de Melo 	member_def(fork_event, pid, T_UINT, "event pid"),
101877108e4SArnaldo Carvalho de Melo 	member_def(fork_event, ppid, T_UINT, "event ppid"),
102877108e4SArnaldo Carvalho de Melo 	member_def(fork_event, tid, T_UINT, "event tid"),
103877108e4SArnaldo Carvalho de Melo 	member_def(fork_event, ptid, T_UINT, "event ptid"),
104f6bbc1daSArnaldo Carvalho de Melo 	member_def(fork_event, time, T_ULONGLONG, "timestamp"),
105f6bbc1daSArnaldo Carvalho de Melo 	{ .name = NULL, },
106877108e4SArnaldo Carvalho de Melo };
107877108e4SArnaldo Carvalho de Melo 
108877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
109877108e4SArnaldo Carvalho de Melo {
110877108e4SArnaldo Carvalho de Melo 	return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
111877108e4SArnaldo Carvalho de Melo 				   "ptid: %u, time: %" PRIu64 "}",
112877108e4SArnaldo Carvalho de Melo 				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
113877108e4SArnaldo Carvalho de Melo 				   pevent->event.fork.pid,
114877108e4SArnaldo Carvalho de Melo 				   pevent->event.fork.ppid,
115877108e4SArnaldo Carvalho de Melo 				   pevent->event.fork.tid,
116877108e4SArnaldo Carvalho de Melo 				   pevent->event.fork.ptid,
117877108e4SArnaldo Carvalho de Melo 				   pevent->event.fork.time);
118877108e4SArnaldo Carvalho de Melo }
119877108e4SArnaldo Carvalho de Melo 
120877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_task_event__type = {
121877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
122877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.task_event",
123877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_event),
124877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
125877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_task_event__doc,
126877108e4SArnaldo Carvalho de Melo 	.tp_members	= pyrf_task_event__members,
127877108e4SArnaldo Carvalho de Melo 	.tp_repr	= (reprfunc)pyrf_task_event__repr,
128877108e4SArnaldo Carvalho de Melo };
129877108e4SArnaldo Carvalho de Melo 
130877108e4SArnaldo Carvalho de Melo static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
131877108e4SArnaldo Carvalho de Melo 
132877108e4SArnaldo Carvalho de Melo static PyMemberDef pyrf_comm_event__members[] = {
133877108e4SArnaldo Carvalho de Melo 	sample_members
134877108e4SArnaldo Carvalho de Melo 	member_def(perf_event_header, type, T_UINT, "event type"),
135877108e4SArnaldo Carvalho de Melo 	member_def(comm_event, pid, T_UINT, "event pid"),
136877108e4SArnaldo Carvalho de Melo 	member_def(comm_event, tid, T_UINT, "event tid"),
137877108e4SArnaldo Carvalho de Melo 	member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
138f6bbc1daSArnaldo Carvalho de Melo 	{ .name = NULL, },
139877108e4SArnaldo Carvalho de Melo };
140877108e4SArnaldo Carvalho de Melo 
141877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
142877108e4SArnaldo Carvalho de Melo {
143877108e4SArnaldo Carvalho de Melo 	return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
144877108e4SArnaldo Carvalho de Melo 				   pevent->event.comm.pid,
145877108e4SArnaldo Carvalho de Melo 				   pevent->event.comm.tid,
146877108e4SArnaldo Carvalho de Melo 				   pevent->event.comm.comm);
147877108e4SArnaldo Carvalho de Melo }
148877108e4SArnaldo Carvalho de Melo 
149877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_comm_event__type = {
150877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
151877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.comm_event",
152877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_event),
153877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
154877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_comm_event__doc,
155877108e4SArnaldo Carvalho de Melo 	.tp_members	= pyrf_comm_event__members,
156877108e4SArnaldo Carvalho de Melo 	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
157877108e4SArnaldo Carvalho de Melo };
158877108e4SArnaldo Carvalho de Melo 
159877108e4SArnaldo Carvalho de Melo static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
160877108e4SArnaldo Carvalho de Melo 
161877108e4SArnaldo Carvalho de Melo static PyMemberDef pyrf_throttle_event__members[] = {
162877108e4SArnaldo Carvalho de Melo 	sample_members
163877108e4SArnaldo Carvalho de Melo 	member_def(perf_event_header, type, T_UINT, "event type"),
164f6bbc1daSArnaldo Carvalho de Melo 	member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
165f6bbc1daSArnaldo Carvalho de Melo 	member_def(throttle_event, id, T_ULONGLONG, "event id"),
166f6bbc1daSArnaldo Carvalho de Melo 	member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
167f6bbc1daSArnaldo Carvalho de Melo 	{ .name = NULL, },
168877108e4SArnaldo Carvalho de Melo };
169877108e4SArnaldo Carvalho de Melo 
170877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
171877108e4SArnaldo Carvalho de Melo {
172877108e4SArnaldo Carvalho de Melo 	struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
173877108e4SArnaldo Carvalho de Melo 
174877108e4SArnaldo Carvalho de Melo 	return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
175877108e4SArnaldo Carvalho de Melo 				   ", stream_id: %" PRIu64 " }",
176877108e4SArnaldo Carvalho de Melo 				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
177877108e4SArnaldo Carvalho de Melo 				   te->time, te->id, te->stream_id);
178877108e4SArnaldo Carvalho de Melo }
179877108e4SArnaldo Carvalho de Melo 
180877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_throttle_event__type = {
181877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
182877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.throttle_event",
183877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_event),
184877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
185877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_throttle_event__doc,
186877108e4SArnaldo Carvalho de Melo 	.tp_members	= pyrf_throttle_event__members,
187877108e4SArnaldo Carvalho de Melo 	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
188877108e4SArnaldo Carvalho de Melo };
189877108e4SArnaldo Carvalho de Melo 
190877108e4SArnaldo Carvalho de Melo static int pyrf_event__setup_types(void)
191877108e4SArnaldo Carvalho de Melo {
192877108e4SArnaldo Carvalho de Melo 	int err;
193877108e4SArnaldo Carvalho de Melo 	pyrf_mmap_event__type.tp_new =
194877108e4SArnaldo Carvalho de Melo 	pyrf_task_event__type.tp_new =
195877108e4SArnaldo Carvalho de Melo 	pyrf_comm_event__type.tp_new =
196877108e4SArnaldo Carvalho de Melo 	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
197877108e4SArnaldo Carvalho de Melo 	err = PyType_Ready(&pyrf_mmap_event__type);
198877108e4SArnaldo Carvalho de Melo 	if (err < 0)
199877108e4SArnaldo Carvalho de Melo 		goto out;
200877108e4SArnaldo Carvalho de Melo 	err = PyType_Ready(&pyrf_task_event__type);
201877108e4SArnaldo Carvalho de Melo 	if (err < 0)
202877108e4SArnaldo Carvalho de Melo 		goto out;
203877108e4SArnaldo Carvalho de Melo 	err = PyType_Ready(&pyrf_comm_event__type);
204877108e4SArnaldo Carvalho de Melo 	if (err < 0)
205877108e4SArnaldo Carvalho de Melo 		goto out;
206877108e4SArnaldo Carvalho de Melo 	err = PyType_Ready(&pyrf_throttle_event__type);
207877108e4SArnaldo Carvalho de Melo 	if (err < 0)
208877108e4SArnaldo Carvalho de Melo 		goto out;
209877108e4SArnaldo Carvalho de Melo out:
210877108e4SArnaldo Carvalho de Melo 	return err;
211877108e4SArnaldo Carvalho de Melo }
212877108e4SArnaldo Carvalho de Melo 
213877108e4SArnaldo Carvalho de Melo static PyTypeObject *pyrf_event__type[] = {
214877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
215877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_LOST]	 = &pyrf_mmap_event__type,
216877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
217877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
218877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
219877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
220877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
221877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_READ]	 = &pyrf_mmap_event__type,
222877108e4SArnaldo Carvalho de Melo 	[PERF_RECORD_SAMPLE]	 = &pyrf_mmap_event__type,
223877108e4SArnaldo Carvalho de Melo };
224877108e4SArnaldo Carvalho de Melo 
225877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_event__new(union perf_event *event)
226877108e4SArnaldo Carvalho de Melo {
227877108e4SArnaldo Carvalho de Melo 	struct pyrf_event *pevent;
228877108e4SArnaldo Carvalho de Melo 	PyTypeObject *ptype;
229877108e4SArnaldo Carvalho de Melo 
230877108e4SArnaldo Carvalho de Melo 	if (event->header.type < PERF_RECORD_MMAP ||
231877108e4SArnaldo Carvalho de Melo 	    event->header.type > PERF_RECORD_SAMPLE)
232877108e4SArnaldo Carvalho de Melo 		return NULL;
233877108e4SArnaldo Carvalho de Melo 
234877108e4SArnaldo Carvalho de Melo 	ptype = pyrf_event__type[event->header.type];
235877108e4SArnaldo Carvalho de Melo 	pevent = PyObject_New(struct pyrf_event, ptype);
236877108e4SArnaldo Carvalho de Melo 	if (pevent != NULL)
237877108e4SArnaldo Carvalho de Melo 		memcpy(&pevent->event, event, event->header.size);
238877108e4SArnaldo Carvalho de Melo 	return (PyObject *)pevent;
239877108e4SArnaldo Carvalho de Melo }
240877108e4SArnaldo Carvalho de Melo 
241877108e4SArnaldo Carvalho de Melo struct pyrf_cpu_map {
242877108e4SArnaldo Carvalho de Melo 	PyObject_HEAD
243877108e4SArnaldo Carvalho de Melo 
244877108e4SArnaldo Carvalho de Melo 	struct cpu_map *cpus;
245877108e4SArnaldo Carvalho de Melo };
246877108e4SArnaldo Carvalho de Melo 
247877108e4SArnaldo Carvalho de Melo static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
248877108e4SArnaldo Carvalho de Melo 			      PyObject *args, PyObject *kwargs)
249877108e4SArnaldo Carvalho de Melo {
250877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = { "cpustr", NULL, NULL, };
251877108e4SArnaldo Carvalho de Melo 	char *cpustr = NULL;
252877108e4SArnaldo Carvalho de Melo 
253877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
254877108e4SArnaldo Carvalho de Melo 					 kwlist, &cpustr))
255877108e4SArnaldo Carvalho de Melo 		return -1;
256877108e4SArnaldo Carvalho de Melo 
257877108e4SArnaldo Carvalho de Melo 	pcpus->cpus = cpu_map__new(cpustr);
258877108e4SArnaldo Carvalho de Melo 	if (pcpus->cpus == NULL)
259877108e4SArnaldo Carvalho de Melo 		return -1;
260877108e4SArnaldo Carvalho de Melo 	return 0;
261877108e4SArnaldo Carvalho de Melo }
262877108e4SArnaldo Carvalho de Melo 
263877108e4SArnaldo Carvalho de Melo static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
264877108e4SArnaldo Carvalho de Melo {
265877108e4SArnaldo Carvalho de Melo 	cpu_map__delete(pcpus->cpus);
266877108e4SArnaldo Carvalho de Melo 	pcpus->ob_type->tp_free((PyObject*)pcpus);
267877108e4SArnaldo Carvalho de Melo }
268877108e4SArnaldo Carvalho de Melo 
269877108e4SArnaldo Carvalho de Melo static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
270877108e4SArnaldo Carvalho de Melo {
271877108e4SArnaldo Carvalho de Melo 	struct pyrf_cpu_map *pcpus = (void *)obj;
272877108e4SArnaldo Carvalho de Melo 
273877108e4SArnaldo Carvalho de Melo 	return pcpus->cpus->nr;
274877108e4SArnaldo Carvalho de Melo }
275877108e4SArnaldo Carvalho de Melo 
276877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
277877108e4SArnaldo Carvalho de Melo {
278877108e4SArnaldo Carvalho de Melo 	struct pyrf_cpu_map *pcpus = (void *)obj;
279877108e4SArnaldo Carvalho de Melo 
280877108e4SArnaldo Carvalho de Melo 	if (i >= pcpus->cpus->nr)
281877108e4SArnaldo Carvalho de Melo 		return NULL;
282877108e4SArnaldo Carvalho de Melo 
283877108e4SArnaldo Carvalho de Melo 	return Py_BuildValue("i", pcpus->cpus->map[i]);
284877108e4SArnaldo Carvalho de Melo }
285877108e4SArnaldo Carvalho de Melo 
286877108e4SArnaldo Carvalho de Melo static PySequenceMethods pyrf_cpu_map__sequence_methods = {
287877108e4SArnaldo Carvalho de Melo 	.sq_length = pyrf_cpu_map__length,
288877108e4SArnaldo Carvalho de Melo 	.sq_item   = pyrf_cpu_map__item,
289877108e4SArnaldo Carvalho de Melo };
290877108e4SArnaldo Carvalho de Melo 
291877108e4SArnaldo Carvalho de Melo static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
292877108e4SArnaldo Carvalho de Melo 
293877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_cpu_map__type = {
294877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
295877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.cpu_map",
296877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
297877108e4SArnaldo Carvalho de Melo 	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
298877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
299877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_cpu_map__doc,
300877108e4SArnaldo Carvalho de Melo 	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
301877108e4SArnaldo Carvalho de Melo 	.tp_init	= (initproc)pyrf_cpu_map__init,
302877108e4SArnaldo Carvalho de Melo };
303877108e4SArnaldo Carvalho de Melo 
304877108e4SArnaldo Carvalho de Melo static int pyrf_cpu_map__setup_types(void)
305877108e4SArnaldo Carvalho de Melo {
306877108e4SArnaldo Carvalho de Melo 	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
307877108e4SArnaldo Carvalho de Melo 	return PyType_Ready(&pyrf_cpu_map__type);
308877108e4SArnaldo Carvalho de Melo }
309877108e4SArnaldo Carvalho de Melo 
310877108e4SArnaldo Carvalho de Melo struct pyrf_thread_map {
311877108e4SArnaldo Carvalho de Melo 	PyObject_HEAD
312877108e4SArnaldo Carvalho de Melo 
313877108e4SArnaldo Carvalho de Melo 	struct thread_map *threads;
314877108e4SArnaldo Carvalho de Melo };
315877108e4SArnaldo Carvalho de Melo 
316877108e4SArnaldo Carvalho de Melo static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
317877108e4SArnaldo Carvalho de Melo 				 PyObject *args, PyObject *kwargs)
318877108e4SArnaldo Carvalho de Melo {
319877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = { "pid", "tid", NULL, NULL, };
320877108e4SArnaldo Carvalho de Melo 	int pid = -1, tid = -1;
321877108e4SArnaldo Carvalho de Melo 
322877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
323877108e4SArnaldo Carvalho de Melo 					 kwlist, &pid, &tid))
324877108e4SArnaldo Carvalho de Melo 		return -1;
325877108e4SArnaldo Carvalho de Melo 
326877108e4SArnaldo Carvalho de Melo 	pthreads->threads = thread_map__new(pid, tid);
327877108e4SArnaldo Carvalho de Melo 	if (pthreads->threads == NULL)
328877108e4SArnaldo Carvalho de Melo 		return -1;
329877108e4SArnaldo Carvalho de Melo 	return 0;
330877108e4SArnaldo Carvalho de Melo }
331877108e4SArnaldo Carvalho de Melo 
332877108e4SArnaldo Carvalho de Melo static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
333877108e4SArnaldo Carvalho de Melo {
334877108e4SArnaldo Carvalho de Melo 	thread_map__delete(pthreads->threads);
335877108e4SArnaldo Carvalho de Melo 	pthreads->ob_type->tp_free((PyObject*)pthreads);
336877108e4SArnaldo Carvalho de Melo }
337877108e4SArnaldo Carvalho de Melo 
338877108e4SArnaldo Carvalho de Melo static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
339877108e4SArnaldo Carvalho de Melo {
340877108e4SArnaldo Carvalho de Melo 	struct pyrf_thread_map *pthreads = (void *)obj;
341877108e4SArnaldo Carvalho de Melo 
342877108e4SArnaldo Carvalho de Melo 	return pthreads->threads->nr;
343877108e4SArnaldo Carvalho de Melo }
344877108e4SArnaldo Carvalho de Melo 
345877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
346877108e4SArnaldo Carvalho de Melo {
347877108e4SArnaldo Carvalho de Melo 	struct pyrf_thread_map *pthreads = (void *)obj;
348877108e4SArnaldo Carvalho de Melo 
349877108e4SArnaldo Carvalho de Melo 	if (i >= pthreads->threads->nr)
350877108e4SArnaldo Carvalho de Melo 		return NULL;
351877108e4SArnaldo Carvalho de Melo 
352877108e4SArnaldo Carvalho de Melo 	return Py_BuildValue("i", pthreads->threads->map[i]);
353877108e4SArnaldo Carvalho de Melo }
354877108e4SArnaldo Carvalho de Melo 
355877108e4SArnaldo Carvalho de Melo static PySequenceMethods pyrf_thread_map__sequence_methods = {
356877108e4SArnaldo Carvalho de Melo 	.sq_length = pyrf_thread_map__length,
357877108e4SArnaldo Carvalho de Melo 	.sq_item   = pyrf_thread_map__item,
358877108e4SArnaldo Carvalho de Melo };
359877108e4SArnaldo Carvalho de Melo 
360877108e4SArnaldo Carvalho de Melo static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
361877108e4SArnaldo Carvalho de Melo 
362877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_thread_map__type = {
363877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
364877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.thread_map",
365877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_thread_map),
366877108e4SArnaldo Carvalho de Melo 	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
367877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
368877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_thread_map__doc,
369877108e4SArnaldo Carvalho de Melo 	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
370877108e4SArnaldo Carvalho de Melo 	.tp_init	= (initproc)pyrf_thread_map__init,
371877108e4SArnaldo Carvalho de Melo };
372877108e4SArnaldo Carvalho de Melo 
373877108e4SArnaldo Carvalho de Melo static int pyrf_thread_map__setup_types(void)
374877108e4SArnaldo Carvalho de Melo {
375877108e4SArnaldo Carvalho de Melo 	pyrf_thread_map__type.tp_new = PyType_GenericNew;
376877108e4SArnaldo Carvalho de Melo 	return PyType_Ready(&pyrf_thread_map__type);
377877108e4SArnaldo Carvalho de Melo }
378877108e4SArnaldo Carvalho de Melo 
379877108e4SArnaldo Carvalho de Melo struct pyrf_evsel {
380877108e4SArnaldo Carvalho de Melo 	PyObject_HEAD
381877108e4SArnaldo Carvalho de Melo 
382877108e4SArnaldo Carvalho de Melo 	struct perf_evsel evsel;
383877108e4SArnaldo Carvalho de Melo };
384877108e4SArnaldo Carvalho de Melo 
385877108e4SArnaldo Carvalho de Melo static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
386877108e4SArnaldo Carvalho de Melo 			    PyObject *args, PyObject *kwargs)
387877108e4SArnaldo Carvalho de Melo {
388877108e4SArnaldo Carvalho de Melo 	struct perf_event_attr attr = {
389877108e4SArnaldo Carvalho de Melo 		.type = PERF_TYPE_HARDWARE,
390877108e4SArnaldo Carvalho de Melo 		.config = PERF_COUNT_HW_CPU_CYCLES,
391877108e4SArnaldo Carvalho de Melo 		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
392877108e4SArnaldo Carvalho de Melo 	};
393877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = {
394877108e4SArnaldo Carvalho de Melo 		"type",
395877108e4SArnaldo Carvalho de Melo 		"config",
396877108e4SArnaldo Carvalho de Melo 		"sample_freq",
397877108e4SArnaldo Carvalho de Melo 		"sample_period",
398877108e4SArnaldo Carvalho de Melo 		"sample_type",
399877108e4SArnaldo Carvalho de Melo 		"read_format",
400877108e4SArnaldo Carvalho de Melo 		"disabled",
401877108e4SArnaldo Carvalho de Melo 		"inherit",
402877108e4SArnaldo Carvalho de Melo 		"pinned",
403877108e4SArnaldo Carvalho de Melo 		"exclusive",
404877108e4SArnaldo Carvalho de Melo 		"exclude_user",
405877108e4SArnaldo Carvalho de Melo 		"exclude_kernel",
406877108e4SArnaldo Carvalho de Melo 		"exclude_hv",
407877108e4SArnaldo Carvalho de Melo 		"exclude_idle",
408877108e4SArnaldo Carvalho de Melo 		"mmap",
409877108e4SArnaldo Carvalho de Melo 		"comm",
410877108e4SArnaldo Carvalho de Melo 		"freq",
411877108e4SArnaldo Carvalho de Melo 		"inherit_stat",
412877108e4SArnaldo Carvalho de Melo 		"enable_on_exec",
413877108e4SArnaldo Carvalho de Melo 		"task",
414877108e4SArnaldo Carvalho de Melo 		"watermark",
415877108e4SArnaldo Carvalho de Melo 		"precise_ip",
416877108e4SArnaldo Carvalho de Melo 		"mmap_data",
417877108e4SArnaldo Carvalho de Melo 		"sample_id_all",
418877108e4SArnaldo Carvalho de Melo 		"wakeup_events",
419877108e4SArnaldo Carvalho de Melo 		"bp_type",
420877108e4SArnaldo Carvalho de Melo 		"bp_addr",
421877108e4SArnaldo Carvalho de Melo 		"bp_len", NULL, NULL, };
422877108e4SArnaldo Carvalho de Melo 	u64 sample_period = 0;
423877108e4SArnaldo Carvalho de Melo 	u32 disabled = 0,
424877108e4SArnaldo Carvalho de Melo 	    inherit = 0,
425877108e4SArnaldo Carvalho de Melo 	    pinned = 0,
426877108e4SArnaldo Carvalho de Melo 	    exclusive = 0,
427877108e4SArnaldo Carvalho de Melo 	    exclude_user = 0,
428877108e4SArnaldo Carvalho de Melo 	    exclude_kernel = 0,
429877108e4SArnaldo Carvalho de Melo 	    exclude_hv = 0,
430877108e4SArnaldo Carvalho de Melo 	    exclude_idle = 0,
431877108e4SArnaldo Carvalho de Melo 	    mmap = 0,
432877108e4SArnaldo Carvalho de Melo 	    comm = 0,
433877108e4SArnaldo Carvalho de Melo 	    freq = 1,
434877108e4SArnaldo Carvalho de Melo 	    inherit_stat = 0,
435877108e4SArnaldo Carvalho de Melo 	    enable_on_exec = 0,
436877108e4SArnaldo Carvalho de Melo 	    task = 0,
437877108e4SArnaldo Carvalho de Melo 	    watermark = 0,
438877108e4SArnaldo Carvalho de Melo 	    precise_ip = 0,
439877108e4SArnaldo Carvalho de Melo 	    mmap_data = 0,
440877108e4SArnaldo Carvalho de Melo 	    sample_id_all = 1;
441877108e4SArnaldo Carvalho de Melo 	int idx = 0;
442877108e4SArnaldo Carvalho de Melo 
443877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
444877108e4SArnaldo Carvalho de Melo 					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
445877108e4SArnaldo Carvalho de Melo 					 &attr.type, &attr.config, &attr.sample_freq,
446877108e4SArnaldo Carvalho de Melo 					 &sample_period, &attr.sample_type,
447877108e4SArnaldo Carvalho de Melo 					 &attr.read_format, &disabled, &inherit,
448877108e4SArnaldo Carvalho de Melo 					 &pinned, &exclusive, &exclude_user,
449877108e4SArnaldo Carvalho de Melo 					 &exclude_kernel, &exclude_hv, &exclude_idle,
450877108e4SArnaldo Carvalho de Melo 					 &mmap, &comm, &freq, &inherit_stat,
451877108e4SArnaldo Carvalho de Melo 					 &enable_on_exec, &task, &watermark,
452877108e4SArnaldo Carvalho de Melo 					 &precise_ip, &mmap_data, &sample_id_all,
453877108e4SArnaldo Carvalho de Melo 					 &attr.wakeup_events, &attr.bp_type,
454877108e4SArnaldo Carvalho de Melo 					 &attr.bp_addr, &attr.bp_len, &idx))
455877108e4SArnaldo Carvalho de Melo 		return -1;
456877108e4SArnaldo Carvalho de Melo 
457877108e4SArnaldo Carvalho de Melo 	/* union... */
458877108e4SArnaldo Carvalho de Melo 	if (sample_period != 0) {
459877108e4SArnaldo Carvalho de Melo 		if (attr.sample_freq != 0)
460877108e4SArnaldo Carvalho de Melo 			return -1; /* FIXME: throw right exception */
461877108e4SArnaldo Carvalho de Melo 		attr.sample_period = sample_period;
462877108e4SArnaldo Carvalho de Melo 	}
463877108e4SArnaldo Carvalho de Melo 
464877108e4SArnaldo Carvalho de Melo 	/* Bitfields */
465877108e4SArnaldo Carvalho de Melo 	attr.disabled	    = disabled;
466877108e4SArnaldo Carvalho de Melo 	attr.inherit	    = inherit;
467877108e4SArnaldo Carvalho de Melo 	attr.pinned	    = pinned;
468877108e4SArnaldo Carvalho de Melo 	attr.exclusive	    = exclusive;
469877108e4SArnaldo Carvalho de Melo 	attr.exclude_user   = exclude_user;
470877108e4SArnaldo Carvalho de Melo 	attr.exclude_kernel = exclude_kernel;
471877108e4SArnaldo Carvalho de Melo 	attr.exclude_hv	    = exclude_hv;
472877108e4SArnaldo Carvalho de Melo 	attr.exclude_idle   = exclude_idle;
473877108e4SArnaldo Carvalho de Melo 	attr.mmap	    = mmap;
474877108e4SArnaldo Carvalho de Melo 	attr.comm	    = comm;
475877108e4SArnaldo Carvalho de Melo 	attr.freq	    = freq;
476877108e4SArnaldo Carvalho de Melo 	attr.inherit_stat   = inherit_stat;
477877108e4SArnaldo Carvalho de Melo 	attr.enable_on_exec = enable_on_exec;
478877108e4SArnaldo Carvalho de Melo 	attr.task	    = task;
479877108e4SArnaldo Carvalho de Melo 	attr.watermark	    = watermark;
480877108e4SArnaldo Carvalho de Melo 	attr.precise_ip	    = precise_ip;
481877108e4SArnaldo Carvalho de Melo 	attr.mmap_data	    = mmap_data;
482877108e4SArnaldo Carvalho de Melo 	attr.sample_id_all  = sample_id_all;
483877108e4SArnaldo Carvalho de Melo 
484877108e4SArnaldo Carvalho de Melo 	perf_evsel__init(&pevsel->evsel, &attr, idx);
485877108e4SArnaldo Carvalho de Melo 	return 0;
486877108e4SArnaldo Carvalho de Melo }
487877108e4SArnaldo Carvalho de Melo 
488877108e4SArnaldo Carvalho de Melo static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
489877108e4SArnaldo Carvalho de Melo {
490877108e4SArnaldo Carvalho de Melo 	perf_evsel__exit(&pevsel->evsel);
491877108e4SArnaldo Carvalho de Melo 	pevsel->ob_type->tp_free((PyObject*)pevsel);
492877108e4SArnaldo Carvalho de Melo }
493877108e4SArnaldo Carvalho de Melo 
494877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
495877108e4SArnaldo Carvalho de Melo 				  PyObject *args, PyObject *kwargs)
496877108e4SArnaldo Carvalho de Melo {
497877108e4SArnaldo Carvalho de Melo 	struct perf_evsel *evsel = &pevsel->evsel;
498877108e4SArnaldo Carvalho de Melo 	struct cpu_map *cpus = NULL;
499877108e4SArnaldo Carvalho de Melo 	struct thread_map *threads = NULL;
500877108e4SArnaldo Carvalho de Melo 	PyObject *pcpus = NULL, *pthreads = NULL;
501877108e4SArnaldo Carvalho de Melo 	int group = 0, overwrite = 0;
502877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = {"cpus", "threads", "group", "overwrite", NULL, NULL};
503877108e4SArnaldo Carvalho de Melo 
504877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
505877108e4SArnaldo Carvalho de Melo 					 &pcpus, &pthreads, &group, &overwrite))
506877108e4SArnaldo Carvalho de Melo 		return NULL;
507877108e4SArnaldo Carvalho de Melo 
508877108e4SArnaldo Carvalho de Melo 	if (pthreads != NULL)
509877108e4SArnaldo Carvalho de Melo 		threads = ((struct pyrf_thread_map *)pthreads)->threads;
510877108e4SArnaldo Carvalho de Melo 
511877108e4SArnaldo Carvalho de Melo 	if (pcpus != NULL)
512877108e4SArnaldo Carvalho de Melo 		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
513877108e4SArnaldo Carvalho de Melo 
514877108e4SArnaldo Carvalho de Melo 	if (perf_evsel__open(evsel, cpus, threads, group, overwrite) < 0) {
515877108e4SArnaldo Carvalho de Melo 		PyErr_SetFromErrno(PyExc_OSError);
516877108e4SArnaldo Carvalho de Melo 		return NULL;
517877108e4SArnaldo Carvalho de Melo 	}
518877108e4SArnaldo Carvalho de Melo 
519877108e4SArnaldo Carvalho de Melo 	Py_INCREF(Py_None);
520877108e4SArnaldo Carvalho de Melo 	return Py_None;
521877108e4SArnaldo Carvalho de Melo }
522877108e4SArnaldo Carvalho de Melo 
523877108e4SArnaldo Carvalho de Melo static PyMethodDef pyrf_evsel__methods[] = {
524877108e4SArnaldo Carvalho de Melo 	{
525877108e4SArnaldo Carvalho de Melo 		.ml_name  = "open",
526877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evsel__open,
527877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
528877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
529877108e4SArnaldo Carvalho de Melo 	},
530f6bbc1daSArnaldo Carvalho de Melo 	{ .ml_name = NULL, }
531877108e4SArnaldo Carvalho de Melo };
532877108e4SArnaldo Carvalho de Melo 
533877108e4SArnaldo Carvalho de Melo static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
534877108e4SArnaldo Carvalho de Melo 
535877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_evsel__type = {
536877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
537877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.evsel",
538877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_evsel),
539877108e4SArnaldo Carvalho de Melo 	.tp_dealloc	= (destructor)pyrf_evsel__delete,
540877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
541877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_evsel__doc,
542877108e4SArnaldo Carvalho de Melo 	.tp_methods	= pyrf_evsel__methods,
543877108e4SArnaldo Carvalho de Melo 	.tp_init	= (initproc)pyrf_evsel__init,
544877108e4SArnaldo Carvalho de Melo };
545877108e4SArnaldo Carvalho de Melo 
546877108e4SArnaldo Carvalho de Melo static int pyrf_evsel__setup_types(void)
547877108e4SArnaldo Carvalho de Melo {
548877108e4SArnaldo Carvalho de Melo 	pyrf_evsel__type.tp_new = PyType_GenericNew;
549877108e4SArnaldo Carvalho de Melo 	return PyType_Ready(&pyrf_evsel__type);
550877108e4SArnaldo Carvalho de Melo }
551877108e4SArnaldo Carvalho de Melo 
552877108e4SArnaldo Carvalho de Melo struct pyrf_evlist {
553877108e4SArnaldo Carvalho de Melo 	PyObject_HEAD
554877108e4SArnaldo Carvalho de Melo 
555877108e4SArnaldo Carvalho de Melo 	struct perf_evlist evlist;
556877108e4SArnaldo Carvalho de Melo };
557877108e4SArnaldo Carvalho de Melo 
558877108e4SArnaldo Carvalho de Melo static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
559f6bbc1daSArnaldo Carvalho de Melo 			     PyObject *args, PyObject *kwargs __used)
560877108e4SArnaldo Carvalho de Melo {
5617e2ed097SArnaldo Carvalho de Melo 	PyObject *pcpus = NULL, *pthreads = NULL;
5627e2ed097SArnaldo Carvalho de Melo 	struct cpu_map *cpus;
5637e2ed097SArnaldo Carvalho de Melo 	struct thread_map *threads;
5647e2ed097SArnaldo Carvalho de Melo 
5657e2ed097SArnaldo Carvalho de Melo 	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
5667e2ed097SArnaldo Carvalho de Melo 		return -1;
5677e2ed097SArnaldo Carvalho de Melo 
5687e2ed097SArnaldo Carvalho de Melo 	threads = ((struct pyrf_thread_map *)pthreads)->threads;
5697e2ed097SArnaldo Carvalho de Melo 	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
5707e2ed097SArnaldo Carvalho de Melo 	perf_evlist__init(&pevlist->evlist, cpus, threads);
571877108e4SArnaldo Carvalho de Melo 	return 0;
572877108e4SArnaldo Carvalho de Melo }
573877108e4SArnaldo Carvalho de Melo 
574877108e4SArnaldo Carvalho de Melo static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
575877108e4SArnaldo Carvalho de Melo {
576877108e4SArnaldo Carvalho de Melo 	perf_evlist__exit(&pevlist->evlist);
577877108e4SArnaldo Carvalho de Melo 	pevlist->ob_type->tp_free((PyObject*)pevlist);
578877108e4SArnaldo Carvalho de Melo }
579877108e4SArnaldo Carvalho de Melo 
580877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
581877108e4SArnaldo Carvalho de Melo 				   PyObject *args, PyObject *kwargs)
582877108e4SArnaldo Carvalho de Melo {
583877108e4SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = &pevlist->evlist;
5847e2ed097SArnaldo Carvalho de Melo 	static char *kwlist[] = {"pages", "overwrite",
585877108e4SArnaldo Carvalho de Melo 				  NULL, NULL};
586877108e4SArnaldo Carvalho de Melo 	int pages = 128, overwrite = false;
587877108e4SArnaldo Carvalho de Melo 
5887e2ed097SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
5897e2ed097SArnaldo Carvalho de Melo 					 &pages, &overwrite))
590877108e4SArnaldo Carvalho de Melo 		return NULL;
591877108e4SArnaldo Carvalho de Melo 
5927e2ed097SArnaldo Carvalho de Melo 	if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
593877108e4SArnaldo Carvalho de Melo 		PyErr_SetFromErrno(PyExc_OSError);
594877108e4SArnaldo Carvalho de Melo 		return NULL;
595877108e4SArnaldo Carvalho de Melo 	}
596877108e4SArnaldo Carvalho de Melo 
597877108e4SArnaldo Carvalho de Melo 	Py_INCREF(Py_None);
598877108e4SArnaldo Carvalho de Melo 	return Py_None;
599877108e4SArnaldo Carvalho de Melo }
600877108e4SArnaldo Carvalho de Melo 
601877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
602877108e4SArnaldo Carvalho de Melo 				   PyObject *args, PyObject *kwargs)
603877108e4SArnaldo Carvalho de Melo {
604877108e4SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = &pevlist->evlist;
605877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = {"timeout", NULL, NULL};
606877108e4SArnaldo Carvalho de Melo 	int timeout = -1, n;
607877108e4SArnaldo Carvalho de Melo 
608877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
609877108e4SArnaldo Carvalho de Melo 		return NULL;
610877108e4SArnaldo Carvalho de Melo 
611877108e4SArnaldo Carvalho de Melo 	n = poll(evlist->pollfd, evlist->nr_fds, timeout);
612877108e4SArnaldo Carvalho de Melo 	if (n < 0) {
613877108e4SArnaldo Carvalho de Melo 		PyErr_SetFromErrno(PyExc_OSError);
614877108e4SArnaldo Carvalho de Melo 		return NULL;
615877108e4SArnaldo Carvalho de Melo 	}
616877108e4SArnaldo Carvalho de Melo 
617877108e4SArnaldo Carvalho de Melo 	return Py_BuildValue("i", n);
618877108e4SArnaldo Carvalho de Melo }
619877108e4SArnaldo Carvalho de Melo 
620877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
621f6bbc1daSArnaldo Carvalho de Melo 					 PyObject *args __used, PyObject *kwargs __used)
622877108e4SArnaldo Carvalho de Melo {
623877108e4SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = &pevlist->evlist;
624877108e4SArnaldo Carvalho de Melo         PyObject *list = PyList_New(0);
625877108e4SArnaldo Carvalho de Melo 	int i;
626877108e4SArnaldo Carvalho de Melo 
627877108e4SArnaldo Carvalho de Melo 	for (i = 0; i < evlist->nr_fds; ++i) {
628877108e4SArnaldo Carvalho de Melo 		PyObject *file;
629877108e4SArnaldo Carvalho de Melo 		FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
630877108e4SArnaldo Carvalho de Melo 
631877108e4SArnaldo Carvalho de Melo 		if (fp == NULL)
632877108e4SArnaldo Carvalho de Melo 			goto free_list;
633877108e4SArnaldo Carvalho de Melo 
634877108e4SArnaldo Carvalho de Melo 		file = PyFile_FromFile(fp, "perf", "r", NULL);
635877108e4SArnaldo Carvalho de Melo 		if (file == NULL)
636877108e4SArnaldo Carvalho de Melo 			goto free_list;
637877108e4SArnaldo Carvalho de Melo 
638877108e4SArnaldo Carvalho de Melo 		if (PyList_Append(list, file) != 0) {
639877108e4SArnaldo Carvalho de Melo 			Py_DECREF(file);
640877108e4SArnaldo Carvalho de Melo 			goto free_list;
641877108e4SArnaldo Carvalho de Melo 		}
642877108e4SArnaldo Carvalho de Melo 
643877108e4SArnaldo Carvalho de Melo 		Py_DECREF(file);
644877108e4SArnaldo Carvalho de Melo 	}
645877108e4SArnaldo Carvalho de Melo 
646877108e4SArnaldo Carvalho de Melo 	return list;
647877108e4SArnaldo Carvalho de Melo free_list:
648877108e4SArnaldo Carvalho de Melo 	return PyErr_NoMemory();
649877108e4SArnaldo Carvalho de Melo }
650877108e4SArnaldo Carvalho de Melo 
651877108e4SArnaldo Carvalho de Melo 
652877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
653f6bbc1daSArnaldo Carvalho de Melo 				  PyObject *args, PyObject *kwargs __used)
654877108e4SArnaldo Carvalho de Melo {
655877108e4SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = &pevlist->evlist;
656877108e4SArnaldo Carvalho de Melo 	PyObject *pevsel;
657877108e4SArnaldo Carvalho de Melo 	struct perf_evsel *evsel;
658877108e4SArnaldo Carvalho de Melo 
659877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTuple(args, "O", &pevsel))
660877108e4SArnaldo Carvalho de Melo 		return NULL;
661877108e4SArnaldo Carvalho de Melo 
662877108e4SArnaldo Carvalho de Melo 	Py_INCREF(pevsel);
663877108e4SArnaldo Carvalho de Melo 	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
664877108e4SArnaldo Carvalho de Melo 	evsel->idx = evlist->nr_entries;
665877108e4SArnaldo Carvalho de Melo 	perf_evlist__add(evlist, evsel);
666877108e4SArnaldo Carvalho de Melo 
667877108e4SArnaldo Carvalho de Melo 	return Py_BuildValue("i", evlist->nr_entries);
668877108e4SArnaldo Carvalho de Melo }
669877108e4SArnaldo Carvalho de Melo 
670877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
671877108e4SArnaldo Carvalho de Melo 					  PyObject *args, PyObject *kwargs)
672877108e4SArnaldo Carvalho de Melo {
673877108e4SArnaldo Carvalho de Melo 	struct perf_evlist *evlist = &pevlist->evlist;
674877108e4SArnaldo Carvalho de Melo 	union perf_event *event;
675877108e4SArnaldo Carvalho de Melo 	int sample_id_all = 1, cpu;
676877108e4SArnaldo Carvalho de Melo 	static char *kwlist[] = {"sample_id_all", NULL, NULL};
677877108e4SArnaldo Carvalho de Melo 
678877108e4SArnaldo Carvalho de Melo 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
679877108e4SArnaldo Carvalho de Melo 					 &cpu, &sample_id_all))
680877108e4SArnaldo Carvalho de Melo 		return NULL;
681877108e4SArnaldo Carvalho de Melo 
682877108e4SArnaldo Carvalho de Melo 	event = perf_evlist__read_on_cpu(evlist, cpu);
683877108e4SArnaldo Carvalho de Melo 	if (event != NULL) {
684877108e4SArnaldo Carvalho de Melo 		struct perf_evsel *first;
685877108e4SArnaldo Carvalho de Melo 		PyObject *pyevent = pyrf_event__new(event);
686877108e4SArnaldo Carvalho de Melo 		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
687877108e4SArnaldo Carvalho de Melo 
688877108e4SArnaldo Carvalho de Melo 		if (pyevent == NULL)
689877108e4SArnaldo Carvalho de Melo 			return PyErr_NoMemory();
690877108e4SArnaldo Carvalho de Melo 
691877108e4SArnaldo Carvalho de Melo 		first = list_entry(evlist->entries.next, struct perf_evsel, node);
692877108e4SArnaldo Carvalho de Melo 		perf_event__parse_sample(event, first->attr.sample_type, sample_id_all,
693877108e4SArnaldo Carvalho de Melo 					 &pevent->sample);
694877108e4SArnaldo Carvalho de Melo 		return pyevent;
695877108e4SArnaldo Carvalho de Melo 	}
696877108e4SArnaldo Carvalho de Melo 
697877108e4SArnaldo Carvalho de Melo 	Py_INCREF(Py_None);
698877108e4SArnaldo Carvalho de Melo 	return Py_None;
699877108e4SArnaldo Carvalho de Melo }
700877108e4SArnaldo Carvalho de Melo 
701877108e4SArnaldo Carvalho de Melo static PyMethodDef pyrf_evlist__methods[] = {
702877108e4SArnaldo Carvalho de Melo 	{
703877108e4SArnaldo Carvalho de Melo 		.ml_name  = "mmap",
704877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
705877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
706877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
707877108e4SArnaldo Carvalho de Melo 	},
708877108e4SArnaldo Carvalho de Melo 	{
709877108e4SArnaldo Carvalho de Melo 		.ml_name  = "poll",
710877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
711877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
712877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
713877108e4SArnaldo Carvalho de Melo 	},
714877108e4SArnaldo Carvalho de Melo 	{
715877108e4SArnaldo Carvalho de Melo 		.ml_name  = "get_pollfd",
716877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
717877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
718877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
719877108e4SArnaldo Carvalho de Melo 	},
720877108e4SArnaldo Carvalho de Melo 	{
721877108e4SArnaldo Carvalho de Melo 		.ml_name  = "add",
722877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evlist__add,
723877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
724877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
725877108e4SArnaldo Carvalho de Melo 	},
726877108e4SArnaldo Carvalho de Melo 	{
727877108e4SArnaldo Carvalho de Melo 		.ml_name  = "read_on_cpu",
728877108e4SArnaldo Carvalho de Melo 		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
729877108e4SArnaldo Carvalho de Melo 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
730877108e4SArnaldo Carvalho de Melo 		.ml_doc	  = PyDoc_STR("reads an event.")
731877108e4SArnaldo Carvalho de Melo 	},
732f6bbc1daSArnaldo Carvalho de Melo 	{ .ml_name = NULL, }
733877108e4SArnaldo Carvalho de Melo };
734877108e4SArnaldo Carvalho de Melo 
735877108e4SArnaldo Carvalho de Melo static Py_ssize_t pyrf_evlist__length(PyObject *obj)
736877108e4SArnaldo Carvalho de Melo {
737877108e4SArnaldo Carvalho de Melo 	struct pyrf_evlist *pevlist = (void *)obj;
738877108e4SArnaldo Carvalho de Melo 
739877108e4SArnaldo Carvalho de Melo 	return pevlist->evlist.nr_entries;
740877108e4SArnaldo Carvalho de Melo }
741877108e4SArnaldo Carvalho de Melo 
742877108e4SArnaldo Carvalho de Melo static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
743877108e4SArnaldo Carvalho de Melo {
744877108e4SArnaldo Carvalho de Melo 	struct pyrf_evlist *pevlist = (void *)obj;
745877108e4SArnaldo Carvalho de Melo 	struct perf_evsel *pos;
746877108e4SArnaldo Carvalho de Melo 
747877108e4SArnaldo Carvalho de Melo 	if (i >= pevlist->evlist.nr_entries)
748877108e4SArnaldo Carvalho de Melo 		return NULL;
749877108e4SArnaldo Carvalho de Melo 
750877108e4SArnaldo Carvalho de Melo 	list_for_each_entry(pos, &pevlist->evlist.entries, node)
751877108e4SArnaldo Carvalho de Melo 		if (i-- == 0)
752877108e4SArnaldo Carvalho de Melo 			break;
753877108e4SArnaldo Carvalho de Melo 
754877108e4SArnaldo Carvalho de Melo 	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
755877108e4SArnaldo Carvalho de Melo }
756877108e4SArnaldo Carvalho de Melo 
757877108e4SArnaldo Carvalho de Melo static PySequenceMethods pyrf_evlist__sequence_methods = {
758877108e4SArnaldo Carvalho de Melo 	.sq_length = pyrf_evlist__length,
759877108e4SArnaldo Carvalho de Melo 	.sq_item   = pyrf_evlist__item,
760877108e4SArnaldo Carvalho de Melo };
761877108e4SArnaldo Carvalho de Melo 
762877108e4SArnaldo Carvalho de Melo static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
763877108e4SArnaldo Carvalho de Melo 
764877108e4SArnaldo Carvalho de Melo static PyTypeObject pyrf_evlist__type = {
765877108e4SArnaldo Carvalho de Melo 	PyVarObject_HEAD_INIT(NULL, 0)
766877108e4SArnaldo Carvalho de Melo 	.tp_name	= "perf.evlist",
767877108e4SArnaldo Carvalho de Melo 	.tp_basicsize	= sizeof(struct pyrf_evlist),
768877108e4SArnaldo Carvalho de Melo 	.tp_dealloc	= (destructor)pyrf_evlist__delete,
769877108e4SArnaldo Carvalho de Melo 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
770877108e4SArnaldo Carvalho de Melo 	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
771877108e4SArnaldo Carvalho de Melo 	.tp_doc		= pyrf_evlist__doc,
772877108e4SArnaldo Carvalho de Melo 	.tp_methods	= pyrf_evlist__methods,
773877108e4SArnaldo Carvalho de Melo 	.tp_init	= (initproc)pyrf_evlist__init,
774877108e4SArnaldo Carvalho de Melo };
775877108e4SArnaldo Carvalho de Melo 
776877108e4SArnaldo Carvalho de Melo static int pyrf_evlist__setup_types(void)
777877108e4SArnaldo Carvalho de Melo {
778877108e4SArnaldo Carvalho de Melo 	pyrf_evlist__type.tp_new = PyType_GenericNew;
779877108e4SArnaldo Carvalho de Melo 	return PyType_Ready(&pyrf_evlist__type);
780877108e4SArnaldo Carvalho de Melo }
781877108e4SArnaldo Carvalho de Melo 
782877108e4SArnaldo Carvalho de Melo static struct {
783877108e4SArnaldo Carvalho de Melo 	const char *name;
784877108e4SArnaldo Carvalho de Melo 	int	    value;
785877108e4SArnaldo Carvalho de Melo } perf__constants[] = {
786877108e4SArnaldo Carvalho de Melo 	{ "TYPE_HARDWARE",   PERF_TYPE_HARDWARE },
787877108e4SArnaldo Carvalho de Melo 	{ "TYPE_SOFTWARE",   PERF_TYPE_SOFTWARE },
788877108e4SArnaldo Carvalho de Melo 	{ "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
789877108e4SArnaldo Carvalho de Melo 	{ "TYPE_HW_CACHE",   PERF_TYPE_HW_CACHE },
790877108e4SArnaldo Carvalho de Melo 	{ "TYPE_RAW",	     PERF_TYPE_RAW },
791877108e4SArnaldo Carvalho de Melo 	{ "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
792877108e4SArnaldo Carvalho de Melo 
793877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CPU_CYCLES",	  PERF_COUNT_HW_CPU_CYCLES },
794877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_INSTRUCTIONS",	  PERF_COUNT_HW_INSTRUCTIONS },
795877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_REFERENCES",	  PERF_COUNT_HW_CACHE_REFERENCES },
796877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_MISSES",	  PERF_COUNT_HW_CACHE_MISSES },
797877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
798877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_BRANCH_MISSES",	  PERF_COUNT_HW_BRANCH_MISSES },
799877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_BUS_CYCLES",	  PERF_COUNT_HW_BUS_CYCLES },
800877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_L1D",		  PERF_COUNT_HW_CACHE_L1D },
801877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_L1I",		  PERF_COUNT_HW_CACHE_L1I },
802877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_LL",	  	  PERF_COUNT_HW_CACHE_LL },
803877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_DTLB",	  PERF_COUNT_HW_CACHE_DTLB },
804877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_ITLB",	  PERF_COUNT_HW_CACHE_ITLB },
805877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_BPU",		  PERF_COUNT_HW_CACHE_BPU },
806877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_OP_READ",	  PERF_COUNT_HW_CACHE_OP_READ },
807877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_OP_WRITE",	  PERF_COUNT_HW_CACHE_OP_WRITE },
808877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_OP_PREFETCH",	  PERF_COUNT_HW_CACHE_OP_PREFETCH },
809877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
810877108e4SArnaldo Carvalho de Melo 	{ "COUNT_HW_CACHE_RESULT_MISS",   PERF_COUNT_HW_CACHE_RESULT_MISS },
811877108e4SArnaldo Carvalho de Melo 
812877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_CPU_CLOCK",	       PERF_COUNT_SW_CPU_CLOCK },
813877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_TASK_CLOCK",       PERF_COUNT_SW_TASK_CLOCK },
814877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_PAGE_FAULTS",      PERF_COUNT_SW_PAGE_FAULTS },
815877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
816877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_CPU_MIGRATIONS",   PERF_COUNT_SW_CPU_MIGRATIONS },
817877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_PAGE_FAULTS_MIN",  PERF_COUNT_SW_PAGE_FAULTS_MIN },
818877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_PAGE_FAULTS_MAJ",  PERF_COUNT_SW_PAGE_FAULTS_MAJ },
819877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
820877108e4SArnaldo Carvalho de Melo 	{ "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
821877108e4SArnaldo Carvalho de Melo 
822877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_IP",	      PERF_SAMPLE_IP },
823877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_TID",	      PERF_SAMPLE_TID },
824877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_TIME",      PERF_SAMPLE_TIME },
825877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_ADDR",      PERF_SAMPLE_ADDR },
826877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_READ",      PERF_SAMPLE_READ },
827877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
828877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_ID",	      PERF_SAMPLE_ID },
829877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_CPU",	      PERF_SAMPLE_CPU },
830877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_PERIOD",    PERF_SAMPLE_PERIOD },
831877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
832877108e4SArnaldo Carvalho de Melo 	{ "SAMPLE_RAW",	      PERF_SAMPLE_RAW },
833877108e4SArnaldo Carvalho de Melo 
834877108e4SArnaldo Carvalho de Melo 	{ "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
835877108e4SArnaldo Carvalho de Melo 	{ "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
836877108e4SArnaldo Carvalho de Melo 	{ "FORMAT_ID",		       PERF_FORMAT_ID },
837877108e4SArnaldo Carvalho de Melo 	{ "FORMAT_GROUP",	       PERF_FORMAT_GROUP },
838877108e4SArnaldo Carvalho de Melo 
839877108e4SArnaldo Carvalho de Melo 	{ "RECORD_MMAP",       PERF_RECORD_MMAP },
840877108e4SArnaldo Carvalho de Melo 	{ "RECORD_LOST",       PERF_RECORD_LOST },
841877108e4SArnaldo Carvalho de Melo 	{ "RECORD_COMM",       PERF_RECORD_COMM },
842877108e4SArnaldo Carvalho de Melo 	{ "RECORD_EXIT",       PERF_RECORD_EXIT },
843877108e4SArnaldo Carvalho de Melo 	{ "RECORD_THROTTLE",   PERF_RECORD_THROTTLE },
844877108e4SArnaldo Carvalho de Melo 	{ "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
845877108e4SArnaldo Carvalho de Melo 	{ "RECORD_FORK",       PERF_RECORD_FORK },
846877108e4SArnaldo Carvalho de Melo 	{ "RECORD_READ",       PERF_RECORD_READ },
847877108e4SArnaldo Carvalho de Melo 	{ "RECORD_SAMPLE",     PERF_RECORD_SAMPLE },
848f6bbc1daSArnaldo Carvalho de Melo 	{ .name = NULL, },
849877108e4SArnaldo Carvalho de Melo };
850877108e4SArnaldo Carvalho de Melo 
851877108e4SArnaldo Carvalho de Melo static PyMethodDef perf__methods[] = {
852f6bbc1daSArnaldo Carvalho de Melo 	{ .ml_name = NULL, }
853877108e4SArnaldo Carvalho de Melo };
854877108e4SArnaldo Carvalho de Melo 
855877108e4SArnaldo Carvalho de Melo PyMODINIT_FUNC initperf(void)
856877108e4SArnaldo Carvalho de Melo {
857877108e4SArnaldo Carvalho de Melo 	PyObject *obj;
858877108e4SArnaldo Carvalho de Melo 	int i;
859877108e4SArnaldo Carvalho de Melo 	PyObject *dict, *module = Py_InitModule("perf", perf__methods);
860877108e4SArnaldo Carvalho de Melo 
861877108e4SArnaldo Carvalho de Melo 	if (module == NULL ||
862877108e4SArnaldo Carvalho de Melo 	    pyrf_event__setup_types() < 0 ||
863877108e4SArnaldo Carvalho de Melo 	    pyrf_evlist__setup_types() < 0 ||
864877108e4SArnaldo Carvalho de Melo 	    pyrf_evsel__setup_types() < 0 ||
865877108e4SArnaldo Carvalho de Melo 	    pyrf_thread_map__setup_types() < 0 ||
866877108e4SArnaldo Carvalho de Melo 	    pyrf_cpu_map__setup_types() < 0)
867877108e4SArnaldo Carvalho de Melo 		return;
868877108e4SArnaldo Carvalho de Melo 
869877108e4SArnaldo Carvalho de Melo 	Py_INCREF(&pyrf_evlist__type);
870877108e4SArnaldo Carvalho de Melo 	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
871877108e4SArnaldo Carvalho de Melo 
872877108e4SArnaldo Carvalho de Melo 	Py_INCREF(&pyrf_evsel__type);
873877108e4SArnaldo Carvalho de Melo 	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
874877108e4SArnaldo Carvalho de Melo 
875877108e4SArnaldo Carvalho de Melo 	Py_INCREF(&pyrf_thread_map__type);
876877108e4SArnaldo Carvalho de Melo 	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
877877108e4SArnaldo Carvalho de Melo 
878877108e4SArnaldo Carvalho de Melo 	Py_INCREF(&pyrf_cpu_map__type);
879877108e4SArnaldo Carvalho de Melo 	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
880877108e4SArnaldo Carvalho de Melo 
881877108e4SArnaldo Carvalho de Melo 	dict = PyModule_GetDict(module);
882877108e4SArnaldo Carvalho de Melo 	if (dict == NULL)
883877108e4SArnaldo Carvalho de Melo 		goto error;
884877108e4SArnaldo Carvalho de Melo 
885877108e4SArnaldo Carvalho de Melo 	for (i = 0; perf__constants[i].name != NULL; i++) {
886877108e4SArnaldo Carvalho de Melo 		obj = PyInt_FromLong(perf__constants[i].value);
887877108e4SArnaldo Carvalho de Melo 		if (obj == NULL)
888877108e4SArnaldo Carvalho de Melo 			goto error;
889877108e4SArnaldo Carvalho de Melo 		PyDict_SetItemString(dict, perf__constants[i].name, obj);
890877108e4SArnaldo Carvalho de Melo 		Py_DECREF(obj);
891877108e4SArnaldo Carvalho de Melo 	}
892877108e4SArnaldo Carvalho de Melo 
893877108e4SArnaldo Carvalho de Melo error:
894877108e4SArnaldo Carvalho de Melo 	if (PyErr_Occurred())
895877108e4SArnaldo Carvalho de Melo 		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
896877108e4SArnaldo Carvalho de Melo }
897