Skip to content

Commit 3b4991d

Browse files
Gautam Menghaniacmel
authored andcommitted
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 <[email protected]> Tested-by: Arnaldo Carvalho de Melo <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Howard Chu <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Madhavan Srinivasan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ian Rogers <[email protected]> Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 0589aff commit 3b4991d

File tree

1 file changed

+91
-1
lines changed

1 file changed

+91
-1
lines changed

tools/perf/util/python.c

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,92 @@ static int pyrf_thread_map__setup_types(void)
626626
return PyType_Ready(&pyrf_thread_map__type);
627627
}
628628

629+
struct pyrf_counts_values {
630+
PyObject_HEAD
631+
632+
struct perf_counts_values values;
633+
};
634+
635+
static const char pyrf_counts_values__doc[] = PyDoc_STR("perf counts values object.");
636+
637+
static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values)
638+
{
639+
Py_TYPE(pcounts_values)->tp_free((PyObject *)pcounts_values);
640+
}
641+
642+
#define counts_values_member_def(member, ptype, help) \
643+
{ #member, ptype, \
644+
offsetof(struct pyrf_counts_values, values.member), \
645+
0, help }
646+
647+
static PyMemberDef pyrf_counts_values_members[] = {
648+
counts_values_member_def(val, T_ULONG, "Value of event"),
649+
counts_values_member_def(ena, T_ULONG, "Time for which enabled"),
650+
counts_values_member_def(run, T_ULONG, "Time for which running"),
651+
counts_values_member_def(id, T_ULONG, "Unique ID for an event"),
652+
counts_values_member_def(lost, T_ULONG, "Num of lost samples"),
653+
{ .name = NULL, },
654+
};
655+
656+
static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self, void *closure)
657+
{
658+
PyObject *vals = PyList_New(5);
659+
660+
if (!vals)
661+
return NULL;
662+
for (int i = 0; i < 5; i++)
663+
PyList_SetItem(vals, i, PyLong_FromLong(self->values.values[i]));
664+
665+
return vals;
666+
}
667+
668+
static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObject *list,
669+
void *closure)
670+
{
671+
Py_ssize_t size;
672+
PyObject *item = NULL;
673+
674+
if (!PyList_Check(list)) {
675+
PyErr_SetString(PyExc_TypeError, "Value assigned must be a list");
676+
return -1;
677+
}
678+
679+
size = PyList_Size(list);
680+
for (Py_ssize_t i = 0; i < size; i++) {
681+
item = PyList_GetItem(list, i);
682+
if (!PyLong_Check(item)) {
683+
PyErr_SetString(PyExc_TypeError, "List members should be numbers");
684+
return -1;
685+
}
686+
self->values.values[i] = PyLong_AsLong(item);
687+
}
688+
689+
return 0;
690+
}
691+
692+
static PyGetSetDef pyrf_counts_values_getset[] = {
693+
{"values", (getter)pyrf_counts_values_get_values, (setter)pyrf_counts_values_set_values,
694+
"Name field", NULL},
695+
{ .name = NULL, },
696+
};
697+
698+
static PyTypeObject pyrf_counts_values__type = {
699+
PyVarObject_HEAD_INIT(NULL, 0)
700+
.tp_name = "perf.counts_values",
701+
.tp_basicsize = sizeof(struct pyrf_counts_values),
702+
.tp_dealloc = (destructor)pyrf_counts_values__delete,
703+
.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
704+
.tp_doc = pyrf_counts_values__doc,
705+
.tp_members = pyrf_counts_values_members,
706+
.tp_getset = pyrf_counts_values_getset,
707+
};
708+
709+
static int pyrf_counts_values__setup_types(void)
710+
{
711+
pyrf_counts_values__type.tp_new = PyType_GenericNew;
712+
return PyType_Ready(&pyrf_counts_values__type);
713+
}
714+
629715
struct pyrf_evsel {
630716
PyObject_HEAD
631717

@@ -1475,7 +1561,8 @@ PyMODINIT_FUNC PyInit_perf(void)
14751561
pyrf_evlist__setup_types() < 0 ||
14761562
pyrf_evsel__setup_types() < 0 ||
14771563
pyrf_thread_map__setup_types() < 0 ||
1478-
pyrf_cpu_map__setup_types() < 0)
1564+
pyrf_cpu_map__setup_types() < 0 ||
1565+
pyrf_counts_values__setup_types() < 0)
14791566
return module;
14801567

14811568
/* The page_size is placed in util object. */
@@ -1520,6 +1607,9 @@ PyMODINIT_FUNC PyInit_perf(void)
15201607
Py_INCREF(&pyrf_cpu_map__type);
15211608
PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
15221609

1610+
Py_INCREF(&pyrf_counts_values__type);
1611+
PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);
1612+
15231613
dict = PyModule_GetDict(module);
15241614
if (dict == NULL)
15251615
goto error;

0 commit comments

Comments
 (0)