• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 #include <Python.h>
3 #include <structmember.h>
4 #include <inttypes.h>
5 #include <poll.h>
6 #include <linux/err.h>
7 #include <perf/cpumap.h>
8 #include <traceevent/event-parse.h>
9 #include "evlist.h"
10 #include "callchain.h"
11 #include "evsel.h"
12 #include "event.h"
13 #include "print_binary.h"
14 #include "thread_map.h"
15 #include "trace-event.h"
16 #include "mmap.h"
17 #include "util/env.h"
18 #include <internal/lib.h>
19 #include "../perf-sys.h"
20 
21 #if PY_MAJOR_VERSION < 3
22 #define _PyUnicode_FromString(arg) \
23   PyString_FromString(arg)
24 #define _PyUnicode_AsString(arg) \
25   PyString_AsString(arg)
26 #define _PyUnicode_FromFormat(...) \
27   PyString_FromFormat(__VA_ARGS__)
28 #define _PyLong_FromLong(arg) \
29   PyInt_FromLong(arg)
30 
31 #else
32 
33 #define _PyUnicode_FromString(arg) \
34   PyUnicode_FromString(arg)
35 #define _PyUnicode_FromFormat(...) \
36   PyUnicode_FromFormat(__VA_ARGS__)
37 #define _PyLong_FromLong(arg) \
38   PyLong_FromLong(arg)
39 #endif
40 
41 #ifndef Py_TYPE
42 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
43 #endif
44 
45 /*
46  * Provide these two so that we don't have to link against callchain.c and
47  * start dragging hist.c, etc.
48  */
49 struct callchain_param callchain_param;
50 
parse_callchain_record(const char * arg __maybe_unused,struct callchain_param * param __maybe_unused)51 int parse_callchain_record(const char *arg __maybe_unused,
52 			   struct callchain_param *param __maybe_unused)
53 {
54 	return 0;
55 }
56 
57 /*
58  * Add this one here not to drag util/env.c
59  */
60 struct perf_env perf_env;
61 
62 /*
63  * Support debug printing even though util/debug.c is not linked.  That means
64  * implementing 'verbose' and 'eprintf'.
65  */
66 int verbose;
67 
68 int eprintf(int level, int var, const char *fmt, ...);
69 
eprintf(int level,int var,const char * fmt,...)70 int eprintf(int level, int var, const char *fmt, ...)
71 {
72 	va_list args;
73 	int ret = 0;
74 
75 	if (var >= level) {
76 		va_start(args, fmt);
77 		ret = vfprintf(stderr, fmt, args);
78 		va_end(args);
79 	}
80 
81 	return ret;
82 }
83 
84 /* Define PyVarObject_HEAD_INIT for python 2.5 */
85 #ifndef PyVarObject_HEAD_INIT
86 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
87 #endif
88 
89 #if PY_MAJOR_VERSION < 3
90 PyMODINIT_FUNC initperf(void);
91 #else
92 PyMODINIT_FUNC PyInit_perf(void);
93 #endif
94 
95 #define member_def(type, member, ptype, help) \
96 	{ #member, ptype, \
97 	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
98 	  0, help }
99 
100 #define sample_member_def(name, member, ptype, help) \
101 	{ #name, ptype, \
102 	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
103 	  0, help }
104 
105 struct pyrf_event {
106 	PyObject_HEAD
107 	struct evsel *evsel;
108 	struct perf_sample sample;
109 	union perf_event   event;
110 };
111 
112 #define sample_members \
113 	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
114 	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
115 	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
116 	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
117 	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
118 	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
119 	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
120 	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
121 	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
122 
123 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
124 
125 static PyMemberDef pyrf_mmap_event__members[] = {
126 	sample_members
127 	member_def(perf_event_header, type, T_UINT, "event type"),
128 	member_def(perf_event_header, misc, T_UINT, "event misc"),
129 	member_def(perf_record_mmap, pid, T_UINT, "event pid"),
130 	member_def(perf_record_mmap, tid, T_UINT, "event tid"),
131 	member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"),
132 	member_def(perf_record_mmap, len, T_ULONGLONG, "map length"),
133 	member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"),
134 	member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"),
135 	{ .name = NULL, },
136 };
137 
pyrf_mmap_event__repr(struct pyrf_event * pevent)138 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
139 {
140 	PyObject *ret;
141 	char *s;
142 
143 	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", "
144 			 "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", "
145 			 "filename: %s }",
146 		     pevent->event.mmap.pid, pevent->event.mmap.tid,
147 		     pevent->event.mmap.start, pevent->event.mmap.len,
148 		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
149 		ret = PyErr_NoMemory();
150 	} else {
151 		ret = _PyUnicode_FromString(s);
152 		free(s);
153 	}
154 	return ret;
155 }
156 
157 static PyTypeObject pyrf_mmap_event__type = {
158 	PyVarObject_HEAD_INIT(NULL, 0)
159 	.tp_name	= "perf.mmap_event",
160 	.tp_basicsize	= sizeof(struct pyrf_event),
161 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
162 	.tp_doc		= pyrf_mmap_event__doc,
163 	.tp_members	= pyrf_mmap_event__members,
164 	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
165 };
166 
167 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
168 
169 static PyMemberDef pyrf_task_event__members[] = {
170 	sample_members
171 	member_def(perf_event_header, type, T_UINT, "event type"),
172 	member_def(perf_record_fork, pid, T_UINT, "event pid"),
173 	member_def(perf_record_fork, ppid, T_UINT, "event ppid"),
174 	member_def(perf_record_fork, tid, T_UINT, "event tid"),
175 	member_def(perf_record_fork, ptid, T_UINT, "event ptid"),
176 	member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"),
177 	{ .name = NULL, },
178 };
179 
pyrf_task_event__repr(struct pyrf_event * pevent)180 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
181 {
182 	return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
183 				   "ptid: %u, time: %" PRI_lu64 "}",
184 				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
185 				   pevent->event.fork.pid,
186 				   pevent->event.fork.ppid,
187 				   pevent->event.fork.tid,
188 				   pevent->event.fork.ptid,
189 				   pevent->event.fork.time);
190 }
191 
192 static PyTypeObject pyrf_task_event__type = {
193 	PyVarObject_HEAD_INIT(NULL, 0)
194 	.tp_name	= "perf.task_event",
195 	.tp_basicsize	= sizeof(struct pyrf_event),
196 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
197 	.tp_doc		= pyrf_task_event__doc,
198 	.tp_members	= pyrf_task_event__members,
199 	.tp_repr	= (reprfunc)pyrf_task_event__repr,
200 };
201 
202 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
203 
204 static PyMemberDef pyrf_comm_event__members[] = {
205 	sample_members
206 	member_def(perf_event_header, type, T_UINT, "event type"),
207 	member_def(perf_record_comm, pid, T_UINT, "event pid"),
208 	member_def(perf_record_comm, tid, T_UINT, "event tid"),
209 	member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"),
210 	{ .name = NULL, },
211 };
212 
pyrf_comm_event__repr(struct pyrf_event * pevent)213 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
214 {
215 	return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
216 				   pevent->event.comm.pid,
217 				   pevent->event.comm.tid,
218 				   pevent->event.comm.comm);
219 }
220 
221 static PyTypeObject pyrf_comm_event__type = {
222 	PyVarObject_HEAD_INIT(NULL, 0)
223 	.tp_name	= "perf.comm_event",
224 	.tp_basicsize	= sizeof(struct pyrf_event),
225 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
226 	.tp_doc		= pyrf_comm_event__doc,
227 	.tp_members	= pyrf_comm_event__members,
228 	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
229 };
230 
231 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
232 
233 static PyMemberDef pyrf_throttle_event__members[] = {
234 	sample_members
235 	member_def(perf_event_header, type, T_UINT, "event type"),
236 	member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"),
237 	member_def(perf_record_throttle, id, T_ULONGLONG, "event id"),
238 	member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"),
239 	{ .name = NULL, },
240 };
241 
pyrf_throttle_event__repr(struct pyrf_event * pevent)242 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
243 {
244 	struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1);
245 
246 	return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64
247 				   ", stream_id: %" PRI_lu64 " }",
248 				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
249 				   te->time, te->id, te->stream_id);
250 }
251 
252 static PyTypeObject pyrf_throttle_event__type = {
253 	PyVarObject_HEAD_INIT(NULL, 0)
254 	.tp_name	= "perf.throttle_event",
255 	.tp_basicsize	= sizeof(struct pyrf_event),
256 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
257 	.tp_doc		= pyrf_throttle_event__doc,
258 	.tp_members	= pyrf_throttle_event__members,
259 	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
260 };
261 
262 static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
263 
264 static PyMemberDef pyrf_lost_event__members[] = {
265 	sample_members
266 	member_def(perf_record_lost, id, T_ULONGLONG, "event id"),
267 	member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"),
268 	{ .name = NULL, },
269 };
270 
pyrf_lost_event__repr(struct pyrf_event * pevent)271 static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
272 {
273 	PyObject *ret;
274 	char *s;
275 
276 	if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", "
277 			 "lost: %#" PRI_lx64 " }",
278 		     pevent->event.lost.id, pevent->event.lost.lost) < 0) {
279 		ret = PyErr_NoMemory();
280 	} else {
281 		ret = _PyUnicode_FromString(s);
282 		free(s);
283 	}
284 	return ret;
285 }
286 
287 static PyTypeObject pyrf_lost_event__type = {
288 	PyVarObject_HEAD_INIT(NULL, 0)
289 	.tp_name	= "perf.lost_event",
290 	.tp_basicsize	= sizeof(struct pyrf_event),
291 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
292 	.tp_doc		= pyrf_lost_event__doc,
293 	.tp_members	= pyrf_lost_event__members,
294 	.tp_repr	= (reprfunc)pyrf_lost_event__repr,
295 };
296 
297 static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
298 
299 static PyMemberDef pyrf_read_event__members[] = {
300 	sample_members
301 	member_def(perf_record_read, pid, T_UINT, "event pid"),
302 	member_def(perf_record_read, tid, T_UINT, "event tid"),
303 	{ .name = NULL, },
304 };
305 
pyrf_read_event__repr(struct pyrf_event * pevent)306 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
307 {
308 	return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
309 				   pevent->event.read.pid,
310 				   pevent->event.read.tid);
311 	/*
312  	 * FIXME: return the array of read values,
313  	 * making this method useful ;-)
314  	 */
315 }
316 
317 static PyTypeObject pyrf_read_event__type = {
318 	PyVarObject_HEAD_INIT(NULL, 0)
319 	.tp_name	= "perf.read_event",
320 	.tp_basicsize	= sizeof(struct pyrf_event),
321 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
322 	.tp_doc		= pyrf_read_event__doc,
323 	.tp_members	= pyrf_read_event__members,
324 	.tp_repr	= (reprfunc)pyrf_read_event__repr,
325 };
326 
327 static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
328 
329 static PyMemberDef pyrf_sample_event__members[] = {
330 	sample_members
331 	member_def(perf_event_header, type, T_UINT, "event type"),
332 	{ .name = NULL, },
333 };
334 
pyrf_sample_event__repr(struct pyrf_event * pevent)335 static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
336 {
337 	PyObject *ret;
338 	char *s;
339 
340 	if (asprintf(&s, "{ type: sample }") < 0) {
341 		ret = PyErr_NoMemory();
342 	} else {
343 		ret = _PyUnicode_FromString(s);
344 		free(s);
345 	}
346 	return ret;
347 }
348 
is_tracepoint(struct pyrf_event * pevent)349 static bool is_tracepoint(struct pyrf_event *pevent)
350 {
351 	return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
352 }
353 
354 static PyObject*
tracepoint_field(struct pyrf_event * pe,struct tep_format_field * field)355 tracepoint_field(struct pyrf_event *pe, struct tep_format_field *field)
356 {
357 	struct tep_handle *pevent = field->event->tep;
358 	void *data = pe->sample.raw_data;
359 	PyObject *ret = NULL;
360 	unsigned long long val;
361 	unsigned int offset, len;
362 
363 	if (field->flags & TEP_FIELD_IS_ARRAY) {
364 		offset = field->offset;
365 		len    = field->size;
366 		if (field->flags & TEP_FIELD_IS_DYNAMIC) {
367 			val     = tep_read_number(pevent, data + offset, len);
368 			offset  = val;
369 			len     = offset >> 16;
370 			offset &= 0xffff;
371 		}
372 		if (field->flags & TEP_FIELD_IS_STRING &&
373 		    is_printable_array(data + offset, len)) {
374 			ret = _PyUnicode_FromString((char *)data + offset);
375 		} else {
376 			ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
377 			field->flags &= ~TEP_FIELD_IS_STRING;
378 		}
379 	} else {
380 		val = tep_read_number(pevent, data + field->offset,
381 				      field->size);
382 		if (field->flags & TEP_FIELD_IS_POINTER)
383 			ret = PyLong_FromUnsignedLong((unsigned long) val);
384 		else if (field->flags & TEP_FIELD_IS_SIGNED)
385 			ret = PyLong_FromLong((long) val);
386 		else
387 			ret = PyLong_FromUnsignedLong((unsigned long) val);
388 	}
389 
390 	return ret;
391 }
392 
393 static PyObject*
get_tracepoint_field(struct pyrf_event * pevent,PyObject * attr_name)394 get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
395 {
396 	const char *str = _PyUnicode_AsString(PyObject_Str(attr_name));
397 	struct evsel *evsel = pevent->evsel;
398 	struct tep_format_field *field;
399 
400 	if (!evsel->tp_format) {
401 		struct tep_event *tp_format;
402 
403 		tp_format = trace_event__tp_format_id(evsel->core.attr.config);
404 		if (!tp_format)
405 			return NULL;
406 
407 		evsel->tp_format = tp_format;
408 	}
409 
410 	field = tep_find_any_field(evsel->tp_format, str);
411 	if (!field)
412 		return NULL;
413 
414 	return tracepoint_field(pevent, field);
415 }
416 
417 static PyObject*
pyrf_sample_event__getattro(struct pyrf_event * pevent,PyObject * attr_name)418 pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
419 {
420 	PyObject *obj = NULL;
421 
422 	if (is_tracepoint(pevent))
423 		obj = get_tracepoint_field(pevent, attr_name);
424 
425 	return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
426 }
427 
428 static PyTypeObject pyrf_sample_event__type = {
429 	PyVarObject_HEAD_INIT(NULL, 0)
430 	.tp_name	= "perf.sample_event",
431 	.tp_basicsize	= sizeof(struct pyrf_event),
432 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
433 	.tp_doc		= pyrf_sample_event__doc,
434 	.tp_members	= pyrf_sample_event__members,
435 	.tp_repr	= (reprfunc)pyrf_sample_event__repr,
436 	.tp_getattro	= (getattrofunc) pyrf_sample_event__getattro,
437 };
438 
439 static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
440 
441 static PyMemberDef pyrf_context_switch_event__members[] = {
442 	sample_members
443 	member_def(perf_event_header, type, T_UINT, "event type"),
444 	member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"),
445 	member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"),
446 	{ .name = NULL, },
447 };
448 
pyrf_context_switch_event__repr(struct pyrf_event * pevent)449 static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
450 {
451 	PyObject *ret;
452 	char *s;
453 
454 	if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
455 		     pevent->event.context_switch.next_prev_pid,
456 		     pevent->event.context_switch.next_prev_tid,
457 		     !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
458 		ret = PyErr_NoMemory();
459 	} else {
460 		ret = _PyUnicode_FromString(s);
461 		free(s);
462 	}
463 	return ret;
464 }
465 
466 static PyTypeObject pyrf_context_switch_event__type = {
467 	PyVarObject_HEAD_INIT(NULL, 0)
468 	.tp_name	= "perf.context_switch_event",
469 	.tp_basicsize	= sizeof(struct pyrf_event),
470 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
471 	.tp_doc		= pyrf_context_switch_event__doc,
472 	.tp_members	= pyrf_context_switch_event__members,
473 	.tp_repr	= (reprfunc)pyrf_context_switch_event__repr,
474 };
475 
pyrf_event__setup_types(void)476 static int pyrf_event__setup_types(void)
477 {
478 	int err;
479 	pyrf_mmap_event__type.tp_new =
480 	pyrf_task_event__type.tp_new =
481 	pyrf_comm_event__type.tp_new =
482 	pyrf_lost_event__type.tp_new =
483 	pyrf_read_event__type.tp_new =
484 	pyrf_sample_event__type.tp_new =
485 	pyrf_context_switch_event__type.tp_new =
486 	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
487 	err = PyType_Ready(&pyrf_mmap_event__type);
488 	if (err < 0)
489 		goto out;
490 	err = PyType_Ready(&pyrf_lost_event__type);
491 	if (err < 0)
492 		goto out;
493 	err = PyType_Ready(&pyrf_task_event__type);
494 	if (err < 0)
495 		goto out;
496 	err = PyType_Ready(&pyrf_comm_event__type);
497 	if (err < 0)
498 		goto out;
499 	err = PyType_Ready(&pyrf_throttle_event__type);
500 	if (err < 0)
501 		goto out;
502 	err = PyType_Ready(&pyrf_read_event__type);
503 	if (err < 0)
504 		goto out;
505 	err = PyType_Ready(&pyrf_sample_event__type);
506 	if (err < 0)
507 		goto out;
508 	err = PyType_Ready(&pyrf_context_switch_event__type);
509 	if (err < 0)
510 		goto out;
511 out:
512 	return err;
513 }
514 
515 static PyTypeObject *pyrf_event__type[] = {
516 	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
517 	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,
518 	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
519 	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
520 	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
521 	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
522 	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
523 	[PERF_RECORD_READ]	 = &pyrf_read_event__type,
524 	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,
525 	[PERF_RECORD_SWITCH]	 = &pyrf_context_switch_event__type,
526 	[PERF_RECORD_SWITCH_CPU_WIDE]  = &pyrf_context_switch_event__type,
527 };
528 
pyrf_event__new(union perf_event * event)529 static PyObject *pyrf_event__new(union perf_event *event)
530 {
531 	struct pyrf_event *pevent;
532 	PyTypeObject *ptype;
533 
534 	if ((event->header.type < PERF_RECORD_MMAP ||
535 	     event->header.type > PERF_RECORD_SAMPLE) &&
536 	    !(event->header.type == PERF_RECORD_SWITCH ||
537 	      event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
538 		return NULL;
539 
540 	ptype = pyrf_event__type[event->header.type];
541 	pevent = PyObject_New(struct pyrf_event, ptype);
542 	if (pevent != NULL)
543 		memcpy(&pevent->event, event, event->header.size);
544 	return (PyObject *)pevent;
545 }
546 
547 struct pyrf_cpu_map {
548 	PyObject_HEAD
549 
550 	struct perf_cpu_map *cpus;
551 };
552 
pyrf_cpu_map__init(struct pyrf_cpu_map * pcpus,PyObject * args,PyObject * kwargs)553 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
554 			      PyObject *args, PyObject *kwargs)
555 {
556 	static char *kwlist[] = { "cpustr", NULL };
557 	char *cpustr = NULL;
558 
559 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
560 					 kwlist, &cpustr))
561 		return -1;
562 
563 	pcpus->cpus = perf_cpu_map__new(cpustr);
564 	if (pcpus->cpus == NULL)
565 		return -1;
566 	return 0;
567 }
568 
pyrf_cpu_map__delete(struct pyrf_cpu_map * pcpus)569 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
570 {
571 	perf_cpu_map__put(pcpus->cpus);
572 	Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
573 }
574 
pyrf_cpu_map__length(PyObject * obj)575 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
576 {
577 	struct pyrf_cpu_map *pcpus = (void *)obj;
578 
579 	return pcpus->cpus->nr;
580 }
581 
pyrf_cpu_map__item(PyObject * obj,Py_ssize_t i)582 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
583 {
584 	struct pyrf_cpu_map *pcpus = (void *)obj;
585 
586 	if (i >= pcpus->cpus->nr)
587 		return NULL;
588 
589 	return Py_BuildValue("i", pcpus->cpus->map[i]);
590 }
591 
592 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
593 	.sq_length = pyrf_cpu_map__length,
594 	.sq_item   = pyrf_cpu_map__item,
595 };
596 
597 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
598 
599 static PyTypeObject pyrf_cpu_map__type = {
600 	PyVarObject_HEAD_INIT(NULL, 0)
601 	.tp_name	= "perf.cpu_map",
602 	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
603 	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
604 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
605 	.tp_doc		= pyrf_cpu_map__doc,
606 	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
607 	.tp_init	= (initproc)pyrf_cpu_map__init,
608 };
609 
pyrf_cpu_map__setup_types(void)610 static int pyrf_cpu_map__setup_types(void)
611 {
612 	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
613 	return PyType_Ready(&pyrf_cpu_map__type);
614 }
615 
616 struct pyrf_thread_map {
617 	PyObject_HEAD
618 
619 	struct perf_thread_map *threads;
620 };
621 
pyrf_thread_map__init(struct pyrf_thread_map * pthreads,PyObject * args,PyObject * kwargs)622 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
623 				 PyObject *args, PyObject *kwargs)
624 {
625 	static char *kwlist[] = { "pid", "tid", "uid", NULL };
626 	int pid = -1, tid = -1, uid = UINT_MAX;
627 
628 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
629 					 kwlist, &pid, &tid, &uid))
630 		return -1;
631 
632 	pthreads->threads = thread_map__new(pid, tid, uid);
633 	if (pthreads->threads == NULL)
634 		return -1;
635 	return 0;
636 }
637 
pyrf_thread_map__delete(struct pyrf_thread_map * pthreads)638 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
639 {
640 	perf_thread_map__put(pthreads->threads);
641 	Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
642 }
643 
pyrf_thread_map__length(PyObject * obj)644 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
645 {
646 	struct pyrf_thread_map *pthreads = (void *)obj;
647 
648 	return pthreads->threads->nr;
649 }
650 
pyrf_thread_map__item(PyObject * obj,Py_ssize_t i)651 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
652 {
653 	struct pyrf_thread_map *pthreads = (void *)obj;
654 
655 	if (i >= pthreads->threads->nr)
656 		return NULL;
657 
658 	return Py_BuildValue("i", pthreads->threads->map[i]);
659 }
660 
661 static PySequenceMethods pyrf_thread_map__sequence_methods = {
662 	.sq_length = pyrf_thread_map__length,
663 	.sq_item   = pyrf_thread_map__item,
664 };
665 
666 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
667 
668 static PyTypeObject pyrf_thread_map__type = {
669 	PyVarObject_HEAD_INIT(NULL, 0)
670 	.tp_name	= "perf.thread_map",
671 	.tp_basicsize	= sizeof(struct pyrf_thread_map),
672 	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
673 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
674 	.tp_doc		= pyrf_thread_map__doc,
675 	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
676 	.tp_init	= (initproc)pyrf_thread_map__init,
677 };
678 
pyrf_thread_map__setup_types(void)679 static int pyrf_thread_map__setup_types(void)
680 {
681 	pyrf_thread_map__type.tp_new = PyType_GenericNew;
682 	return PyType_Ready(&pyrf_thread_map__type);
683 }
684 
685 struct pyrf_evsel {
686 	PyObject_HEAD
687 
688 	struct evsel evsel;
689 };
690 
pyrf_evsel__init(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)691 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
692 			    PyObject *args, PyObject *kwargs)
693 {
694 	struct perf_event_attr attr = {
695 		.type = PERF_TYPE_HARDWARE,
696 		.config = PERF_COUNT_HW_CPU_CYCLES,
697 		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
698 	};
699 	static char *kwlist[] = {
700 		"type",
701 		"config",
702 		"sample_freq",
703 		"sample_period",
704 		"sample_type",
705 		"read_format",
706 		"disabled",
707 		"inherit",
708 		"pinned",
709 		"exclusive",
710 		"exclude_user",
711 		"exclude_kernel",
712 		"exclude_hv",
713 		"exclude_idle",
714 		"mmap",
715 		"context_switch",
716 		"comm",
717 		"freq",
718 		"inherit_stat",
719 		"enable_on_exec",
720 		"task",
721 		"watermark",
722 		"precise_ip",
723 		"mmap_data",
724 		"sample_id_all",
725 		"wakeup_events",
726 		"bp_type",
727 		"bp_addr",
728 		"bp_len",
729 		 NULL
730 	};
731 	u64 sample_period = 0;
732 	u32 disabled = 0,
733 	    inherit = 0,
734 	    pinned = 0,
735 	    exclusive = 0,
736 	    exclude_user = 0,
737 	    exclude_kernel = 0,
738 	    exclude_hv = 0,
739 	    exclude_idle = 0,
740 	    mmap = 0,
741 	    context_switch = 0,
742 	    comm = 0,
743 	    freq = 1,
744 	    inherit_stat = 0,
745 	    enable_on_exec = 0,
746 	    task = 0,
747 	    watermark = 0,
748 	    precise_ip = 0,
749 	    mmap_data = 0,
750 	    sample_id_all = 1;
751 	int idx = 0;
752 
753 	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
754 					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
755 					 &attr.type, &attr.config, &attr.sample_freq,
756 					 &sample_period, &attr.sample_type,
757 					 &attr.read_format, &disabled, &inherit,
758 					 &pinned, &exclusive, &exclude_user,
759 					 &exclude_kernel, &exclude_hv, &exclude_idle,
760 					 &mmap, &context_switch, &comm, &freq, &inherit_stat,
761 					 &enable_on_exec, &task, &watermark,
762 					 &precise_ip, &mmap_data, &sample_id_all,
763 					 &attr.wakeup_events, &attr.bp_type,
764 					 &attr.bp_addr, &attr.bp_len, &idx))
765 		return -1;
766 
767 	/* union... */
768 	if (sample_period != 0) {
769 		if (attr.sample_freq != 0)
770 			return -1; /* FIXME: throw right exception */
771 		attr.sample_period = sample_period;
772 	}
773 
774 	/* Bitfields */
775 	attr.disabled	    = disabled;
776 	attr.inherit	    = inherit;
777 	attr.pinned	    = pinned;
778 	attr.exclusive	    = exclusive;
779 	attr.exclude_user   = exclude_user;
780 	attr.exclude_kernel = exclude_kernel;
781 	attr.exclude_hv	    = exclude_hv;
782 	attr.exclude_idle   = exclude_idle;
783 	attr.mmap	    = mmap;
784 	attr.context_switch = context_switch;
785 	attr.comm	    = comm;
786 	attr.freq	    = freq;
787 	attr.inherit_stat   = inherit_stat;
788 	attr.enable_on_exec = enable_on_exec;
789 	attr.task	    = task;
790 	attr.watermark	    = watermark;
791 	attr.precise_ip	    = precise_ip;
792 	attr.mmap_data	    = mmap_data;
793 	attr.sample_id_all  = sample_id_all;
794 	attr.size	    = sizeof(attr);
795 
796 	evsel__init(&pevsel->evsel, &attr, idx);
797 	return 0;
798 }
799 
pyrf_evsel__delete(struct pyrf_evsel * pevsel)800 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
801 {
802 	perf_evsel__exit(&pevsel->evsel);
803 	Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
804 }
805 
pyrf_evsel__open(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)806 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
807 				  PyObject *args, PyObject *kwargs)
808 {
809 	struct evsel *evsel = &pevsel->evsel;
810 	struct perf_cpu_map *cpus = NULL;
811 	struct perf_thread_map *threads = NULL;
812 	PyObject *pcpus = NULL, *pthreads = NULL;
813 	int group = 0, inherit = 0;
814 	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
815 
816 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
817 					 &pcpus, &pthreads, &group, &inherit))
818 		return NULL;
819 
820 	if (pthreads != NULL)
821 		threads = ((struct pyrf_thread_map *)pthreads)->threads;
822 
823 	if (pcpus != NULL)
824 		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
825 
826 	evsel->core.attr.inherit = inherit;
827 	/*
828 	 * This will group just the fds for this single evsel, to group
829 	 * multiple events, use evlist.open().
830 	 */
831 	if (evsel__open(evsel, cpus, threads) < 0) {
832 		PyErr_SetFromErrno(PyExc_OSError);
833 		return NULL;
834 	}
835 
836 	Py_INCREF(Py_None);
837 	return Py_None;
838 }
839 
840 static PyMethodDef pyrf_evsel__methods[] = {
841 	{
842 		.ml_name  = "open",
843 		.ml_meth  = (PyCFunction)pyrf_evsel__open,
844 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
845 		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
846 	},
847 	{ .ml_name = NULL, }
848 };
849 
850 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
851 
852 static PyTypeObject pyrf_evsel__type = {
853 	PyVarObject_HEAD_INIT(NULL, 0)
854 	.tp_name	= "perf.evsel",
855 	.tp_basicsize	= sizeof(struct pyrf_evsel),
856 	.tp_dealloc	= (destructor)pyrf_evsel__delete,
857 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
858 	.tp_doc		= pyrf_evsel__doc,
859 	.tp_methods	= pyrf_evsel__methods,
860 	.tp_init	= (initproc)pyrf_evsel__init,
861 };
862 
pyrf_evsel__setup_types(void)863 static int pyrf_evsel__setup_types(void)
864 {
865 	pyrf_evsel__type.tp_new = PyType_GenericNew;
866 	return PyType_Ready(&pyrf_evsel__type);
867 }
868 
869 struct pyrf_evlist {
870 	PyObject_HEAD
871 
872 	struct evlist evlist;
873 };
874 
pyrf_evlist__init(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs __maybe_unused)875 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
876 			     PyObject *args, PyObject *kwargs __maybe_unused)
877 {
878 	PyObject *pcpus = NULL, *pthreads = NULL;
879 	struct perf_cpu_map *cpus;
880 	struct perf_thread_map *threads;
881 
882 	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
883 		return -1;
884 
885 	threads = ((struct pyrf_thread_map *)pthreads)->threads;
886 	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
887 	evlist__init(&pevlist->evlist, cpus, threads);
888 	return 0;
889 }
890 
pyrf_evlist__delete(struct pyrf_evlist * pevlist)891 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
892 {
893 	evlist__exit(&pevlist->evlist);
894 	Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
895 }
896 
pyrf_evlist__mmap(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)897 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
898 				   PyObject *args, PyObject *kwargs)
899 {
900 	struct evlist *evlist = &pevlist->evlist;
901 	static char *kwlist[] = { "pages", "overwrite", NULL };
902 	int pages = 128, overwrite = false;
903 
904 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
905 					 &pages, &overwrite))
906 		return NULL;
907 
908 	if (evlist__mmap(evlist, pages) < 0) {
909 		PyErr_SetFromErrno(PyExc_OSError);
910 		return NULL;
911 	}
912 
913 	Py_INCREF(Py_None);
914 	return Py_None;
915 }
916 
pyrf_evlist__poll(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)917 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
918 				   PyObject *args, PyObject *kwargs)
919 {
920 	struct evlist *evlist = &pevlist->evlist;
921 	static char *kwlist[] = { "timeout", NULL };
922 	int timeout = -1, n;
923 
924 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
925 		return NULL;
926 
927 	n = evlist__poll(evlist, timeout);
928 	if (n < 0) {
929 		PyErr_SetFromErrno(PyExc_OSError);
930 		return NULL;
931 	}
932 
933 	return Py_BuildValue("i", n);
934 }
935 
pyrf_evlist__get_pollfd(struct pyrf_evlist * pevlist,PyObject * args __maybe_unused,PyObject * kwargs __maybe_unused)936 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
937 					 PyObject *args __maybe_unused,
938 					 PyObject *kwargs __maybe_unused)
939 {
940 	struct evlist *evlist = &pevlist->evlist;
941         PyObject *list = PyList_New(0);
942 	int i;
943 
944 	for (i = 0; i < evlist->core.pollfd.nr; ++i) {
945 		PyObject *file;
946 #if PY_MAJOR_VERSION < 3
947 		FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r");
948 
949 		if (fp == NULL)
950 			goto free_list;
951 
952 		file = PyFile_FromFile(fp, "perf", "r", NULL);
953 #else
954 		file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1,
955 				     NULL, NULL, NULL, 0);
956 #endif
957 		if (file == NULL)
958 			goto free_list;
959 
960 		if (PyList_Append(list, file) != 0) {
961 			Py_DECREF(file);
962 			goto free_list;
963 		}
964 
965 		Py_DECREF(file);
966 	}
967 
968 	return list;
969 free_list:
970 	return PyErr_NoMemory();
971 }
972 
973 
pyrf_evlist__add(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs __maybe_unused)974 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
975 				  PyObject *args,
976 				  PyObject *kwargs __maybe_unused)
977 {
978 	struct evlist *evlist = &pevlist->evlist;
979 	PyObject *pevsel;
980 	struct evsel *evsel;
981 
982 	if (!PyArg_ParseTuple(args, "O", &pevsel))
983 		return NULL;
984 
985 	Py_INCREF(pevsel);
986 	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
987 	evsel->idx = evlist->core.nr_entries;
988 	evlist__add(evlist, evsel);
989 
990 	return Py_BuildValue("i", evlist->core.nr_entries);
991 }
992 
get_md(struct evlist * evlist,int cpu)993 static struct mmap *get_md(struct evlist *evlist, int cpu)
994 {
995 	int i;
996 
997 	for (i = 0; i < evlist->core.nr_mmaps; i++) {
998 		struct mmap *md = &evlist->mmap[i];
999 
1000 		if (md->core.cpu == cpu)
1001 			return md;
1002 	}
1003 
1004 	return NULL;
1005 }
1006 
pyrf_evlist__read_on_cpu(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)1007 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
1008 					  PyObject *args, PyObject *kwargs)
1009 {
1010 	struct evlist *evlist = &pevlist->evlist;
1011 	union perf_event *event;
1012 	int sample_id_all = 1, cpu;
1013 	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
1014 	struct mmap *md;
1015 	int err;
1016 
1017 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
1018 					 &cpu, &sample_id_all))
1019 		return NULL;
1020 
1021 	md = get_md(evlist, cpu);
1022 	if (!md)
1023 		return NULL;
1024 
1025 	if (perf_mmap__read_init(md) < 0)
1026 		goto end;
1027 
1028 	event = perf_mmap__read_event(md);
1029 	if (event != NULL) {
1030 		PyObject *pyevent = pyrf_event__new(event);
1031 		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
1032 		struct evsel *evsel;
1033 
1034 		if (pyevent == NULL)
1035 			return PyErr_NoMemory();
1036 
1037 		evsel = perf_evlist__event2evsel(evlist, event);
1038 		if (!evsel) {
1039 			Py_INCREF(Py_None);
1040 			return Py_None;
1041 		}
1042 
1043 		pevent->evsel = evsel;
1044 
1045 		err = perf_evsel__parse_sample(evsel, event, &pevent->sample);
1046 
1047 		/* Consume the even only after we parsed it out. */
1048 		perf_mmap__consume(md);
1049 
1050 		if (err)
1051 			return PyErr_Format(PyExc_OSError,
1052 					    "perf: can't parse sample, err=%d", err);
1053 		return pyevent;
1054 	}
1055 end:
1056 	Py_INCREF(Py_None);
1057 	return Py_None;
1058 }
1059 
pyrf_evlist__open(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)1060 static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
1061 				   PyObject *args, PyObject *kwargs)
1062 {
1063 	struct evlist *evlist = &pevlist->evlist;
1064 	int group = 0;
1065 	static char *kwlist[] = { "group", NULL };
1066 
1067 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
1068 		return NULL;
1069 
1070 	if (group)
1071 		perf_evlist__set_leader(evlist);
1072 
1073 	if (evlist__open(evlist) < 0) {
1074 		PyErr_SetFromErrno(PyExc_OSError);
1075 		return NULL;
1076 	}
1077 
1078 	Py_INCREF(Py_None);
1079 	return Py_None;
1080 }
1081 
1082 static PyMethodDef pyrf_evlist__methods[] = {
1083 	{
1084 		.ml_name  = "mmap",
1085 		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
1086 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1087 		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
1088 	},
1089 	{
1090 		.ml_name  = "open",
1091 		.ml_meth  = (PyCFunction)pyrf_evlist__open,
1092 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1093 		.ml_doc	  = PyDoc_STR("open the file descriptors.")
1094 	},
1095 	{
1096 		.ml_name  = "poll",
1097 		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
1098 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1099 		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
1100 	},
1101 	{
1102 		.ml_name  = "get_pollfd",
1103 		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
1104 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1105 		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
1106 	},
1107 	{
1108 		.ml_name  = "add",
1109 		.ml_meth  = (PyCFunction)pyrf_evlist__add,
1110 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1111 		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
1112 	},
1113 	{
1114 		.ml_name  = "read_on_cpu",
1115 		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
1116 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1117 		.ml_doc	  = PyDoc_STR("reads an event.")
1118 	},
1119 	{ .ml_name = NULL, }
1120 };
1121 
pyrf_evlist__length(PyObject * obj)1122 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
1123 {
1124 	struct pyrf_evlist *pevlist = (void *)obj;
1125 
1126 	return pevlist->evlist.core.nr_entries;
1127 }
1128 
pyrf_evlist__item(PyObject * obj,Py_ssize_t i)1129 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
1130 {
1131 	struct pyrf_evlist *pevlist = (void *)obj;
1132 	struct evsel *pos;
1133 
1134 	if (i >= pevlist->evlist.core.nr_entries)
1135 		return NULL;
1136 
1137 	evlist__for_each_entry(&pevlist->evlist, pos) {
1138 		if (i-- == 0)
1139 			break;
1140 	}
1141 
1142 	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
1143 }
1144 
1145 static PySequenceMethods pyrf_evlist__sequence_methods = {
1146 	.sq_length = pyrf_evlist__length,
1147 	.sq_item   = pyrf_evlist__item,
1148 };
1149 
1150 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
1151 
1152 static PyTypeObject pyrf_evlist__type = {
1153 	PyVarObject_HEAD_INIT(NULL, 0)
1154 	.tp_name	= "perf.evlist",
1155 	.tp_basicsize	= sizeof(struct pyrf_evlist),
1156 	.tp_dealloc	= (destructor)pyrf_evlist__delete,
1157 	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1158 	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
1159 	.tp_doc		= pyrf_evlist__doc,
1160 	.tp_methods	= pyrf_evlist__methods,
1161 	.tp_init	= (initproc)pyrf_evlist__init,
1162 };
1163 
pyrf_evlist__setup_types(void)1164 static int pyrf_evlist__setup_types(void)
1165 {
1166 	pyrf_evlist__type.tp_new = PyType_GenericNew;
1167 	return PyType_Ready(&pyrf_evlist__type);
1168 }
1169 
1170 #define PERF_CONST(name) { #name, PERF_##name }
1171 
1172 static struct {
1173 	const char *name;
1174 	int	    value;
1175 } perf__constants[] = {
1176 	PERF_CONST(TYPE_HARDWARE),
1177 	PERF_CONST(TYPE_SOFTWARE),
1178 	PERF_CONST(TYPE_TRACEPOINT),
1179 	PERF_CONST(TYPE_HW_CACHE),
1180 	PERF_CONST(TYPE_RAW),
1181 	PERF_CONST(TYPE_BREAKPOINT),
1182 
1183 	PERF_CONST(COUNT_HW_CPU_CYCLES),
1184 	PERF_CONST(COUNT_HW_INSTRUCTIONS),
1185 	PERF_CONST(COUNT_HW_CACHE_REFERENCES),
1186 	PERF_CONST(COUNT_HW_CACHE_MISSES),
1187 	PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
1188 	PERF_CONST(COUNT_HW_BRANCH_MISSES),
1189 	PERF_CONST(COUNT_HW_BUS_CYCLES),
1190 	PERF_CONST(COUNT_HW_CACHE_L1D),
1191 	PERF_CONST(COUNT_HW_CACHE_L1I),
1192 	PERF_CONST(COUNT_HW_CACHE_LL),
1193 	PERF_CONST(COUNT_HW_CACHE_DTLB),
1194 	PERF_CONST(COUNT_HW_CACHE_ITLB),
1195 	PERF_CONST(COUNT_HW_CACHE_BPU),
1196 	PERF_CONST(COUNT_HW_CACHE_OP_READ),
1197 	PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
1198 	PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
1199 	PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
1200 	PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
1201 
1202 	PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
1203 	PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
1204 
1205 	PERF_CONST(COUNT_SW_CPU_CLOCK),
1206 	PERF_CONST(COUNT_SW_TASK_CLOCK),
1207 	PERF_CONST(COUNT_SW_PAGE_FAULTS),
1208 	PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
1209 	PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
1210 	PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
1211 	PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
1212 	PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
1213 	PERF_CONST(COUNT_SW_EMULATION_FAULTS),
1214 	PERF_CONST(COUNT_SW_DUMMY),
1215 
1216 	PERF_CONST(SAMPLE_IP),
1217 	PERF_CONST(SAMPLE_TID),
1218 	PERF_CONST(SAMPLE_TIME),
1219 	PERF_CONST(SAMPLE_ADDR),
1220 	PERF_CONST(SAMPLE_READ),
1221 	PERF_CONST(SAMPLE_CALLCHAIN),
1222 	PERF_CONST(SAMPLE_ID),
1223 	PERF_CONST(SAMPLE_CPU),
1224 	PERF_CONST(SAMPLE_PERIOD),
1225 	PERF_CONST(SAMPLE_STREAM_ID),
1226 	PERF_CONST(SAMPLE_RAW),
1227 
1228 	PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
1229 	PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
1230 	PERF_CONST(FORMAT_ID),
1231 	PERF_CONST(FORMAT_GROUP),
1232 
1233 	PERF_CONST(RECORD_MMAP),
1234 	PERF_CONST(RECORD_LOST),
1235 	PERF_CONST(RECORD_COMM),
1236 	PERF_CONST(RECORD_EXIT),
1237 	PERF_CONST(RECORD_THROTTLE),
1238 	PERF_CONST(RECORD_UNTHROTTLE),
1239 	PERF_CONST(RECORD_FORK),
1240 	PERF_CONST(RECORD_READ),
1241 	PERF_CONST(RECORD_SAMPLE),
1242 	PERF_CONST(RECORD_MMAP2),
1243 	PERF_CONST(RECORD_AUX),
1244 	PERF_CONST(RECORD_ITRACE_START),
1245 	PERF_CONST(RECORD_LOST_SAMPLES),
1246 	PERF_CONST(RECORD_SWITCH),
1247 	PERF_CONST(RECORD_SWITCH_CPU_WIDE),
1248 
1249 	PERF_CONST(RECORD_MISC_SWITCH_OUT),
1250 	{ .name = NULL, },
1251 };
1252 
pyrf__tracepoint(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)1253 static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
1254 				  PyObject *args, PyObject *kwargs)
1255 {
1256 	struct tep_event *tp_format;
1257 	static char *kwlist[] = { "sys", "name", NULL };
1258 	char *sys  = NULL;
1259 	char *name = NULL;
1260 
1261 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
1262 					 &sys, &name))
1263 		return NULL;
1264 
1265 	tp_format = trace_event__tp_format(sys, name);
1266 	if (IS_ERR(tp_format))
1267 		return _PyLong_FromLong(-1);
1268 
1269 	return _PyLong_FromLong(tp_format->id);
1270 }
1271 
1272 static PyMethodDef perf__methods[] = {
1273 	{
1274 		.ml_name  = "tracepoint",
1275 		.ml_meth  = (PyCFunction) pyrf__tracepoint,
1276 		.ml_flags = METH_VARARGS | METH_KEYWORDS,
1277 		.ml_doc	  = PyDoc_STR("Get tracepoint config.")
1278 	},
1279 	{ .ml_name = NULL, }
1280 };
1281 
1282 #if PY_MAJOR_VERSION < 3
initperf(void)1283 PyMODINIT_FUNC initperf(void)
1284 #else
1285 PyMODINIT_FUNC PyInit_perf(void)
1286 #endif
1287 {
1288 	PyObject *obj;
1289 	int i;
1290 	PyObject *dict;
1291 #if PY_MAJOR_VERSION < 3
1292 	PyObject *module = Py_InitModule("perf", perf__methods);
1293 #else
1294 	static struct PyModuleDef moduledef = {
1295 		PyModuleDef_HEAD_INIT,
1296 		"perf",			/* m_name */
1297 		"",			/* m_doc */
1298 		-1,			/* m_size */
1299 		perf__methods,		/* m_methods */
1300 		NULL,			/* m_reload */
1301 		NULL,			/* m_traverse */
1302 		NULL,			/* m_clear */
1303 		NULL,			/* m_free */
1304 	};
1305 	PyObject *module = PyModule_Create(&moduledef);
1306 #endif
1307 
1308 	if (module == NULL ||
1309 	    pyrf_event__setup_types() < 0 ||
1310 	    pyrf_evlist__setup_types() < 0 ||
1311 	    pyrf_evsel__setup_types() < 0 ||
1312 	    pyrf_thread_map__setup_types() < 0 ||
1313 	    pyrf_cpu_map__setup_types() < 0)
1314 #if PY_MAJOR_VERSION < 3
1315 		return;
1316 #else
1317 		return module;
1318 #endif
1319 
1320 	/* The page_size is placed in util object. */
1321 	page_size = sysconf(_SC_PAGE_SIZE);
1322 
1323 	Py_INCREF(&pyrf_evlist__type);
1324 	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
1325 
1326 	Py_INCREF(&pyrf_evsel__type);
1327 	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1328 
1329 	Py_INCREF(&pyrf_mmap_event__type);
1330 	PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
1331 
1332 	Py_INCREF(&pyrf_lost_event__type);
1333 	PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
1334 
1335 	Py_INCREF(&pyrf_comm_event__type);
1336 	PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
1337 
1338 	Py_INCREF(&pyrf_task_event__type);
1339 	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1340 
1341 	Py_INCREF(&pyrf_throttle_event__type);
1342 	PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
1343 
1344 	Py_INCREF(&pyrf_task_event__type);
1345 	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1346 
1347 	Py_INCREF(&pyrf_read_event__type);
1348 	PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
1349 
1350 	Py_INCREF(&pyrf_sample_event__type);
1351 	PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
1352 
1353 	Py_INCREF(&pyrf_context_switch_event__type);
1354 	PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
1355 
1356 	Py_INCREF(&pyrf_thread_map__type);
1357 	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1358 
1359 	Py_INCREF(&pyrf_cpu_map__type);
1360 	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
1361 
1362 	dict = PyModule_GetDict(module);
1363 	if (dict == NULL)
1364 		goto error;
1365 
1366 	for (i = 0; perf__constants[i].name != NULL; i++) {
1367 		obj = _PyLong_FromLong(perf__constants[i].value);
1368 		if (obj == NULL)
1369 			goto error;
1370 		PyDict_SetItemString(dict, perf__constants[i].name, obj);
1371 		Py_DECREF(obj);
1372 	}
1373 
1374 error:
1375 	if (PyErr_Occurred())
1376 		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1377 #if PY_MAJOR_VERSION >= 3
1378 	return module;
1379 #endif
1380 }
1381 
1382 /*
1383  * Dummy, to avoid dragging all the test_attr infrastructure in the python
1384  * binding.
1385  */
test_attr__open(struct perf_event_attr * attr,pid_t pid,int cpu,int fd,int group_fd,unsigned long flags)1386 void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
1387                      int fd, int group_fd, unsigned long flags)
1388 {
1389 }
1390