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