Linux Audio

Check our new training course

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