Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[pandora-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 /* 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 int pyrf_event__setup_types(void)
191 {
192         int err;
193         pyrf_mmap_event__type.tp_new =
194         pyrf_task_event__type.tp_new =
195         pyrf_comm_event__type.tp_new =
196         pyrf_throttle_event__type.tp_new = PyType_GenericNew;
197         err = PyType_Ready(&pyrf_mmap_event__type);
198         if (err < 0)
199                 goto out;
200         err = PyType_Ready(&pyrf_task_event__type);
201         if (err < 0)
202                 goto out;
203         err = PyType_Ready(&pyrf_comm_event__type);
204         if (err < 0)
205                 goto out;
206         err = PyType_Ready(&pyrf_throttle_event__type);
207         if (err < 0)
208                 goto out;
209 out:
210         return err;
211 }
212
213 static PyTypeObject *pyrf_event__type[] = {
214         [PERF_RECORD_MMAP]       = &pyrf_mmap_event__type,
215         [PERF_RECORD_LOST]       = &pyrf_mmap_event__type,
216         [PERF_RECORD_COMM]       = &pyrf_comm_event__type,
217         [PERF_RECORD_EXIT]       = &pyrf_task_event__type,
218         [PERF_RECORD_THROTTLE]   = &pyrf_throttle_event__type,
219         [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
220         [PERF_RECORD_FORK]       = &pyrf_task_event__type,
221         [PERF_RECORD_READ]       = &pyrf_mmap_event__type,
222         [PERF_RECORD_SAMPLE]     = &pyrf_mmap_event__type,
223 };
224
225 static PyObject *pyrf_event__new(union perf_event *event)
226 {
227         struct pyrf_event *pevent;
228         PyTypeObject *ptype;
229
230         if (event->header.type < PERF_RECORD_MMAP ||
231             event->header.type > PERF_RECORD_SAMPLE)
232                 return NULL;
233
234         ptype = pyrf_event__type[event->header.type];
235         pevent = PyObject_New(struct pyrf_event, ptype);
236         if (pevent != NULL)
237                 memcpy(&pevent->event, event, event->header.size);
238         return (PyObject *)pevent;
239 }
240
241 struct pyrf_cpu_map {
242         PyObject_HEAD
243
244         struct cpu_map *cpus;
245 };
246
247 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
248                               PyObject *args, PyObject *kwargs)
249 {
250         static char *kwlist[] = { "cpustr", NULL, NULL, };
251         char *cpustr = NULL;
252
253         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
254                                          kwlist, &cpustr))
255                 return -1;
256
257         pcpus->cpus = cpu_map__new(cpustr);
258         if (pcpus->cpus == NULL)
259                 return -1;
260         return 0;
261 }
262
263 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
264 {
265         cpu_map__delete(pcpus->cpus);
266         pcpus->ob_type->tp_free((PyObject*)pcpus);
267 }
268
269 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
270 {
271         struct pyrf_cpu_map *pcpus = (void *)obj;
272
273         return pcpus->cpus->nr;
274 }
275
276 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
277 {
278         struct pyrf_cpu_map *pcpus = (void *)obj;
279
280         if (i >= pcpus->cpus->nr)
281                 return NULL;
282
283         return Py_BuildValue("i", pcpus->cpus->map[i]);
284 }
285
286 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
287         .sq_length = pyrf_cpu_map__length,
288         .sq_item   = pyrf_cpu_map__item,
289 };
290
291 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
292
293 static PyTypeObject pyrf_cpu_map__type = {
294         PyVarObject_HEAD_INIT(NULL, 0)
295         .tp_name        = "perf.cpu_map",
296         .tp_basicsize   = sizeof(struct pyrf_cpu_map),
297         .tp_dealloc     = (destructor)pyrf_cpu_map__delete,
298         .tp_flags       = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
299         .tp_doc         = pyrf_cpu_map__doc,
300         .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
301         .tp_init        = (initproc)pyrf_cpu_map__init,
302 };
303
304 static int pyrf_cpu_map__setup_types(void)
305 {
306         pyrf_cpu_map__type.tp_new = PyType_GenericNew;
307         return PyType_Ready(&pyrf_cpu_map__type);
308 }
309
310 struct pyrf_thread_map {
311         PyObject_HEAD
312
313         struct thread_map *threads;
314 };
315
316 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
317                                  PyObject *args, PyObject *kwargs)
318 {
319         static char *kwlist[] = { "pid", "tid", NULL, NULL, };
320         int pid = -1, tid = -1;
321
322         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
323                                          kwlist, &pid, &tid))
324                 return -1;
325
326         pthreads->threads = thread_map__new(pid, tid);
327         if (pthreads->threads == NULL)
328                 return -1;
329         return 0;
330 }
331
332 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
333 {
334         thread_map__delete(pthreads->threads);
335         pthreads->ob_type->tp_free((PyObject*)pthreads);
336 }
337
338 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
339 {
340         struct pyrf_thread_map *pthreads = (void *)obj;
341
342         return pthreads->threads->nr;
343 }
344
345 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
346 {
347         struct pyrf_thread_map *pthreads = (void *)obj;
348
349         if (i >= pthreads->threads->nr)
350                 return NULL;
351
352         return Py_BuildValue("i", pthreads->threads->map[i]);
353 }
354
355 static PySequenceMethods pyrf_thread_map__sequence_methods = {
356         .sq_length = pyrf_thread_map__length,
357         .sq_item   = pyrf_thread_map__item,
358 };
359
360 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
361
362 static PyTypeObject pyrf_thread_map__type = {
363         PyVarObject_HEAD_INIT(NULL, 0)
364         .tp_name        = "perf.thread_map",
365         .tp_basicsize   = sizeof(struct pyrf_thread_map),
366         .tp_dealloc     = (destructor)pyrf_thread_map__delete,
367         .tp_flags       = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
368         .tp_doc         = pyrf_thread_map__doc,
369         .tp_as_sequence = &pyrf_thread_map__sequence_methods,
370         .tp_init        = (initproc)pyrf_thread_map__init,
371 };
372
373 static int pyrf_thread_map__setup_types(void)
374 {
375         pyrf_thread_map__type.tp_new = PyType_GenericNew;
376         return PyType_Ready(&pyrf_thread_map__type);
377 }
378
379 struct pyrf_evsel {
380         PyObject_HEAD
381
382         struct perf_evsel evsel;
383 };
384
385 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
386                             PyObject *args, PyObject *kwargs)
387 {
388         struct perf_event_attr attr = {
389                 .type = PERF_TYPE_HARDWARE,
390                 .config = PERF_COUNT_HW_CPU_CYCLES,
391                 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
392         };
393         static char *kwlist[] = {
394                 "type",
395                 "config",
396                 "sample_freq",
397                 "sample_period",
398                 "sample_type",
399                 "read_format",
400                 "disabled",
401                 "inherit",
402                 "pinned",
403                 "exclusive",
404                 "exclude_user",
405                 "exclude_kernel",
406                 "exclude_hv",
407                 "exclude_idle",
408                 "mmap",
409                 "comm",
410                 "freq",
411                 "inherit_stat",
412                 "enable_on_exec",
413                 "task",
414                 "watermark",
415                 "precise_ip",
416                 "mmap_data",
417                 "sample_id_all",
418                 "wakeup_events",
419                 "bp_type",
420                 "bp_addr",
421                 "bp_len", NULL, NULL, };
422         u64 sample_period = 0;
423         u32 disabled = 0,
424             inherit = 0,
425             pinned = 0,
426             exclusive = 0,
427             exclude_user = 0,
428             exclude_kernel = 0,
429             exclude_hv = 0,
430             exclude_idle = 0,
431             mmap = 0,
432             comm = 0,
433             freq = 1,
434             inherit_stat = 0,
435             enable_on_exec = 0,
436             task = 0,
437             watermark = 0,
438             precise_ip = 0,
439             mmap_data = 0,
440             sample_id_all = 1;
441         int idx = 0;
442
443         if (!PyArg_ParseTupleAndKeywords(args, kwargs,
444                                          "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
445                                          &attr.type, &attr.config, &attr.sample_freq,
446                                          &sample_period, &attr.sample_type,
447                                          &attr.read_format, &disabled, &inherit,
448                                          &pinned, &exclusive, &exclude_user,
449                                          &exclude_kernel, &exclude_hv, &exclude_idle,
450                                          &mmap, &comm, &freq, &inherit_stat,
451                                          &enable_on_exec, &task, &watermark,
452                                          &precise_ip, &mmap_data, &sample_id_all,
453                                          &attr.wakeup_events, &attr.bp_type,
454                                          &attr.bp_addr, &attr.bp_len, &idx))
455                 return -1;
456
457         /* union... */
458         if (sample_period != 0) {
459                 if (attr.sample_freq != 0)
460                         return -1; /* FIXME: throw right exception */
461                 attr.sample_period = sample_period;
462         }
463
464         /* Bitfields */
465         attr.disabled       = disabled;
466         attr.inherit        = inherit;
467         attr.pinned         = pinned;
468         attr.exclusive      = exclusive;
469         attr.exclude_user   = exclude_user;
470         attr.exclude_kernel = exclude_kernel;
471         attr.exclude_hv     = exclude_hv;
472         attr.exclude_idle   = exclude_idle;
473         attr.mmap           = mmap;
474         attr.comm           = comm;
475         attr.freq           = freq;
476         attr.inherit_stat   = inherit_stat;
477         attr.enable_on_exec = enable_on_exec;
478         attr.task           = task;
479         attr.watermark      = watermark;
480         attr.precise_ip     = precise_ip;
481         attr.mmap_data      = mmap_data;
482         attr.sample_id_all  = sample_id_all;
483
484         perf_evsel__init(&pevsel->evsel, &attr, idx);
485         return 0;
486 }
487
488 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
489 {
490         perf_evsel__exit(&pevsel->evsel);
491         pevsel->ob_type->tp_free((PyObject*)pevsel);
492 }
493
494 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
495                                   PyObject *args, PyObject *kwargs)
496 {
497         struct perf_evsel *evsel = &pevsel->evsel;
498         struct cpu_map *cpus = NULL;
499         struct thread_map *threads = NULL;
500         PyObject *pcpus = NULL, *pthreads = NULL;
501         int group = 0, inherit = 0;
502         static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL};
503
504         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
505                                          &pcpus, &pthreads, &group, &inherit))
506                 return NULL;
507
508         if (pthreads != NULL)
509                 threads = ((struct pyrf_thread_map *)pthreads)->threads;
510
511         if (pcpus != NULL)
512                 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
513
514         evsel->attr.inherit = inherit;
515         if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
516                 PyErr_SetFromErrno(PyExc_OSError);
517                 return NULL;
518         }
519
520         Py_INCREF(Py_None);
521         return Py_None;
522 }
523
524 static PyMethodDef pyrf_evsel__methods[] = {
525         {
526                 .ml_name  = "open",
527                 .ml_meth  = (PyCFunction)pyrf_evsel__open,
528                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
529                 .ml_doc   = PyDoc_STR("open the event selector file descriptor table.")
530         },
531         { .ml_name = NULL, }
532 };
533
534 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
535
536 static PyTypeObject pyrf_evsel__type = {
537         PyVarObject_HEAD_INIT(NULL, 0)
538         .tp_name        = "perf.evsel",
539         .tp_basicsize   = sizeof(struct pyrf_evsel),
540         .tp_dealloc     = (destructor)pyrf_evsel__delete,
541         .tp_flags       = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
542         .tp_doc         = pyrf_evsel__doc,
543         .tp_methods     = pyrf_evsel__methods,
544         .tp_init        = (initproc)pyrf_evsel__init,
545 };
546
547 static int pyrf_evsel__setup_types(void)
548 {
549         pyrf_evsel__type.tp_new = PyType_GenericNew;
550         return PyType_Ready(&pyrf_evsel__type);
551 }
552
553 struct pyrf_evlist {
554         PyObject_HEAD
555
556         struct perf_evlist evlist;
557 };
558
559 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
560                              PyObject *args, PyObject *kwargs __used)
561 {
562         PyObject *pcpus = NULL, *pthreads = NULL;
563         struct cpu_map *cpus;
564         struct thread_map *threads;
565
566         if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
567                 return -1;
568
569         threads = ((struct pyrf_thread_map *)pthreads)->threads;
570         cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
571         perf_evlist__init(&pevlist->evlist, cpus, threads);
572         return 0;
573 }
574
575 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
576 {
577         perf_evlist__exit(&pevlist->evlist);
578         pevlist->ob_type->tp_free((PyObject*)pevlist);
579 }
580
581 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
582                                    PyObject *args, PyObject *kwargs)
583 {
584         struct perf_evlist *evlist = &pevlist->evlist;
585         static char *kwlist[] = {"pages", "overwrite",
586                                   NULL, NULL};
587         int pages = 128, overwrite = false;
588
589         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
590                                          &pages, &overwrite))
591                 return NULL;
592
593         if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
594                 PyErr_SetFromErrno(PyExc_OSError);
595                 return NULL;
596         }
597
598         Py_INCREF(Py_None);
599         return Py_None;
600 }
601
602 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
603                                    PyObject *args, PyObject *kwargs)
604 {
605         struct perf_evlist *evlist = &pevlist->evlist;
606         static char *kwlist[] = {"timeout", NULL, NULL};
607         int timeout = -1, n;
608
609         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
610                 return NULL;
611
612         n = poll(evlist->pollfd, evlist->nr_fds, timeout);
613         if (n < 0) {
614                 PyErr_SetFromErrno(PyExc_OSError);
615                 return NULL;
616         }
617
618         return Py_BuildValue("i", n);
619 }
620
621 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
622                                          PyObject *args __used, PyObject *kwargs __used)
623 {
624         struct perf_evlist *evlist = &pevlist->evlist;
625         PyObject *list = PyList_New(0);
626         int i;
627
628         for (i = 0; i < evlist->nr_fds; ++i) {
629                 PyObject *file;
630                 FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
631
632                 if (fp == NULL)
633                         goto free_list;
634
635                 file = PyFile_FromFile(fp, "perf", "r", NULL);
636                 if (file == NULL)
637                         goto free_list;
638
639                 if (PyList_Append(list, file) != 0) {
640                         Py_DECREF(file);
641                         goto free_list;
642                 }
643                         
644                 Py_DECREF(file);
645         }
646
647         return list;
648 free_list:
649         return PyErr_NoMemory();
650 }
651
652
653 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
654                                   PyObject *args, PyObject *kwargs __used)
655 {
656         struct perf_evlist *evlist = &pevlist->evlist;
657         PyObject *pevsel;
658         struct perf_evsel *evsel;
659
660         if (!PyArg_ParseTuple(args, "O", &pevsel))
661                 return NULL;
662
663         Py_INCREF(pevsel);
664         evsel = &((struct pyrf_evsel *)pevsel)->evsel;
665         evsel->idx = evlist->nr_entries;
666         perf_evlist__add(evlist, evsel);
667
668         return Py_BuildValue("i", evlist->nr_entries);
669 }
670
671 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
672                                           PyObject *args, PyObject *kwargs)
673 {
674         struct perf_evlist *evlist = &pevlist->evlist;
675         union perf_event *event;
676         int sample_id_all = 1, cpu;
677         static char *kwlist[] = {"sample_id_all", NULL, NULL};
678
679         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
680                                          &cpu, &sample_id_all))
681                 return NULL;
682
683         event = perf_evlist__read_on_cpu(evlist, cpu);
684         if (event != NULL) {
685                 struct perf_evsel *first;
686                 PyObject *pyevent = pyrf_event__new(event);
687                 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
688
689                 if (pyevent == NULL)
690                         return PyErr_NoMemory();
691
692                 first = list_entry(evlist->entries.next, struct perf_evsel, node);
693                 perf_event__parse_sample(event, first->attr.sample_type, sample_id_all,
694                                          &pevent->sample);
695                 return pyevent;
696         }
697
698         Py_INCREF(Py_None);
699         return Py_None;
700 }
701
702 static PyMethodDef pyrf_evlist__methods[] = {
703         {
704                 .ml_name  = "mmap",
705                 .ml_meth  = (PyCFunction)pyrf_evlist__mmap,
706                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
707                 .ml_doc   = PyDoc_STR("mmap the file descriptor table.")
708         },
709         {
710                 .ml_name  = "poll",
711                 .ml_meth  = (PyCFunction)pyrf_evlist__poll,
712                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
713                 .ml_doc   = PyDoc_STR("poll the file descriptor table.")
714         },
715         {
716                 .ml_name  = "get_pollfd",
717                 .ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
718                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
719                 .ml_doc   = PyDoc_STR("get the poll file descriptor table.")
720         },
721         {
722                 .ml_name  = "add",
723                 .ml_meth  = (PyCFunction)pyrf_evlist__add,
724                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
725                 .ml_doc   = PyDoc_STR("adds an event selector to the list.")
726         },
727         {
728                 .ml_name  = "read_on_cpu",
729                 .ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
730                 .ml_flags = METH_VARARGS | METH_KEYWORDS,
731                 .ml_doc   = PyDoc_STR("reads an event.")
732         },
733         { .ml_name = NULL, }
734 };
735
736 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
737 {
738         struct pyrf_evlist *pevlist = (void *)obj;
739
740         return pevlist->evlist.nr_entries;
741 }
742
743 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
744 {
745         struct pyrf_evlist *pevlist = (void *)obj;
746         struct perf_evsel *pos;
747
748         if (i >= pevlist->evlist.nr_entries)
749                 return NULL;
750
751         list_for_each_entry(pos, &pevlist->evlist.entries, node)
752                 if (i-- == 0)
753                         break;
754
755         return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
756 }
757
758 static PySequenceMethods pyrf_evlist__sequence_methods = {
759         .sq_length = pyrf_evlist__length,
760         .sq_item   = pyrf_evlist__item,
761 };
762
763 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
764
765 static PyTypeObject pyrf_evlist__type = {
766         PyVarObject_HEAD_INIT(NULL, 0)
767         .tp_name        = "perf.evlist",
768         .tp_basicsize   = sizeof(struct pyrf_evlist),
769         .tp_dealloc     = (destructor)pyrf_evlist__delete,
770         .tp_flags       = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
771         .tp_as_sequence = &pyrf_evlist__sequence_methods,
772         .tp_doc         = pyrf_evlist__doc,
773         .tp_methods     = pyrf_evlist__methods,
774         .tp_init        = (initproc)pyrf_evlist__init,
775 };
776
777 static int pyrf_evlist__setup_types(void)
778 {
779         pyrf_evlist__type.tp_new = PyType_GenericNew;
780         return PyType_Ready(&pyrf_evlist__type);
781 }
782
783 static struct {
784         const char *name;
785         int         value;
786 } perf__constants[] = {
787         { "TYPE_HARDWARE",   PERF_TYPE_HARDWARE },
788         { "TYPE_SOFTWARE",   PERF_TYPE_SOFTWARE },
789         { "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
790         { "TYPE_HW_CACHE",   PERF_TYPE_HW_CACHE },
791         { "TYPE_RAW",        PERF_TYPE_RAW },
792         { "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
793
794         { "COUNT_HW_CPU_CYCLES",          PERF_COUNT_HW_CPU_CYCLES },
795         { "COUNT_HW_INSTRUCTIONS",        PERF_COUNT_HW_INSTRUCTIONS },
796         { "COUNT_HW_CACHE_REFERENCES",    PERF_COUNT_HW_CACHE_REFERENCES },
797         { "COUNT_HW_CACHE_MISSES",        PERF_COUNT_HW_CACHE_MISSES },
798         { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
799         { "COUNT_HW_BRANCH_MISSES",       PERF_COUNT_HW_BRANCH_MISSES },
800         { "COUNT_HW_BUS_CYCLES",          PERF_COUNT_HW_BUS_CYCLES },
801         { "COUNT_HW_CACHE_L1D",           PERF_COUNT_HW_CACHE_L1D },
802         { "COUNT_HW_CACHE_L1I",           PERF_COUNT_HW_CACHE_L1I },
803         { "COUNT_HW_CACHE_LL",            PERF_COUNT_HW_CACHE_LL },
804         { "COUNT_HW_CACHE_DTLB",          PERF_COUNT_HW_CACHE_DTLB },
805         { "COUNT_HW_CACHE_ITLB",          PERF_COUNT_HW_CACHE_ITLB },
806         { "COUNT_HW_CACHE_BPU",           PERF_COUNT_HW_CACHE_BPU },
807         { "COUNT_HW_CACHE_OP_READ",       PERF_COUNT_HW_CACHE_OP_READ },
808         { "COUNT_HW_CACHE_OP_WRITE",      PERF_COUNT_HW_CACHE_OP_WRITE },
809         { "COUNT_HW_CACHE_OP_PREFETCH",   PERF_COUNT_HW_CACHE_OP_PREFETCH },
810         { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
811         { "COUNT_HW_CACHE_RESULT_MISS",   PERF_COUNT_HW_CACHE_RESULT_MISS },
812
813         { "COUNT_SW_CPU_CLOCK",        PERF_COUNT_SW_CPU_CLOCK },
814         { "COUNT_SW_TASK_CLOCK",       PERF_COUNT_SW_TASK_CLOCK },
815         { "COUNT_SW_PAGE_FAULTS",      PERF_COUNT_SW_PAGE_FAULTS },
816         { "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
817         { "COUNT_SW_CPU_MIGRATIONS",   PERF_COUNT_SW_CPU_MIGRATIONS },
818         { "COUNT_SW_PAGE_FAULTS_MIN",  PERF_COUNT_SW_PAGE_FAULTS_MIN },
819         { "COUNT_SW_PAGE_FAULTS_MAJ",  PERF_COUNT_SW_PAGE_FAULTS_MAJ },
820         { "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
821         { "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
822
823         { "SAMPLE_IP",        PERF_SAMPLE_IP },
824         { "SAMPLE_TID",       PERF_SAMPLE_TID },
825         { "SAMPLE_TIME",      PERF_SAMPLE_TIME },
826         { "SAMPLE_ADDR",      PERF_SAMPLE_ADDR },
827         { "SAMPLE_READ",      PERF_SAMPLE_READ },
828         { "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
829         { "SAMPLE_ID",        PERF_SAMPLE_ID },
830         { "SAMPLE_CPU",       PERF_SAMPLE_CPU },
831         { "SAMPLE_PERIOD",    PERF_SAMPLE_PERIOD },
832         { "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
833         { "SAMPLE_RAW",       PERF_SAMPLE_RAW },
834
835         { "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
836         { "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
837         { "FORMAT_ID",                 PERF_FORMAT_ID },
838         { "FORMAT_GROUP",              PERF_FORMAT_GROUP },
839
840         { "RECORD_MMAP",       PERF_RECORD_MMAP },
841         { "RECORD_LOST",       PERF_RECORD_LOST },
842         { "RECORD_COMM",       PERF_RECORD_COMM },
843         { "RECORD_EXIT",       PERF_RECORD_EXIT },
844         { "RECORD_THROTTLE",   PERF_RECORD_THROTTLE },
845         { "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
846         { "RECORD_FORK",       PERF_RECORD_FORK },
847         { "RECORD_READ",       PERF_RECORD_READ },
848         { "RECORD_SAMPLE",     PERF_RECORD_SAMPLE },
849         { .name = NULL, },
850 };
851
852 static PyMethodDef perf__methods[] = {
853         { .ml_name = NULL, }
854 };
855
856 PyMODINIT_FUNC initperf(void)
857 {
858         PyObject *obj;
859         int i;
860         PyObject *dict, *module = Py_InitModule("perf", perf__methods);
861
862         if (module == NULL ||
863             pyrf_event__setup_types() < 0 ||
864             pyrf_evlist__setup_types() < 0 ||
865             pyrf_evsel__setup_types() < 0 ||
866             pyrf_thread_map__setup_types() < 0 ||
867             pyrf_cpu_map__setup_types() < 0)
868                 return;
869
870         Py_INCREF(&pyrf_evlist__type);
871         PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
872
873         Py_INCREF(&pyrf_evsel__type);
874         PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
875
876         Py_INCREF(&pyrf_thread_map__type);
877         PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
878
879         Py_INCREF(&pyrf_cpu_map__type);
880         PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
881
882         dict = PyModule_GetDict(module);
883         if (dict == NULL)
884                 goto error;
885
886         for (i = 0; perf__constants[i].name != NULL; i++) {
887                 obj = PyInt_FromLong(perf__constants[i].value);
888                 if (obj == NULL)
889                         goto error;
890                 PyDict_SetItemString(dict, perf__constants[i].name, obj);
891                 Py_DECREF(obj);
892         }
893
894 error:
895         if (PyErr_Occurred())
896                 PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
897 }