History

perf python: Add function returning dictionary of all events on a PMU

Allow all events on a PMU to be gathered, similar to how perf list gathers event information. An example usage: ``` $ python Python 3.12.9 (main, Feb 5 2025, 01:31:18) [GCC 14.2.0] on linux >>> import perf >>> for pmu in perf.pmus(): ... print(pmu.events()) ... [{'name': 'mem_load_retired.l3_hit', 'desc': 'Retired load instructions... ```

Ian Rogers committed 1 year ago

Commit 2f20df51 parent 7f1f71a1 file · +71 −0Browse files

Unified · Split

tools/perf/util/python.c+71−0
@@ -670,6 +670,71 @@ static PyObject *pyrf_pmu__name(PyObject *self) · 669 unmodified lines
670670 return PyUnicode_FromString(ppmu->pmu->name);
671671 }
672672
673+static bool add_to_dict(PyObject *dict, const char *key, const char *value)
674+{
675+ PyObject *pkey, *pvalue;
676+ bool ret;
677+
678+ if (value == NULL)
679+ return true;
680+
681+ pkey = PyUnicode_FromString(key);
682+ pvalue = PyUnicode_FromString(value);
683+
684+ ret = pkey && pvalue && PyDict_SetItem(dict, pkey, pvalue) == 0;
685+ Py_XDECREF(pkey);
686+ Py_XDECREF(pvalue);
687+ return ret;
688+}
689+
690+static int pyrf_pmu__events_cb(void *state, struct pmu_event_info *info)
691+{
692+ PyObject *py_list = state;
693+ PyObject *dict = PyDict_New();
694+
695+ if (!dict)
696+ return -ENOMEM;
697+
698+ if (!add_to_dict(dict, "name", info->name) ||
699+ !add_to_dict(dict, "alias", info->alias) ||
700+ !add_to_dict(dict, "scale_unit", info->scale_unit) ||
701+ !add_to_dict(dict, "desc", info->desc) ||
702+ !add_to_dict(dict, "long_desc", info->long_desc) ||
703+ !add_to_dict(dict, "encoding_desc", info->encoding_desc) ||
704+ !add_to_dict(dict, "topic", info->topic) ||
705+ !add_to_dict(dict, "event_type_desc", info->event_type_desc) ||
706+ !add_to_dict(dict, "str", info->str) ||
707+ !add_to_dict(dict, "deprecated", info->deprecated ? "deprecated" : NULL) ||
708+ PyList_Append(py_list, dict) != 0) {
709+ Py_DECREF(dict);
710+ return -ENOMEM;
711+ }
712+ Py_DECREF(dict);
713+ return 0;
714+}
715+
716+static PyObject *pyrf_pmu__events(PyObject *self)
717+{
718+ struct pyrf_pmu *ppmu = (void *)self;
719+ PyObject *py_list = PyList_New(0);
720+ int ret;
721+
722+ if (!py_list)
723+ return NULL;
724+
725+ ret = perf_pmu__for_each_event(ppmu->pmu,
726+ /*skip_duplicate_pmus=*/false,
727+ py_list,
728+ pyrf_pmu__events_cb);
729+ if (ret) {
730+ Py_DECREF(py_list);
731+ errno = -ret;
732+ PyErr_SetFromErrno(PyExc_OSError);
733+ return NULL;
734+ }
735+ return py_list;
736+}
737+
673738 static PyObject *pyrf_pmu__repr(PyObject *self)
674739 {
675740 struct pyrf_pmu *ppmu = (void *)self;
@@ -680,6 +745,12 @@ static PyObject *pyrf_pmu__repr(PyObject *self) · 4 unmodified lines
680745 static const char pyrf_pmu__doc[] = PyDoc_STR("perf Performance Monitoring Unit (PMU) object.");
681746
682747 static PyMethodDef pyrf_pmu__methods[] = {
748+ {
749+ .ml_name = "events",
750+ .ml_meth = (PyCFunction)pyrf_pmu__events,
751+ .ml_flags = METH_NOARGS,
752+ .ml_doc = PyDoc_STR("Returns a sequence of events encoded as a dictionaries.")
753+ },
683754 {
684755 .ml_name = "name",
685756 .ml_meth = (PyCFunction)pyrf_pmu__name,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t