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