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