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