• 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