mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-17 23:34:24 +00:00
perf python: Add support for 'struct perf_counts_values' to return counter data
Add support for the perf_counts_values struct to enable the python
bindings to read and return the counter data.
Committer notes:
Use T_ULONG instead of Py_T_ULONG, as all the other PyMemberDef arrays,
fixing the build with older python3 versions.
Use { .name = NULL, } to finish the new PyMemberDef
pyrf_counts_values_members array, again as the other arrays to please
some clang versions, ditto for PyGetSetDef.
Signed-off-by: Gautam Menghani <gautam@linux.ibm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20250519195148.1708988-5-irogers@google.com
Signed-off-by: Ian Rogers <irogers@google.com>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
committed by
Arnaldo Carvalho de Melo
parent
0589aff473
commit
3b4991dcb4
@@ -626,6 +626,92 @@ static int pyrf_thread_map__setup_types(void)
|
||||
return PyType_Ready(&pyrf_thread_map__type);
|
||||
}
|
||||
|
||||
struct pyrf_counts_values {
|
||||
PyObject_HEAD
|
||||
|
||||
struct perf_counts_values values;
|
||||
};
|
||||
|
||||
static const char pyrf_counts_values__doc[] = PyDoc_STR("perf counts values object.");
|
||||
|
||||
static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values)
|
||||
{
|
||||
Py_TYPE(pcounts_values)->tp_free((PyObject *)pcounts_values);
|
||||
}
|
||||
|
||||
#define counts_values_member_def(member, ptype, help) \
|
||||
{ #member, ptype, \
|
||||
offsetof(struct pyrf_counts_values, values.member), \
|
||||
0, help }
|
||||
|
||||
static PyMemberDef pyrf_counts_values_members[] = {
|
||||
counts_values_member_def(val, T_ULONG, "Value of event"),
|
||||
counts_values_member_def(ena, T_ULONG, "Time for which enabled"),
|
||||
counts_values_member_def(run, T_ULONG, "Time for which running"),
|
||||
counts_values_member_def(id, T_ULONG, "Unique ID for an event"),
|
||||
counts_values_member_def(lost, T_ULONG, "Num of lost samples"),
|
||||
{ .name = NULL, },
|
||||
};
|
||||
|
||||
static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self, void *closure)
|
||||
{
|
||||
PyObject *vals = PyList_New(5);
|
||||
|
||||
if (!vals)
|
||||
return NULL;
|
||||
for (int i = 0; i < 5; i++)
|
||||
PyList_SetItem(vals, i, PyLong_FromLong(self->values.values[i]));
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObject *list,
|
||||
void *closure)
|
||||
{
|
||||
Py_ssize_t size;
|
||||
PyObject *item = NULL;
|
||||
|
||||
if (!PyList_Check(list)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Value assigned must be a list");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size = PyList_Size(list);
|
||||
for (Py_ssize_t i = 0; i < size; i++) {
|
||||
item = PyList_GetItem(list, i);
|
||||
if (!PyLong_Check(item)) {
|
||||
PyErr_SetString(PyExc_TypeError, "List members should be numbers");
|
||||
return -1;
|
||||
}
|
||||
self->values.values[i] = PyLong_AsLong(item);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyGetSetDef pyrf_counts_values_getset[] = {
|
||||
{"values", (getter)pyrf_counts_values_get_values, (setter)pyrf_counts_values_set_values,
|
||||
"Name field", NULL},
|
||||
{ .name = NULL, },
|
||||
};
|
||||
|
||||
static PyTypeObject pyrf_counts_values__type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
.tp_name = "perf.counts_values",
|
||||
.tp_basicsize = sizeof(struct pyrf_counts_values),
|
||||
.tp_dealloc = (destructor)pyrf_counts_values__delete,
|
||||
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
|
||||
.tp_doc = pyrf_counts_values__doc,
|
||||
.tp_members = pyrf_counts_values_members,
|
||||
.tp_getset = pyrf_counts_values_getset,
|
||||
};
|
||||
|
||||
static int pyrf_counts_values__setup_types(void)
|
||||
{
|
||||
pyrf_counts_values__type.tp_new = PyType_GenericNew;
|
||||
return PyType_Ready(&pyrf_counts_values__type);
|
||||
}
|
||||
|
||||
struct pyrf_evsel {
|
||||
PyObject_HEAD
|
||||
|
||||
@@ -1475,7 +1561,8 @@ PyMODINIT_FUNC PyInit_perf(void)
|
||||
pyrf_evlist__setup_types() < 0 ||
|
||||
pyrf_evsel__setup_types() < 0 ||
|
||||
pyrf_thread_map__setup_types() < 0 ||
|
||||
pyrf_cpu_map__setup_types() < 0)
|
||||
pyrf_cpu_map__setup_types() < 0 ||
|
||||
pyrf_counts_values__setup_types() < 0)
|
||||
return module;
|
||||
|
||||
/* The page_size is placed in util object. */
|
||||
@@ -1520,6 +1607,9 @@ PyMODINIT_FUNC PyInit_perf(void)
|
||||
Py_INCREF(&pyrf_cpu_map__type);
|
||||
PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
|
||||
|
||||
Py_INCREF(&pyrf_counts_values__type);
|
||||
PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);
|
||||
|
||||
dict = PyModule_GetDict(module);
|
||||
if (dict == NULL)
|
||||
goto error;
|
||||
|
||||
Reference in New Issue
Block a user