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
670 return PyUnicode_FromString(ppmu->pmu->name);670 return PyUnicode_FromString(ppmu->pmu->name);
671}671}
672 672
673static 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
690static 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
716static 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
673static PyObject *pyrf_pmu__repr(PyObject *self)738static PyObject *pyrf_pmu__repr(PyObject *self)
674{739{
675 struct pyrf_pmu *ppmu = (void *)self;740 struct pyrf_pmu *ppmu = (void *)self;
@@ -680,6 +745,12 @@ static PyObject *pyrf_pmu__repr(PyObject *self) · 4 unmodified lines
680static const char pyrf_pmu__doc[] = PyDoc_STR("perf Performance Monitoring Unit (PMU) object.");745static const char pyrf_pmu__doc[] = PyDoc_STR("perf Performance Monitoring Unit (PMU) object.");
681 746
682static PyMethodDef pyrf_pmu__methods[] = {747static 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 },
683 {754 {
684 .ml_name = "name",755 .ml_name = "name",
685 .ml_meth = (PyCFunction)pyrf_pmu__name,756 .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