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