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 Load more
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];