3 #include <structmember.h> 15 #if PY_MAJOR_VERSION < 3 16 #define _PyUnicode_FromString(arg) \ 17 PyString_FromString(arg) 18 #define _PyUnicode_AsString(arg) \ 19 PyString_AsString(arg) 20 #define _PyUnicode_FromFormat(...) \ 21 PyString_FromFormat(__VA_ARGS__) 22 #define _PyLong_FromLong(arg) \ 27 #define _PyUnicode_FromString(arg) \ 28 PyUnicode_FromString(arg) 29 #define _PyUnicode_FromFormat(...) \ 30 PyUnicode_FromFormat(__VA_ARGS__) 31 #define _PyLong_FromLong(arg) \ 36 #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 64 ret = vfprintf(stderr, fmt, args);
72 #ifndef PyVarObject_HEAD_INIT 73 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 76 #if PY_MAJOR_VERSION < 3 79 PyMODINIT_FUNC PyInit_perf(
void);
82 #define member_def(type, member, ptype, help) \ 84 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 87 #define sample_member_def(name, member, ptype, help) \ 89 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 99 #define sample_members \ 100 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 101 sample_member_def(sample_pid, pid, T_INT, "event pid"), \ 102 sample_member_def(sample_tid, tid, T_INT, "event tid"), \ 103 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ 104 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ 105 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ 106 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ 107 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ 108 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), 114 member_def(perf_event_header, type, T_UINT,
"event type"),
115 member_def(perf_event_header, misc, T_UINT,
"event misc"),
130 if (asprintf(&s,
"{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64
", " 131 "length: %#" PRIx64
", offset: %#" PRIx64
", " 136 ret = PyErr_NoMemory();
146 .tp_name =
"perf.mmap_event",
148 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
158 member_def(perf_event_header, type, T_UINT,
"event type"),
170 "ptid: %u, time: %" PRIu64
"}",
171 pevent->
event.
header.type == PERF_RECORD_FORK ?
"fork" :
"exit",
181 .tp_name =
"perf.task_event",
183 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
193 member_def(perf_event_header, type, T_UINT,
"event type"),
210 .tp_name =
"perf.comm_event",
212 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
222 member_def(perf_event_header, type, T_UINT,
"event type"),
234 ", stream_id: %" PRIu64
" }",
235 pevent->
event.
header.type == PERF_RECORD_THROTTLE ?
"" :
"un",
241 .tp_name =
"perf.throttle_event",
243 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
263 if (asprintf(&s,
"{ type: lost, id: %#" PRIx64
", " 264 "lost: %#" PRIx64
" }",
266 ret = PyErr_NoMemory();
276 .tp_name =
"perf.lost_event",
278 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
306 .tp_name =
"perf.read_event",
308 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
318 member_def(perf_event_header, type, T_UINT,
"event type"),
327 if (asprintf(&s,
"{ type: sample }") < 0) {
328 ret = PyErr_NoMemory();
338 return pevent->
evsel->
attr.type == PERF_TYPE_TRACEPOINT;
344 struct pevent *pevent = field->event->pevent;
346 PyObject *ret = NULL;
347 unsigned long long val;
348 unsigned int offset, len;
350 if (field->flags & FIELD_IS_ARRAY) {
351 offset = field->offset;
353 if (field->flags & FIELD_IS_DYNAMIC) {
354 val = pevent_read_number(pevent, data + offset, len);
359 if (field->flags & FIELD_IS_STRING &&
363 ret = PyByteArray_FromStringAndSize((
const char *) data + offset, len);
364 field->flags &= ~FIELD_IS_STRING;
367 val = pevent_read_number(pevent, data + field->offset,
369 if (field->flags & FIELD_IS_POINTER)
370 ret = PyLong_FromUnsignedLong((
unsigned long) val);
371 else if (field->flags & FIELD_IS_SIGNED)
372 ret = PyLong_FromLong((
long) val);
374 ret = PyLong_FromUnsignedLong((
unsigned long) val);
385 struct format_field *
field;
397 field = pevent_find_any_field(evsel->
tp_format, str);
407 PyObject *obj = NULL;
412 return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
417 .tp_name =
"perf.sample_event",
419 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
430 member_def(perf_event_header, type, T_UINT,
"event type"),
441 if (asprintf(&s,
"{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
444 !!(pevent->
event.
header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
445 ret = PyErr_NoMemory();
455 .tp_name =
"perf.context_switch_event",
457 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
521 if ((event->
header.type < PERF_RECORD_MMAP ||
522 event->
header.type > PERF_RECORD_SAMPLE) &&
523 !(event->
header.type == PERF_RECORD_SWITCH ||
524 event->
header.type == PERF_RECORD_SWITCH_CPU_WIDE))
528 pevent = PyObject_New(
struct pyrf_event, ptype);
531 return (PyObject *)pevent;
541 PyObject *
args, PyObject *kwargs)
543 static char *kwlist[] = {
"cpustr", NULL };
546 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|s",
551 if (pcpus->
cpus == NULL)
559 Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
576 return Py_BuildValue(
"i", pcpus->
cpus->
map[i]);
588 .tp_name =
"perf.cpu_map",
591 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
610 PyObject *
args, PyObject *kwargs)
612 static char *kwlist[] = {
"pid",
"tid",
"uid", NULL };
613 int pid = -1, tid = -1, uid = UINT_MAX;
615 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|iii",
616 kwlist, &pid, &tid, &uid))
628 Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
645 return Py_BuildValue(
"i", pthreads->
threads->
map[i]);
657 .tp_name =
"perf.thread_map",
660 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
679 PyObject *
args, PyObject *kwargs)
681 struct perf_event_attr attr = {
682 .type = PERF_TYPE_HARDWARE,
683 .config = PERF_COUNT_HW_CPU_CYCLES,
684 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
686 static char *kwlist[] = {
718 u64 sample_period = 0;
740 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
741 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
742 &attr.type, &attr.config, &attr.sample_freq,
743 &sample_period, &attr.sample_type,
744 &attr.read_format, &disabled, &inherit,
745 &pinned, &exclusive, &exclude_user,
746 &exclude_kernel, &exclude_hv, &exclude_idle,
747 &mmap, &context_switch, &
comm, &freq, &inherit_stat,
748 &enable_on_exec, &
task, &watermark,
749 &precise_ip, &mmap_data, &sample_id_all,
750 &attr.wakeup_events, &attr.bp_type,
751 &attr.bp_addr, &attr.bp_len, &idx))
755 if (sample_period != 0) {
756 if (attr.sample_freq != 0)
758 attr.sample_period = sample_period;
762 attr.disabled = disabled;
763 attr.inherit = inherit;
764 attr.pinned = pinned;
765 attr.exclusive = exclusive;
766 attr.exclude_user = exclude_user;
767 attr.exclude_kernel = exclude_kernel;
768 attr.exclude_hv = exclude_hv;
769 attr.exclude_idle = exclude_idle;
771 attr.context_switch = context_switch;
774 attr.inherit_stat = inherit_stat;
775 attr.enable_on_exec = enable_on_exec;
777 attr.watermark = watermark;
778 attr.precise_ip = precise_ip;
779 attr.mmap_data = mmap_data;
780 attr.sample_id_all = sample_id_all;
781 attr.size =
sizeof(attr);
790 Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
794 PyObject *
args, PyObject *kwargs)
799 PyObject *pcpus = NULL, *pthreads = NULL;
800 int group = 0, inherit = 0;
801 static char *kwlist[] = {
"cpus",
"threads",
"group",
"inherit", NULL };
803 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|OOii", kwlist,
804 &pcpus, &pthreads, &group, &inherit))
807 if (pthreads != NULL)
813 evsel->
attr.inherit = inherit;
819 PyErr_SetFromErrno(PyExc_OSError);
831 .ml_flags = METH_VARARGS | METH_KEYWORDS,
832 .ml_doc = PyDoc_STR(
"open the event selector file descriptor table.")
841 .tp_name =
"perf.evsel",
844 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
863 PyObject *
args, PyObject *kwargs __maybe_unused)
865 PyObject *pcpus = NULL, *pthreads = NULL;
869 if (!PyArg_ParseTuple(args,
"OO", &pcpus, &pthreads))
881 Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
885 PyObject *
args, PyObject *kwargs)
888 static char *kwlist[] = {
"pages",
"overwrite", NULL };
889 int pages = 128, overwrite =
false;
891 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|ii", kwlist,
896 PyErr_SetFromErrno(PyExc_OSError);
905 PyObject *
args, PyObject *kwargs)
908 static char *kwlist[] = {
"timeout", NULL };
911 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|i", kwlist, &timeout))
916 PyErr_SetFromErrno(PyExc_OSError);
920 return Py_BuildValue(
"i", n);
924 PyObject *
args __maybe_unused,
925 PyObject *kwargs __maybe_unused)
928 PyObject *list = PyList_New(0);
931 for (i = 0; i < evlist->
pollfd.nr; ++i) {
933 #if PY_MAJOR_VERSION < 3 934 FILE *fp = fdopen(evlist->
pollfd.entries[i].fd,
"r");
939 file = PyFile_FromFile(fp,
"perf",
"r", NULL);
941 file = PyFile_FromFd(evlist->
pollfd.entries[i].fd,
"perf",
"r", -1, NULL, NULL, NULL, 1);
946 if (PyList_Append(list, file) != 0) {
956 return PyErr_NoMemory();
962 PyObject *kwargs __maybe_unused)
968 if (!PyArg_ParseTuple(args,
"O", &pevsel))
972 evsel = &((
struct pyrf_evsel *)pevsel)->evsel;
976 return Py_BuildValue(
"i", evlist->
nr_entries);
980 PyObject *
args, PyObject *kwargs)
984 int sample_id_all = 1, cpu;
985 static char *kwlist[] = {
"cpu",
"sample_id_all", NULL };
989 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"i|i", kwlist,
990 &cpu, &sample_id_all))
993 md = &evlist->
mmap[cpu];
1003 if (pyevent == NULL)
1004 return PyErr_NoMemory();
1020 return PyErr_Format(PyExc_OSError,
1021 "perf: can't parse sample, err=%d", err);
1030 PyObject *
args, PyObject *kwargs)
1034 static char *kwlist[] = {
"group", NULL };
1036 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|OOii", kwlist, &group))
1043 PyErr_SetFromErrno(PyExc_OSError);
1055 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1056 .ml_doc = PyDoc_STR(
"mmap the file descriptor table.")
1061 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1062 .ml_doc = PyDoc_STR(
"open the file descriptors.")
1067 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1068 .ml_doc = PyDoc_STR(
"poll the file descriptor table.")
1071 .ml_name =
"get_pollfd",
1073 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1074 .ml_doc = PyDoc_STR(
"get the poll file descriptor table.")
1079 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1080 .ml_doc = PyDoc_STR(
"adds an event selector to the list.")
1083 .ml_name =
"read_on_cpu",
1085 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1086 .ml_doc = PyDoc_STR(
"reads an event.")
1088 { .ml_name = NULL, }
1111 return Py_BuildValue(
"O", container_of(pos,
struct pyrf_evsel, evsel));
1123 .tp_name =
"perf.evlist",
1126 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1139 #define PERF_CONST(name) { #name, PERF_##name } 1171 PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
1223 PyObject *
args, PyObject *kwargs)
1226 static char *kwlist[] = {
"sys",
"name", NULL };
1230 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
"|ss", kwlist,
1235 if (IS_ERR(tp_format))
1243 .ml_name =
"tracepoint",
1245 .ml_flags = METH_VARARGS | METH_KEYWORDS,
1246 .ml_doc = PyDoc_STR(
"Get tracepoint config.")
1248 { .ml_name = NULL, }
1251 #if PY_MAJOR_VERSION < 3 1254 PyMODINIT_FUNC PyInit_perf(
void)
1260 #if PY_MAJOR_VERSION < 3 1263 static struct PyModuleDef moduledef = {
1264 PyModuleDef_HEAD_INIT,
1274 PyObject *module = PyModule_Create(&moduledef);
1277 if (module == NULL ||
1283 #if PY_MAJOR_VERSION < 3 1313 Py_INCREF(&pyrf_task_event__type);
1314 PyModule_AddObject(module,
"task_event", (PyObject *)&pyrf_task_event__type);
1331 dict = PyModule_GetDict(module);
1344 if (PyErr_Occurred())
1345 PyErr_SetString(PyExc_ImportError,
"perf: Init failed!");
1346 #if PY_MAJOR_VERSION >= 3 1356 int fd,
int group_fd,
unsigned long flags)
static PyMemberDef pyrf_comm_event__members[]
static int pyrf_evsel__init(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs)
static PyMemberDef pyrf_throttle_event__members[]
static PyMemberDef pyrf_task_event__members[]
void perf_evlist__exit(struct perf_evlist *evlist)
static PyObject * pyrf_read_event__repr(struct pyrf_event *pevent)
void perf_mmap__consume(struct perf_mmap *map)
static PyMemberDef pyrf_context_switch_event__members[]
struct event_format * trace_event__tp_format(const char *sys, const char *name)
static PyObject * get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
static PyObject * pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, PyObject *args __maybe_unused, PyObject *kwargs __maybe_unused)
void perf_evlist__set_leader(struct perf_evlist *evlist)
static char pyrf_mmap_event__doc[]
#define _PyUnicode_AsString(arg)
static PyObject * pyrf_context_switch_event__repr(struct pyrf_event *pevent)
static PySequenceMethods pyrf_evlist__sequence_methods
static PyObject * pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
static PyObject * pyrf_evlist__open(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs)
static PyObject * pyrf_throttle_event__repr(struct pyrf_event *pevent)
void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, int fd, int group_fd, unsigned long flags)
static int pyrf_evsel__setup_types(void)
static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, PyObject *args, PyObject *kwargs)
static int pyrf_evlist__init(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs __maybe_unused)
int eprintf(int level, int var, const char *fmt,...)
static PyMemberDef pyrf_mmap_event__members[]
static PyTypeObject * pyrf_event__type[]
static char pyrf_comm_event__doc[]
struct perf_evsel * perf_evlist__event2evsel(struct perf_evlist *evlist, union perf_event *event)
static char pyrf_task_event__doc[]
static PyTypeObject pyrf_evlist__type
static PyMemberDef pyrf_read_event__members[]
static PyTypeObject pyrf_task_event__type
#define PyVarObject_HEAD_INIT(type, size)
static PyObject * pyrf_event__new(union perf_event *event)
static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
static PyObject * pyrf_evsel__open(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs)
static PyTypeObject pyrf_cpu_map__type
struct perf_sample sample
static char pyrf_evsel__doc[]
static PyTypeObject pyrf_throttle_event__type
static PyTypeObject pyrf_sample_event__type
static PyObject * pyrf_evlist__poll(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs)
static PySequenceMethods pyrf_cpu_map__sequence_methods
void cpu_map__put(struct cpu_map *map)
int perf_mmap__read_init(struct perf_mmap *map)
PyObject_HEAD struct thread_map * threads
int perf_evlist__poll(struct perf_evlist *evlist, int timeout)
static Py_ssize_t pyrf_evlist__length(PyObject *obj)
static PyMemberDef pyrf_sample_event__members[]
int perf_evlist__open(struct perf_evlist *evlist)
#define evlist__for_each_entry(evlist, evsel)
PyObject_HEAD struct perf_evsel evsel
static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
static PyObject * tracepoint_field(struct pyrf_event *pe, struct format_field *field)
static PyMethodDef pyrf_evsel__methods[]
static PyMethodDef pyrf_evlist__methods[]
static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
struct context_switch_event context_switch
static PyObject * pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
struct event_format * tp_format
static PyObject * pyrf_evlist__mmap(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs)
int parse_callchain_record(const char *arg __maybe_unused, struct callchain_param *param __maybe_unused)
static char pyrf_context_switch_event__doc[]
static int str(yyscan_t scanner, int token)
PyObject_HEAD struct perf_evsel * evsel
static PyTypeObject pyrf_evsel__type
static PyTypeObject pyrf_context_switch_event__type
static int pyrf_evlist__setup_types(void)
void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
static PyMemberDef pyrf_lost_event__members[]
struct thread_map_data map[]
#define _PyUnicode_FromString(arg)
static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, PyObject *args, PyObject *kwargs)
static char pyrf_lost_event__doc[]
static PyObject * pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
static PyTypeObject pyrf_mmap_event__type
static PyTypeObject pyrf_thread_map__type
int perf_evlist__mmap(struct perf_evlist *evlist, unsigned int pages)
x86 movsq based memcpy() in arch/x86/lib/memcpy_64.S") MEMCPY_FN(memcpy_erms
#define _PyUnicode_FromFormat(...)
static PyTypeObject pyrf_comm_event__type
static PyObject * pyrf_sample_event__repr(struct pyrf_event *pevent)
static char pyrf_throttle_event__doc[]
static int pyrf_event__setup_types(void)
void perf_evsel__exit(struct perf_evsel *evsel)
static struct thread_data threads[THREADS]
static char pyrf_evlist__doc[]
struct perf_event_header header
#define _PyLong_FromLong(arg)
int perf_evsel__open(struct perf_evsel *evsel, struct cpu_map *cpus, struct thread_map *threads)
static bool is_tracepoint(struct pyrf_event *pevent)
static PyTypeObject pyrf_read_event__type
static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
struct event_format * trace_event__tp_format_id(int id)
static PyObject * pyrf_task_event__repr(struct pyrf_event *pevent)
PyObject_HEAD struct cpu_map * cpus
union perf_event * perf_mmap__read_event(struct perf_mmap *map)
static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
#define member_def(type, member, ptype, help)
static char pyrf_sample_event__doc[]
static struct @136 perf__constants[]
static PyMethodDef perf__methods[]
static PyTypeObject pyrf_lost_event__type
static char pyrf_thread_map__doc[]
static char pyrf_cpu_map__doc[]
void thread_map__put(struct thread_map *map)
PyMODINIT_FUNC initperf(void)
static PyObject * pyrf__tracepoint(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs)
void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, struct thread_map *threads)
int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, struct perf_sample *data)
static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
PyObject_HEAD struct perf_evlist evlist
int is_printable_array(char *p, unsigned int len)
struct thread_map * thread_map__new(pid_t pid, pid_t tid, uid_t uid)
static PyObject * pyrf_mmap_event__repr(struct pyrf_event *pevent)
static struct event_format * tp_format(const char *sys, const char *name)
struct cpu_map * cpu_map__new(const char *cpu_list)
static PyObject * pyrf_lost_event__repr(struct pyrf_event *pevent)
static int pyrf_thread_map__setup_types(void)
static PyObject * pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs)
static int pyrf_cpu_map__setup_types(void)
static PyObject * pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
static PyObject * pyrf_evlist__add(struct pyrf_evlist *pevlist, PyObject *args, PyObject *kwargs __maybe_unused)
struct perf_event_attr attr
static char pyrf_read_event__doc[]
static PyObject * pyrf_comm_event__repr(struct pyrf_event *pevent)
void perf_evsel__init(struct perf_evsel *evsel, struct perf_event_attr *attr, int idx)
static PySequenceMethods pyrf_thread_map__sequence_methods