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