at v4.13 36 kB view raw
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 */ 18struct callchain_param callchain_param; 19 20int 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 */ 30int verbose; 31 32int 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 51PyMODINIT_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 63struct 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 81static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); 82 83static 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 96static 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 115static 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 125static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); 126 127static 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 138static 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 150static 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 160static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); 161 162static 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 171static 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 179static 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 189static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); 190 191static 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 200static 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 210static 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 220static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); 221 222static 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 229static 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 245static 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 255static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); 256 257static 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 264static 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 275static 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 285static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); 286 287static PyMemberDef pyrf_sample_event__members[] = { 288 sample_members 289 member_def(perf_event_header, type, T_UINT, "event type"), 290 { .name = NULL, }, 291}; 292 293static 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 307static bool is_tracepoint(struct pyrf_event *pevent) 308{ 309 return pevent->evsel->attr.type == PERF_TYPE_TRACEPOINT; 310} 311 312static PyObject* 313tracepoint_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 351static PyObject* 352get_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 375static PyObject* 376pyrf_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 386static 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 397static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 398 399static 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 407static 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 424static 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 434static 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; 469out: 470 return err; 471} 472 473static 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 487static 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 505struct pyrf_cpu_map { 506 PyObject_HEAD 507 508 struct cpu_map *cpus; 509}; 510 511static 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 527static 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 533static 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 540static 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 550static PySequenceMethods pyrf_cpu_map__sequence_methods = { 551 .sq_length = pyrf_cpu_map__length, 552 .sq_item = pyrf_cpu_map__item, 553}; 554 555static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); 556 557static 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 568static 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 574struct pyrf_thread_map { 575 PyObject_HEAD 576 577 struct thread_map *threads; 578}; 579 580static 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 596static 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 602static 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 609static 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 619static PySequenceMethods pyrf_thread_map__sequence_methods = { 620 .sq_length = pyrf_thread_map__length, 621 .sq_item = pyrf_thread_map__item, 622}; 623 624static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); 625 626static 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 637static 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 643struct pyrf_evsel { 644 PyObject_HEAD 645 646 struct perf_evsel evsel; 647}; 648 649static 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 758static 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 764static 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 798static 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 808static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); 809 810static 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 821static int pyrf_evsel__setup_types(void) 822{ 823 pyrf_evsel__type.tp_new = PyType_GenericNew; 824 return PyType_Ready(&pyrf_evsel__type); 825} 826 827struct pyrf_evlist { 828 PyObject_HEAD 829 830 struct perf_evlist evlist; 831}; 832 833static 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 849static 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 855static 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 875static 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 894static 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; 922free_list: 923 return PyErr_NoMemory(); 924} 925 926 927static 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 946static 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 989static 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 1011static 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 1051static 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 1058static 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 1074static PySequenceMethods pyrf_evlist__sequence_methods = { 1075 .sq_length = pyrf_evlist__length, 1076 .sq_item = pyrf_evlist__item, 1077}; 1078 1079static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object."); 1080 1081static 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 1093static 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 1101static 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 1182static 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 1201static 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 1211PyMODINIT_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 1279error: 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 */ 1288void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 1289 int fd, int group_fd, unsigned long flags) 1290{ 1291}