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