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