1391 lines · 36.8 KB · C
RawDownload
	err = PyType_Ready(&pyrf_throttle_event__type);	if (err < 0)		goto out;	err = PyType_Ready(&pyrf_read_event__type);	if (err < 0)		goto out;	err = PyType_Ready(&pyrf_sample_event__type);	if (err < 0)		goto out;	err = PyType_Ready(&pyrf_context_switch_event__type);	if (err < 0)		goto out;out:	return err;} static PyTypeObject *pyrf_event__type[] = {	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,	[PERF_RECORD_READ]	 = &pyrf_read_event__type,	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,	[PERF_RECORD_SWITCH]	 = &pyrf_context_switch_event__type,	[PERF_RECORD_SWITCH_CPU_WIDE]  = &pyrf_context_switch_event__type,}; static PyObject *pyrf_event__new(union perf_event *event){	struct pyrf_event *pevent;	PyTypeObject *ptype; 	if ((event->header.type < PERF_RECORD_MMAP ||	     event->header.type > PERF_RECORD_SAMPLE) &&	    !(event->header.type == PERF_RECORD_SWITCH ||	      event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))		return NULL; 	ptype = pyrf_event__type[event->header.type];	pevent = PyObject_New(struct pyrf_event, ptype);	if (pevent != NULL)		memcpy(&pevent->event, event, event->header.size);	return (PyObject *)pevent;} struct pyrf_cpu_map {	PyObject_HEAD 	struct perf_cpu_map *cpus;}; static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,			      PyObject *args, PyObject *kwargs){	static char *kwlist[] = { "cpustr", NULL };	char *cpustr = NULL; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",					 kwlist, &cpustr))		return -1; 	pcpus->cpus = perf_cpu_map__new(cpustr);	if (pcpus->cpus == NULL)		return -1;	return 0;} static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus){	perf_cpu_map__put(pcpus->cpus);	Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);} static Py_ssize_t pyrf_cpu_map__length(PyObject *obj){	struct pyrf_cpu_map *pcpus = (void *)obj; 	return pcpus->cpus->nr;} static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i){	struct pyrf_cpu_map *pcpus = (void *)obj; 	if (i >= pcpus->cpus->nr)		return NULL; 	return Py_BuildValue("i", pcpus->cpus->map[i]);} static PySequenceMethods pyrf_cpu_map__sequence_methods = {	.sq_length = pyrf_cpu_map__length,	.sq_item   = pyrf_cpu_map__item,}; static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); static PyTypeObject pyrf_cpu_map__type = {	PyVarObject_HEAD_INIT(NULL, 0)	.tp_name	= "perf.cpu_map",	.tp_basicsize	= sizeof(struct pyrf_cpu_map),	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,	.tp_doc		= pyrf_cpu_map__doc,	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,	.tp_init	= (initproc)pyrf_cpu_map__init,}; static int pyrf_cpu_map__setup_types(void){	pyrf_cpu_map__type.tp_new = PyType_GenericNew;	return PyType_Ready(&pyrf_cpu_map__type);} struct pyrf_thread_map {	PyObject_HEAD 	struct perf_thread_map *threads;}; static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,				 PyObject *args, PyObject *kwargs){	static char *kwlist[] = { "pid", "tid", "uid", NULL };	int pid = -1, tid = -1, uid = UINT_MAX; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",					 kwlist, &pid, &tid, &uid))		return -1; 	pthreads->threads = thread_map__new(pid, tid, uid);	if (pthreads->threads == NULL)		return -1;	return 0;} static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads){	perf_thread_map__put(pthreads->threads);	Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);} static Py_ssize_t pyrf_thread_map__length(PyObject *obj){	struct pyrf_thread_map *pthreads = (void *)obj; 	return pthreads->threads->nr;} static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i){	struct pyrf_thread_map *pthreads = (void *)obj; 	if (i >= pthreads->threads->nr)		return NULL; 	return Py_BuildValue("i", pthreads->threads->map[i]);} static PySequenceMethods pyrf_thread_map__sequence_methods = {	.sq_length = pyrf_thread_map__length,	.sq_item   = pyrf_thread_map__item,}; static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); static PyTypeObject pyrf_thread_map__type = {	PyVarObject_HEAD_INIT(NULL, 0)	.tp_name	= "perf.thread_map",	.tp_basicsize	= sizeof(struct pyrf_thread_map),	.tp_dealloc	= (destructor)pyrf_thread_map__delete,	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,	.tp_doc		= pyrf_thread_map__doc,	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,	.tp_init	= (initproc)pyrf_thread_map__init,}; static int pyrf_thread_map__setup_types(void){	pyrf_thread_map__type.tp_new = PyType_GenericNew;	return PyType_Ready(&pyrf_thread_map__type);} struct pyrf_evsel {	PyObject_HEAD 	struct evsel evsel;}; static int pyrf_evsel__init(struct pyrf_evsel *pevsel,			    PyObject *args, PyObject *kwargs){	struct perf_event_attr attr = {		.type = PERF_TYPE_HARDWARE,		.config = PERF_COUNT_HW_CPU_CYCLES,		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,	};	static char *kwlist[] = {		"type",		"config",		"sample_freq",		"sample_period",		"sample_type",		"read_format",		"disabled",		"inherit",		"pinned",		"exclusive",		"exclude_user",		"exclude_kernel",		"exclude_hv",		"exclude_idle",		"mmap",		"context_switch",		"comm",		"freq",		"inherit_stat",		"enable_on_exec",		"task",		"watermark",		"precise_ip",		"mmap_data",		"sample_id_all",		"wakeup_events",		"bp_type",		"bp_addr",		"bp_len",		 NULL	};	u64 sample_period = 0;	u32 disabled = 0,	    inherit = 0,	    pinned = 0,	    exclusive = 0,	    exclude_user = 0,	    exclude_kernel = 0,	    exclude_hv = 0,	    exclude_idle = 0,	    mmap = 0,	    context_switch = 0,	    comm = 0,	    freq = 1,	    inherit_stat = 0,	    enable_on_exec = 0,	    task = 0,	    watermark = 0,	    precise_ip = 0,	    mmap_data = 0,	    sample_id_all = 1;	int idx = 0; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs,					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,					 &attr.type, &attr.config, &attr.sample_freq,					 &sample_period, &attr.sample_type,					 &attr.read_format, &disabled, &inherit,					 &pinned, &exclusive, &exclude_user,					 &exclude_kernel, &exclude_hv, &exclude_idle,					 &mmap, &context_switch, &comm, &freq, &inherit_stat,					 &enable_on_exec, &task, &watermark,					 &precise_ip, &mmap_data, &sample_id_all,					 &attr.wakeup_events, &attr.bp_type,					 &attr.bp_addr, &attr.bp_len, &idx))		return -1; 	/* union... */	if (sample_period != 0) {		if (attr.sample_freq != 0)			return -1; /* FIXME: throw right exception */		attr.sample_period = sample_period;	} 	/* Bitfields */	attr.disabled	    = disabled;	attr.inherit	    = inherit;	attr.pinned	    = pinned;	attr.exclusive	    = exclusive;	attr.exclude_user   = exclude_user;	attr.exclude_kernel = exclude_kernel;	attr.exclude_hv	    = exclude_hv;	attr.exclude_idle   = exclude_idle;	attr.mmap	    = mmap;	attr.context_switch = context_switch;	attr.comm	    = comm;	attr.freq	    = freq;	attr.inherit_stat   = inherit_stat;	attr.enable_on_exec = enable_on_exec;	attr.task	    = task;	attr.watermark	    = watermark;	attr.precise_ip	    = precise_ip;	attr.mmap_data	    = mmap_data;	attr.sample_id_all  = sample_id_all;	attr.size	    = sizeof(attr); 	evsel__init(&pevsel->evsel, &attr, idx);	return 0;} static void pyrf_evsel__delete(struct pyrf_evsel *pevsel){	evsel__exit(&pevsel->evsel);	Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);} static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,				  PyObject *args, PyObject *kwargs){	struct evsel *evsel = &pevsel->evsel;	struct perf_cpu_map *cpus = NULL;	struct perf_thread_map *threads = NULL;	PyObject *pcpus = NULL, *pthreads = NULL;	int group = 0, inherit = 0;	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,					 &pcpus, &pthreads, &group, &inherit))		return NULL; 	if (pthreads != NULL)		threads = ((struct pyrf_thread_map *)pthreads)->threads; 	if (pcpus != NULL)		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 	evsel->core.attr.inherit = inherit;	/*	 * This will group just the fds for this single evsel, to group	 * multiple events, use evlist.open().	 */	if (evsel__open(evsel, cpus, threads) < 0) {		PyErr_SetFromErrno(PyExc_OSError);		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;} static PyMethodDef pyrf_evsel__methods[] = {	{		.ml_name  = "open",		.ml_meth  = (PyCFunction)pyrf_evsel__open,		.ml_flags = METH_VARARGS | METH_KEYWORDS,		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")	},	{ .ml_name = NULL, }}; static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); static PyTypeObject pyrf_evsel__type = {	PyVarObject_HEAD_INIT(NULL, 0)	.tp_name	= "perf.evsel",	.tp_basicsize	= sizeof(struct pyrf_evsel),	.tp_dealloc	= (destructor)pyrf_evsel__delete,	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,	.tp_doc		= pyrf_evsel__doc,	.tp_methods	= pyrf_evsel__methods,	.tp_init	= (initproc)pyrf_evsel__init,}; static int pyrf_evsel__setup_types(void){	pyrf_evsel__type.tp_new = PyType_GenericNew;	return PyType_Ready(&pyrf_evsel__type);} struct pyrf_evlist {	PyObject_HEAD 	struct evlist evlist;}; static int pyrf_evlist__init(struct pyrf_evlist *pevlist,			     PyObject *args, PyObject *kwargs __maybe_unused){	PyObject *pcpus = NULL, *pthreads = NULL;	struct perf_cpu_map *cpus;	struct perf_thread_map *threads; 	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))		return -1; 	threads = ((struct pyrf_thread_map *)pthreads)->threads;	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;	evlist__init(&pevlist->evlist, cpus, threads);	return 0;} static void pyrf_evlist__delete(struct pyrf_evlist *pevlist){	evlist__exit(&pevlist->evlist);	Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);} static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,				   PyObject *args, PyObject *kwargs){	struct evlist *evlist = &pevlist->evlist;	static char *kwlist[] = { "pages", "overwrite", NULL };	int pages = 128, overwrite = false; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,					 &pages, &overwrite))		return NULL; 	if (evlist__mmap(evlist, pages) < 0) {		PyErr_SetFromErrno(PyExc_OSError);		return NULL;	} 	Py_INCREF(Py_None);	return Py_None;} static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,				   PyObject *args, PyObject *kwargs){	struct evlist *evlist = &pevlist->evlist;	static char *kwlist[] = { "timeout", NULL };	int timeout = -1, n; 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))		return NULL; 	n = evlist__poll(evlist, timeout);	if (n < 0) {		PyErr_SetFromErrno(PyExc_OSError);		return NULL;	} 	return Py_BuildValue("i", n);} static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,					 PyObject *args __maybe_unused,					 PyObject *kwargs __maybe_unused){	struct evlist *evlist = &pevlist->evlist;        PyObject *list = PyList_New(0);	int i; 	for (i = 0; i < evlist->core.pollfd.nr; ++i) {		PyObject *file;#if PY_MAJOR_VERSION < 3		FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r"); 		if (fp == NULL)			goto free_list; 		file = PyFile_FromFile(fp, "perf", "r", NULL);#else		file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1,				     NULL, NULL, NULL, 0);#endif		if (file == NULL)			goto free_list; 		if (PyList_Append(list, file) != 0) {			Py_DECREF(file);			goto free_list;		} 		Py_DECREF(file);	} 	return list;free_list:	return PyErr_NoMemory();}  static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,				  PyObject *args,				  PyObject *kwargs __maybe_unused){	struct evlist *evlist = &pevlist->evlist;	PyObject *pevsel;	struct evsel *evsel; 	if (!PyArg_ParseTuple(args, "O", &pevsel))		return NULL; 	Py_INCREF(pevsel);	evsel = &((struct pyrf_evsel *)pevsel)->evsel;	evsel->idx = evlist->core.nr_entries;	evlist__add(evlist, evsel); 	return Py_BuildValue("i", evlist->core.nr_entries);} static struct mmap *get_md(struct evlist *evlist, int cpu){	int i; 	for (i = 0; i < evlist->core.nr_mmaps; i++) {		struct mmap *md = &evlist->mmap[i];

Lines 501–1000 of 1391. Previous lines