// SPDX-License-Identifier: GPL-2.0#define PY_SSIZE_T_CLEAN#include <Python.h> #include <inttypes.h>#include <string.h> #include <linux/err.h>#include <poll.h>#include <unistd.h> #include <internal/lib.h>#include <perf/cpumap.h>#include <perf/mmap.h>#include <structmember.h> #include "addr_location.h"#include "build-id.h"#include "callchain.h"#include "comm.h"#include "config.h"#include "counts.h"#include "data.h"#include "debug.h"#include "dso.h"#include "dwarf-regs.h"#include "event.h"#include "branch.h"#include "evlist.h"#include "evsel.h"#include "expr.h"#include "map.h"#include "metricgroup.h"#include "mmap.h"#include "pmus.h"#include "print_binary.h"#include "record.h"#include "sample.h"#include "session.h"#include "srccode.h"#include "srcline.h"#include "strbuf.h"#include "symbol.h"#include "stat.h"#include "header.h"#include "trace/beauty/syscalltbl.h"#include "thread.h"#include "thread_map.h"#include "tool.h"#include "tp_pmu.h"#include "trace-event.h" #ifdef HAVE_LIBTRACEEVENT#include <event-parse.h>#endif PyMODINIT_FUNC PyInit_perf(void); static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel); #define member_def(type, member, ptype, help) \ { #member, ptype, \ offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 0, help } #define sample_member_def(name, member, ptype, help) \ { #name, ptype, \ offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 0, help } #define CHECK_INITIALIZED(ptr, msg) \ do { \ if (!(ptr)) { \ PyErr_SetString(PyExc_ValueError, msg " not initialized"); \ return NULL; \ } \ } while (0) #define CHECK_INITIALIZED_INT(ptr, msg) \ do { \ if (!(ptr)) { \ PyErr_SetString(PyExc_ValueError, msg " not initialized"); \ return -1; \ } \ } while (0) struct pyrf_event { PyObject_HEAD /** @sample: The parsed sample from the event. */ struct perf_sample sample; /** @al: The address location from machine__resolve, lazily computed. */ struct addr_location al; /** @al_resolved: True when machine__resolve been called. */ bool al_resolved; /** @callchain: Resolved callchain, eagerly computed if requested. */ PyObject *callchain; /** @brstack: Resolved branch stack, eagerly computed if requested. */ PyObject *brstack; /** @event: The underlying perf_event that may be in a file or ring buffer. */ union perf_event event;}; #define sample_members \ sample_member_def(sample_pid, pid, T_INT, "event pid"), \ sample_member_def(sample_tid, tid, T_INT, "event tid"), \ sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), static PyObject *pyrf_event__get_evsel(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (!pevent->sample.evsel) Py_RETURN_NONE; return pyrf_evsel__from_evsel(pevent->sample.evsel);} static PyGetSetDef pyrf_event__getset[] = { { .name = "evsel", .get = pyrf_event__get_evsel, .set = NULL, .doc = "tracking event.", }, { .name = NULL, },}; static void pyrf_event__delete(struct pyrf_event *pevent){ if (pevent->al_resolved) addr_location__exit(&pevent->al); Py_XDECREF(pevent->callchain); Py_XDECREF(pevent->brstack); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject *)pevent);} static const char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); static PyMemberDef pyrf_mmap_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_event_header, misc, T_USHORT, "event misc"), member_def(perf_record_mmap, pid, T_UINT, "event pid"), member_def(perf_record_mmap, tid, T_UINT, "event tid"), member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"), member_def(perf_record_mmap, len, T_ULONGLONG, "map length"), member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"), member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, },}; static PyObject *pyrf_mmap_event__repr(const struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", " "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " "filename: %s }", pevent->event.mmap.pid, pevent->event.mmap.tid, pevent->event.mmap.start, pevent->event.mmap.len, pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { ret = PyErr_NoMemory(); } else { ret = PyUnicode_FromString(s); free(s); } return ret;} static PyTypeObject pyrf_mmap_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.mmap_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap_event__doc, .tp_members = pyrf_mmap_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_mmap_event__repr,}; static const char pyrf_mmap2_event__doc[] = PyDoc_STR("perf mmap2 event object."); static PyObject *pyrf_mmap2_event__get_maj(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLong(pevent->event.mmap2.maj);} static PyObject *pyrf_mmap2_event__get_min(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLong(pevent->event.mmap2.min);} static PyObject *pyrf_mmap2_event__get_ino(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino);} static PyObject *pyrf_mmap2_event__get_ino_generation(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino_generation);} static PyObject *pyrf_mmap2_event__get_build_id(PyObject *self, void *closure __maybe_unused){ struct pyrf_event *pevent = (void *)self; if (!(pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)) Py_RETURN_NONE; int size = pevent->event.mmap2.build_id_size; if (size > 20) size = 20; return PyBytes_FromStringAndSize((const char *)pevent->event.mmap2.build_id, size);} static PyGetSetDef pyrf_mmap2_event__getset[] = { { .name = "evsel", .get = pyrf_event__get_evsel, .set = NULL, .doc = "tracking event.", }, { .name = "maj", .get = pyrf_mmap2_event__get_maj, .set = NULL, .doc = "major number.", }, { .name = "min", .get = pyrf_mmap2_event__get_min, .set = NULL, .doc = "minor number.", }, { .name = "ino", .get = pyrf_mmap2_event__get_ino, .set = NULL, .doc = "inode number.", }, { .name = "ino_generation", .get = pyrf_mmap2_event__get_ino_generation, .set = NULL, .doc = "inode generation.", }, { .name = "build_id", .get = pyrf_mmap2_event__get_build_id, .set = NULL, .doc = "binary build ID.", }, { .name = NULL, },}; static PyMemberDef pyrf_mmap2_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_event_header, misc, T_USHORT, "event misc"), member_def(perf_record_mmap2, pid, T_UINT, "event pid"), member_def(perf_record_mmap2, tid, T_UINT, "event tid"), member_def(perf_record_mmap2, start, T_ULONGLONG, "start of the map"), member_def(perf_record_mmap2, len, T_ULONGLONG, "map length"), member_def(perf_record_mmap2, pgoff, T_ULONGLONG, "page offset"), member_def(perf_record_mmap2, prot, T_UINT, "protection"), member_def(perf_record_mmap2, flags, T_UINT, "flags"), member_def(perf_record_mmap2, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, },}; static PyObject *pyrf_mmap2_event__repr(const struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap2, pid: %u, tid: %u, start: %#" PRI_lx64 ", length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", flags: %#x, prot: %#x, filename: %s }", pevent->event.mmap2.pid, pevent->event.mmap2.tid, pevent->event.mmap2.start, pevent->event.mmap2.len, pevent->event.mmap2.pgoff, pevent->event.mmap2.flags, pevent->event.mmap2.prot, pevent->event.mmap2.filename) < 0) return PyErr_NoMemory(); ret = PyUnicode_FromString(s); free(s); return ret;} static PyTypeObject pyrf_mmap2_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.mmap2_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap2_event__doc, .tp_members = pyrf_mmap2_event__members, .tp_getset = pyrf_mmap2_event__getset, .tp_repr = (reprfunc)pyrf_mmap2_event__repr,}; static const char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); static PyMemberDef pyrf_task_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_fork, pid, T_UINT, "event pid"), member_def(perf_record_fork, ppid, T_UINT, "event ppid"), member_def(perf_record_fork, tid, T_UINT, "event tid"), member_def(perf_record_fork, ptid, T_UINT, "event ptid"), member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"), { .name = NULL, },}; static PyObject *pyrf_task_event__repr(const struct pyrf_event *pevent){ return PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " "ptid: %u, time: %" PRI_lu64 "}", pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", pevent->event.fork.pid, pevent->event.fork.ppid, pevent->event.fork.tid, pevent->event.fork.ptid, pevent->event.fork.time);} static PyTypeObject pyrf_task_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.task_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_task_event__doc, .tp_members = pyrf_task_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_task_event__repr,}; static const char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); static PyMemberDef pyrf_comm_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_comm, pid, T_UINT, "event pid"), member_def(perf_record_comm, tid, T_UINT, "event tid"), member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"), { .name = NULL, },}; static PyObject *pyrf_comm_event__repr(const struct pyrf_event *pevent){ return PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", pevent->event.comm.pid, pevent->event.comm.tid, pevent->event.comm.comm);} static PyTypeObject pyrf_comm_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.comm_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_comm_event__doc, .tp_members = pyrf_comm_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_comm_event__repr,}; static const char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); static PyMemberDef pyrf_throttle_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"), member_def(perf_record_throttle, id, T_ULONGLONG, "event id"), member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"), { .name = NULL, },}; static PyObject *pyrf_throttle_event__repr(const struct pyrf_event *pevent){ const struct perf_record_throttle *te = (const struct perf_record_throttle *) (&pevent->event.header + 1); return PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 ", stream_id: %" PRI_lu64 " }", pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", te->time, te->id, te->stream_id);} static PyTypeObject pyrf_throttle_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.throttle_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_throttle_event__doc, .tp_members = pyrf_throttle_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_throttle_event__repr,}; static const char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); static PyMemberDef pyrf_lost_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_lost, id, T_ULONGLONG, "event id"), member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"), { .name = NULL, },}; static PyObject *pyrf_lost_event__repr(const struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", " "lost: %#" PRI_lx64 " }", pevent->event.lost.id, pevent->event.lost.lost) < 0) { ret = PyErr_NoMemory(); } else { ret = PyUnicode_FromString(s); free(s); } return ret;} static PyTypeObject pyrf_lost_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.lost_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_lost_event__doc, .tp_members = pyrf_lost_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_lost_event__repr,}; static const char pyrf_stat_event__doc[] = PyDoc_STR("perf stat event object."); static PyMemberDef pyrf_stat_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_stat, id, T_ULONGLONG, "event id"), member_def(perf_record_stat, cpu, T_UINT, "event cpu"), member_def(perf_record_stat, thread, T_UINT, "event thread"), member_def(perf_record_stat, val, T_ULONGLONG, "counter value"), member_def(perf_record_stat, ena, T_ULONGLONG, "enabled time"), member_def(perf_record_stat, run, T_ULONGLONG, "running time"), { .name = NULL, },}; static PyObject *pyrf_stat_event__repr(const struct pyrf_event *pevent){ return PyUnicode_FromFormat( "{ type: stat, id: %llu, cpu: %u, thread: %u, val: %llu, ena: %llu, run: %llu }", pevent->event.stat.id, pevent->event.stat.cpu, pevent->event.stat.thread, pevent->event.stat.val, pevent->event.stat.ena, pevent->event.stat.run);} static PyTypeObject pyrf_stat_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.stat_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_new = PyType_GenericNew, .tp_dealloc = (destructor)pyrf_event__delete,Lines 1–500 of 4341. Load more
// SPDX-License-Identifier: GPL-2.0 #define PY_SSIZE_T_CLEAN #include <Python.h> #include <inttypes.h> #include <string.h> #include <linux/err.h> #include <poll.h> #include <unistd.h> #include <internal/lib.h> #include <perf/cpumap.h> #include <perf/mmap.h> #include <structmember.h> #include "addr_location.h" #include "build-id.h" #include "callchain.h" #include "comm.h" #include "config.h" #include "counts.h" #include "data.h" #include "debug.h" #include "dso.h" #include "dwarf-regs.h" #include "event.h" #include "branch.h" #include "evlist.h" #include "evsel.h" #include "expr.h" #include "map.h" #include "metricgroup.h" #include "mmap.h" #include "pmus.h" #include "print_binary.h" #include "record.h" #include "sample.h" #include "session.h" #include "srccode.h" #include "srcline.h" #include "strbuf.h" #include "symbol.h" #include "stat.h" #include "header.h" #include "trace/beauty/syscalltbl.h" #include "thread.h" #include "thread_map.h" #include "tool.h" #include "tp_pmu.h" #include "trace-event.h" #ifdef HAVE_LIBTRACEEVENT #include <event-parse.h> #endif PyMODINIT_FUNC PyInit_perf(void); static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel); #define member_def(type, member, ptype, help) \ { #member, ptype, \ offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 0, help } #define sample_member_def(name, member, ptype, help) \ { #name, ptype, \ offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 0, help } #define CHECK_INITIALIZED(ptr, msg) \ do { \ if (!(ptr)) { \ PyErr_SetString(PyExc_ValueError, msg " not initialized"); \ return NULL; \ } \ } while (0) #define CHECK_INITIALIZED_INT(ptr, msg) \ do { \ if (!(ptr)) { \ PyErr_SetString(PyExc_ValueError, msg " not initialized"); \ return -1; \ } \ } while (0) struct pyrf_event { PyObject_HEAD /** @sample: The parsed sample from the event. */ struct perf_sample sample; /** @al: The address location from machine__resolve, lazily computed. */ struct addr_location al; /** @al_resolved: True when machine__resolve been called. */ bool al_resolved; /** @callchain: Resolved callchain, eagerly computed if requested. */ PyObject *callchain; /** @brstack: Resolved branch stack, eagerly computed if requested. */ PyObject *brstack; /** @event: The underlying perf_event that may be in a file or ring buffer. */ union perf_event event; }; #define sample_members \ sample_member_def(sample_pid, pid, T_INT, "event pid"), \ sample_member_def(sample_tid, tid, T_INT, "event tid"), \ sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), static PyObject *pyrf_event__get_evsel(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (!pevent->sample.evsel) Py_RETURN_NONE; return pyrf_evsel__from_evsel(pevent->sample.evsel); } static PyGetSetDef pyrf_event__getset[] = { { .name = "evsel", .get = pyrf_event__get_evsel, .set = NULL, .doc = "tracking event.", }, { .name = NULL, }, }; static void pyrf_event__delete(struct pyrf_event *pevent) { if (pevent->al_resolved) addr_location__exit(&pevent->al); Py_XDECREF(pevent->callchain); Py_XDECREF(pevent->brstack); perf_sample__exit(&pevent->sample); Py_TYPE(pevent)->tp_free((PyObject *)pevent); } static const char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); static PyMemberDef pyrf_mmap_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_event_header, misc, T_USHORT, "event misc"), member_def(perf_record_mmap, pid, T_UINT, "event pid"), member_def(perf_record_mmap, tid, T_UINT, "event tid"), member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"), member_def(perf_record_mmap, len, T_ULONGLONG, "map length"), member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"), member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, }, }; static PyObject *pyrf_mmap_event__repr(const struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", " "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " "filename: %s }", pevent->event.mmap.pid, pevent->event.mmap.tid, pevent->event.mmap.start, pevent->event.mmap.len, pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { ret = PyErr_NoMemory(); } else { ret = PyUnicode_FromString(s); free(s); } return ret; } static PyTypeObject pyrf_mmap_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.mmap_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap_event__doc, .tp_members = pyrf_mmap_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_mmap_event__repr, }; static const char pyrf_mmap2_event__doc[] = PyDoc_STR("perf mmap2 event object."); static PyObject *pyrf_mmap2_event__get_maj(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLong(pevent->event.mmap2.maj); } static PyObject *pyrf_mmap2_event__get_min(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLong(pevent->event.mmap2.min); } static PyObject *pyrf_mmap2_event__get_ino(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino); } static PyObject *pyrf_mmap2_event__get_ino_generation(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID) Py_RETURN_NONE; return PyLong_FromUnsignedLongLong(pevent->event.mmap2.ino_generation); } static PyObject *pyrf_mmap2_event__get_build_id(PyObject *self, void *closure __maybe_unused) { struct pyrf_event *pevent = (void *)self; if (!(pevent->event.header.misc & PERF_RECORD_MISC_MMAP_BUILD_ID)) Py_RETURN_NONE; int size = pevent->event.mmap2.build_id_size; if (size > 20) size = 20; return PyBytes_FromStringAndSize((const char *)pevent->event.mmap2.build_id, size); } static PyGetSetDef pyrf_mmap2_event__getset[] = { { .name = "evsel", .get = pyrf_event__get_evsel, .set = NULL, .doc = "tracking event.", }, { .name = "maj", .get = pyrf_mmap2_event__get_maj, .set = NULL, .doc = "major number.", }, { .name = "min", .get = pyrf_mmap2_event__get_min, .set = NULL, .doc = "minor number.", }, { .name = "ino", .get = pyrf_mmap2_event__get_ino, .set = NULL, .doc = "inode number.", }, { .name = "ino_generation", .get = pyrf_mmap2_event__get_ino_generation, .set = NULL, .doc = "inode generation.", }, { .name = "build_id", .get = pyrf_mmap2_event__get_build_id, .set = NULL, .doc = "binary build ID.", }, { .name = NULL, }, }; static PyMemberDef pyrf_mmap2_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_event_header, misc, T_USHORT, "event misc"), member_def(perf_record_mmap2, pid, T_UINT, "event pid"), member_def(perf_record_mmap2, tid, T_UINT, "event tid"), member_def(perf_record_mmap2, start, T_ULONGLONG, "start of the map"), member_def(perf_record_mmap2, len, T_ULONGLONG, "map length"), member_def(perf_record_mmap2, pgoff, T_ULONGLONG, "page offset"), member_def(perf_record_mmap2, prot, T_UINT, "protection"), member_def(perf_record_mmap2, flags, T_UINT, "flags"), member_def(perf_record_mmap2, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, }, }; static PyObject *pyrf_mmap2_event__repr(const struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap2, pid: %u, tid: %u, start: %#" PRI_lx64 ", length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", flags: %#x, prot: %#x, filename: %s }", pevent->event.mmap2.pid, pevent->event.mmap2.tid, pevent->event.mmap2.start, pevent->event.mmap2.len, pevent->event.mmap2.pgoff, pevent->event.mmap2.flags, pevent->event.mmap2.prot, pevent->event.mmap2.filename) < 0) return PyErr_NoMemory(); ret = PyUnicode_FromString(s); free(s); return ret; } static PyTypeObject pyrf_mmap2_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.mmap2_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap2_event__doc, .tp_members = pyrf_mmap2_event__members, .tp_getset = pyrf_mmap2_event__getset, .tp_repr = (reprfunc)pyrf_mmap2_event__repr, }; static const char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); static PyMemberDef pyrf_task_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_fork, pid, T_UINT, "event pid"), member_def(perf_record_fork, ppid, T_UINT, "event ppid"), member_def(perf_record_fork, tid, T_UINT, "event tid"), member_def(perf_record_fork, ptid, T_UINT, "event ptid"), member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"), { .name = NULL, }, }; static PyObject *pyrf_task_event__repr(const struct pyrf_event *pevent) { return PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " "ptid: %u, time: %" PRI_lu64 "}", pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", pevent->event.fork.pid, pevent->event.fork.ppid, pevent->event.fork.tid, pevent->event.fork.ptid, pevent->event.fork.time); } static PyTypeObject pyrf_task_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.task_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_task_event__doc, .tp_members = pyrf_task_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_task_event__repr, }; static const char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); static PyMemberDef pyrf_comm_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_comm, pid, T_UINT, "event pid"), member_def(perf_record_comm, tid, T_UINT, "event tid"), member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"), { .name = NULL, }, }; static PyObject *pyrf_comm_event__repr(const struct pyrf_event *pevent) { return PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", pevent->event.comm.pid, pevent->event.comm.tid, pevent->event.comm.comm); } static PyTypeObject pyrf_comm_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.comm_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_comm_event__doc, .tp_members = pyrf_comm_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_comm_event__repr, }; static const char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); static PyMemberDef pyrf_throttle_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"), member_def(perf_record_throttle, id, T_ULONGLONG, "event id"), member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"), { .name = NULL, }, }; static PyObject *pyrf_throttle_event__repr(const struct pyrf_event *pevent) { const struct perf_record_throttle *te = (const struct perf_record_throttle *) (&pevent->event.header + 1); return PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 ", stream_id: %" PRI_lu64 " }", pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", te->time, te->id, te->stream_id); } static PyTypeObject pyrf_throttle_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.throttle_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_throttle_event__doc, .tp_members = pyrf_throttle_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_throttle_event__repr, }; static const char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); static PyMemberDef pyrf_lost_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_lost, id, T_ULONGLONG, "event id"), member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"), { .name = NULL, }, }; static PyObject *pyrf_lost_event__repr(const struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", " "lost: %#" PRI_lx64 " }", pevent->event.lost.id, pevent->event.lost.lost) < 0) { ret = PyErr_NoMemory(); } else { ret = PyUnicode_FromString(s); free(s); } return ret; } static PyTypeObject pyrf_lost_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.lost_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_dealloc = (destructor)pyrf_event__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_lost_event__doc, .tp_members = pyrf_lost_event__members, .tp_getset = pyrf_event__getset, .tp_repr = (reprfunc)pyrf_lost_event__repr, }; static const char pyrf_stat_event__doc[] = PyDoc_STR("perf stat event object."); static PyMemberDef pyrf_stat_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), member_def(perf_record_stat, id, T_ULONGLONG, "event id"), member_def(perf_record_stat, cpu, T_UINT, "event cpu"), member_def(perf_record_stat, thread, T_UINT, "event thread"), member_def(perf_record_stat, val, T_ULONGLONG, "counter value"), member_def(perf_record_stat, ena, T_ULONGLONG, "enabled time"), member_def(perf_record_stat, run, T_ULONGLONG, "running time"), { .name = NULL, }, }; static PyObject *pyrf_stat_event__repr(const struct pyrf_event *pevent) { return PyUnicode_FromFormat( "{ type: stat, id: %llu, cpu: %u, thread: %u, val: %llu, ena: %llu, run: %llu }", pevent->event.stat.id, pevent->event.stat.cpu, pevent->event.stat.thread, pevent->event.stat.val, pevent->event.stat.ena, pevent->event.stat.run); } static PyTypeObject pyrf_stat_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.stat_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_new = PyType_GenericNew, .tp_dealloc = (destructor)pyrf_event__delete,