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