#include <Python.h>#include <structmember.h>#include <inttypes.h>#include <poll.h>#include "evlist.h"#include "evsel.h"#include "event.h"#include "cpumap.h"#include "thread_map.h" /* Define PyVarObject_HEAD_INIT for python 2.5 */#ifndef PyVarObject_HEAD_INIT# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,#endif struct throttle_event { struct perf_event_header header; u64 time; u64 id; u64 stream_id;}; PyMODINIT_FUNC initperf(void); #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 } struct pyrf_event { PyObject_HEAD struct perf_sample sample; union perf_event event;}; #define sample_members \ sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 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_addr, addr, T_ULONGLONG, "event addr"), \ 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 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(mmap_event, pid, T_UINT, "event pid"), member_def(mmap_event, tid, T_UINT, "event tid"), member_def(mmap_event, start, T_ULONGLONG, "start of the map"), member_def(mmap_event, len, T_ULONGLONG, "map length"), member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"), member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, },}; static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", " "length: %#" PRIx64 ", offset: %#" PRIx64 ", " "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 = PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap_event__doc, .tp_members = pyrf_mmap_event__members, .tp_repr = (reprfunc)pyrf_mmap_event__repr,}; static 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(fork_event, pid, T_UINT, "event pid"), member_def(fork_event, ppid, T_UINT, "event ppid"), member_def(fork_event, tid, T_UINT, "event tid"), member_def(fork_event, ptid, T_UINT, "event ptid"), member_def(fork_event, time, T_ULONGLONG, "timestamp"), { .name = NULL, },}; static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent){ return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " "ptid: %u, time: %" PRIu64 "}", 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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_task_event__doc, .tp_members = pyrf_task_event__members, .tp_repr = (reprfunc)pyrf_task_event__repr,}; static 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(comm_event, pid, T_UINT, "event pid"), member_def(comm_event, tid, T_UINT, "event tid"), member_def(comm_event, comm, T_STRING_INPLACE, "process name"), { .name = NULL, },}; static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent){ return PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_comm_event__doc, .tp_members = pyrf_comm_event__members, .tp_repr = (reprfunc)pyrf_comm_event__repr,}; static 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(throttle_event, time, T_ULONGLONG, "timestamp"), member_def(throttle_event, id, T_ULONGLONG, "event id"), member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"), { .name = NULL, },}; static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent){ struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64 ", stream_id: %" PRIu64 " }", 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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_throttle_event__doc, .tp_members = pyrf_throttle_event__members, .tp_repr = (reprfunc)pyrf_throttle_event__repr,}; static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); static PyMemberDef pyrf_lost_event__members[] = { sample_members member_def(lost_event, id, T_ULONGLONG, "event id"), member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), { .name = NULL, },}; static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " "lost: %#" PRIx64 " }", pevent->event.lost.id, pevent->event.lost.lost) < 0) { ret = PyErr_NoMemory(); } else { ret = PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_lost_event__doc, .tp_members = pyrf_lost_event__members, .tp_repr = (reprfunc)pyrf_lost_event__repr,}; static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); static PyMemberDef pyrf_read_event__members[] = { sample_members member_def(read_event, pid, T_UINT, "event pid"), member_def(read_event, tid, T_UINT, "event tid"), { .name = NULL, },}; static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent){ return PyString_FromFormat("{ type: read, pid: %u, tid: %u }", pevent->event.read.pid, pevent->event.read.tid); /* * FIXME: return the array of read values, * making this method useful ;-) */} static PyTypeObject pyrf_read_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.read_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_read_event__doc, .tp_members = pyrf_read_event__members, .tp_repr = (reprfunc)pyrf_read_event__repr,}; static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); static PyMemberDef pyrf_sample_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), { .name = NULL, },}; static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent){ PyObject *ret; char *s; if (asprintf(&s, "{ type: sample }") < 0) { ret = PyErr_NoMemory(); } else { ret = PyString_FromString(s); free(s); } return ret;} static PyTypeObject pyrf_sample_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.sample_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_sample_event__doc, .tp_members = pyrf_sample_event__members, .tp_repr = (reprfunc)pyrf_sample_event__repr,}; static int pyrf_event__setup_types(void){ int err; pyrf_mmap_event__type.tp_new = pyrf_task_event__type.tp_new = pyrf_comm_event__type.tp_new = pyrf_lost_event__type.tp_new = pyrf_read_event__type.tp_new = pyrf_sample_event__type.tp_new = pyrf_throttle_event__type.tp_new = PyType_GenericNew; err = PyType_Ready(&pyrf_mmap_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_lost_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_task_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_comm_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_throttle_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_read_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_sample_event__type); if (err < 0) goto out;out: return err;} static PyTypeObject *pyrf_event__type[] = { [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, [PERF_RECORD_LOST] = &pyrf_lost_event__type, [PERF_RECORD_COMM] = &pyrf_comm_event__type, [PERF_RECORD_EXIT] = &pyrf_task_event__type, [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_FORK] = &pyrf_task_event__type, [PERF_RECORD_READ] = &pyrf_read_event__type, [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,}; static PyObject *pyrf_event__new(union perf_event *event){ struct pyrf_event *pevent; PyTypeObject *ptype; if (event->header.type < PERF_RECORD_MMAP || event->header.type > PERF_RECORD_SAMPLE) return NULL; ptype = pyrf_event__type[event->header.type]; pevent = PyObject_New(struct pyrf_event, ptype); if (pevent != NULL) memcpy(&pevent->event, event, event->header.size); return (PyObject *)pevent;} struct pyrf_cpu_map { PyObject_HEAD struct cpu_map *cpus;}; static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, PyObject *args, PyObject *kwargs){ static char *kwlist[] = { "cpustr", NULL }; char *cpustr = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &cpustr)) return -1; pcpus->cpus = cpu_map__new(cpustr); if (pcpus->cpus == NULL) return -1; return 0;} static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus){ cpu_map__delete(pcpus->cpus); pcpus->ob_type->tp_free((PyObject*)pcpus);} static Py_ssize_t pyrf_cpu_map__length(PyObject *obj){ struct pyrf_cpu_map *pcpus = (void *)obj; return pcpus->cpus->nr;} static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i){ struct pyrf_cpu_map *pcpus = (void *)obj; if (i >= pcpus->cpus->nr) return NULL; return Py_BuildValue("i", pcpus->cpus->map[i]);} static PySequenceMethods pyrf_cpu_map__sequence_methods = { .sq_length = pyrf_cpu_map__length, .sq_item = pyrf_cpu_map__item,}; static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); static PyTypeObject pyrf_cpu_map__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.cpu_map", .tp_basicsize = sizeof(struct pyrf_cpu_map), .tp_dealloc = (destructor)pyrf_cpu_map__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_cpu_map__doc, .tp_as_sequence = &pyrf_cpu_map__sequence_methods, .tp_init = (initproc)pyrf_cpu_map__init,}; static int pyrf_cpu_map__setup_types(void){ pyrf_cpu_map__type.tp_new = PyType_GenericNew; return PyType_Ready(&pyrf_cpu_map__type);} struct pyrf_thread_map { PyObject_HEAD struct thread_map *threads;}; static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, PyObject *args, PyObject *kwargs){ static char *kwlist[] = { "pid", "tid", NULL }; int pid = -1, tid = -1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, &pid, &tid)) return -1; pthreads->threads = thread_map__new(pid, tid); if (pthreads->threads == NULL) return -1; return 0;} static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads){ thread_map__delete(pthreads->threads); pthreads->ob_type->tp_free((PyObject*)pthreads);} static Py_ssize_t pyrf_thread_map__length(PyObject *obj){ struct pyrf_thread_map *pthreads = (void *)obj; return pthreads->threads->nr;} static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i){ struct pyrf_thread_map *pthreads = (void *)obj; if (i >= pthreads->threads->nr) return NULL; return Py_BuildValue("i", pthreads->threads->map[i]);} static PySequenceMethods pyrf_thread_map__sequence_methods = { .sq_length = pyrf_thread_map__length, .sq_item = pyrf_thread_map__item,}; static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); static PyTypeObject pyrf_thread_map__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.thread_map", .tp_basicsize = sizeof(struct pyrf_thread_map), .tp_dealloc = (destructor)pyrf_thread_map__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_thread_map__doc, .tp_as_sequence = &pyrf_thread_map__sequence_methods, .tp_init = (initproc)pyrf_thread_map__init,}; static int pyrf_thread_map__setup_types(void){ pyrf_thread_map__type.tp_new = PyType_GenericNew; return PyType_Ready(&pyrf_thread_map__type);} struct pyrf_evsel { PyObject_HEAD struct perf_evsel evsel;}; static int pyrf_evsel__init(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs){ struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,Lines 1–500 of 1015. Load more
#include <Python.h> #include <structmember.h> #include <inttypes.h> #include <poll.h> #include "evlist.h" #include "evsel.h" #include "event.h" #include "cpumap.h" #include "thread_map.h" /* Define PyVarObject_HEAD_INIT for python 2.5 */ #ifndef PyVarObject_HEAD_INIT # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, #endif struct throttle_event { struct perf_event_header header; u64 time; u64 id; u64 stream_id; }; PyMODINIT_FUNC initperf(void); #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 } struct pyrf_event { PyObject_HEAD struct perf_sample sample; union perf_event event; }; #define sample_members \ sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 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_addr, addr, T_ULONGLONG, "event addr"), \ 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 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(mmap_event, pid, T_UINT, "event pid"), member_def(mmap_event, tid, T_UINT, "event tid"), member_def(mmap_event, start, T_ULONGLONG, "start of the map"), member_def(mmap_event, len, T_ULONGLONG, "map length"), member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"), member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"), { .name = NULL, }, }; static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", " "length: %#" PRIx64 ", offset: %#" PRIx64 ", " "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 = PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_mmap_event__doc, .tp_members = pyrf_mmap_event__members, .tp_repr = (reprfunc)pyrf_mmap_event__repr, }; static 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(fork_event, pid, T_UINT, "event pid"), member_def(fork_event, ppid, T_UINT, "event ppid"), member_def(fork_event, tid, T_UINT, "event tid"), member_def(fork_event, ptid, T_UINT, "event ptid"), member_def(fork_event, time, T_ULONGLONG, "timestamp"), { .name = NULL, }, }; static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) { return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " "ptid: %u, time: %" PRIu64 "}", 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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_task_event__doc, .tp_members = pyrf_task_event__members, .tp_repr = (reprfunc)pyrf_task_event__repr, }; static 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(comm_event, pid, T_UINT, "event pid"), member_def(comm_event, tid, T_UINT, "event tid"), member_def(comm_event, comm, T_STRING_INPLACE, "process name"), { .name = NULL, }, }; static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent) { return PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_comm_event__doc, .tp_members = pyrf_comm_event__members, .tp_repr = (reprfunc)pyrf_comm_event__repr, }; static 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(throttle_event, time, T_ULONGLONG, "timestamp"), member_def(throttle_event, id, T_ULONGLONG, "event id"), member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"), { .name = NULL, }, }; static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) { struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64 ", stream_id: %" PRIu64 " }", 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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_throttle_event__doc, .tp_members = pyrf_throttle_event__members, .tp_repr = (reprfunc)pyrf_throttle_event__repr, }; static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); static PyMemberDef pyrf_lost_event__members[] = { sample_members member_def(lost_event, id, T_ULONGLONG, "event id"), member_def(lost_event, lost, T_ULONGLONG, "number of lost events"), { .name = NULL, }, }; static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", " "lost: %#" PRIx64 " }", pevent->event.lost.id, pevent->event.lost.lost) < 0) { ret = PyErr_NoMemory(); } else { ret = PyString_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_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_lost_event__doc, .tp_members = pyrf_lost_event__members, .tp_repr = (reprfunc)pyrf_lost_event__repr, }; static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); static PyMemberDef pyrf_read_event__members[] = { sample_members member_def(read_event, pid, T_UINT, "event pid"), member_def(read_event, tid, T_UINT, "event tid"), { .name = NULL, }, }; static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) { return PyString_FromFormat("{ type: read, pid: %u, tid: %u }", pevent->event.read.pid, pevent->event.read.tid); /* * FIXME: return the array of read values, * making this method useful ;-) */ } static PyTypeObject pyrf_read_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.read_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_read_event__doc, .tp_members = pyrf_read_event__members, .tp_repr = (reprfunc)pyrf_read_event__repr, }; static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); static PyMemberDef pyrf_sample_event__members[] = { sample_members member_def(perf_event_header, type, T_UINT, "event type"), { .name = NULL, }, }; static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) { PyObject *ret; char *s; if (asprintf(&s, "{ type: sample }") < 0) { ret = PyErr_NoMemory(); } else { ret = PyString_FromString(s); free(s); } return ret; } static PyTypeObject pyrf_sample_event__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.sample_event", .tp_basicsize = sizeof(struct pyrf_event), .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_sample_event__doc, .tp_members = pyrf_sample_event__members, .tp_repr = (reprfunc)pyrf_sample_event__repr, }; static int pyrf_event__setup_types(void) { int err; pyrf_mmap_event__type.tp_new = pyrf_task_event__type.tp_new = pyrf_comm_event__type.tp_new = pyrf_lost_event__type.tp_new = pyrf_read_event__type.tp_new = pyrf_sample_event__type.tp_new = pyrf_throttle_event__type.tp_new = PyType_GenericNew; err = PyType_Ready(&pyrf_mmap_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_lost_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_task_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_comm_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_throttle_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_read_event__type); if (err < 0) goto out; err = PyType_Ready(&pyrf_sample_event__type); if (err < 0) goto out; out: return err; } static PyTypeObject *pyrf_event__type[] = { [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, [PERF_RECORD_LOST] = &pyrf_lost_event__type, [PERF_RECORD_COMM] = &pyrf_comm_event__type, [PERF_RECORD_EXIT] = &pyrf_task_event__type, [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, [PERF_RECORD_FORK] = &pyrf_task_event__type, [PERF_RECORD_READ] = &pyrf_read_event__type, [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, }; static PyObject *pyrf_event__new(union perf_event *event) { struct pyrf_event *pevent; PyTypeObject *ptype; if (event->header.type < PERF_RECORD_MMAP || event->header.type > PERF_RECORD_SAMPLE) return NULL; ptype = pyrf_event__type[event->header.type]; pevent = PyObject_New(struct pyrf_event, ptype); if (pevent != NULL) memcpy(&pevent->event, event, event->header.size); return (PyObject *)pevent; } struct pyrf_cpu_map { PyObject_HEAD struct cpu_map *cpus; }; static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "cpustr", NULL }; char *cpustr = NULL; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &cpustr)) return -1; pcpus->cpus = cpu_map__new(cpustr); if (pcpus->cpus == NULL) return -1; return 0; } static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) { cpu_map__delete(pcpus->cpus); pcpus->ob_type->tp_free((PyObject*)pcpus); } static Py_ssize_t pyrf_cpu_map__length(PyObject *obj) { struct pyrf_cpu_map *pcpus = (void *)obj; return pcpus->cpus->nr; } static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) { struct pyrf_cpu_map *pcpus = (void *)obj; if (i >= pcpus->cpus->nr) return NULL; return Py_BuildValue("i", pcpus->cpus->map[i]); } static PySequenceMethods pyrf_cpu_map__sequence_methods = { .sq_length = pyrf_cpu_map__length, .sq_item = pyrf_cpu_map__item, }; static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); static PyTypeObject pyrf_cpu_map__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.cpu_map", .tp_basicsize = sizeof(struct pyrf_cpu_map), .tp_dealloc = (destructor)pyrf_cpu_map__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_cpu_map__doc, .tp_as_sequence = &pyrf_cpu_map__sequence_methods, .tp_init = (initproc)pyrf_cpu_map__init, }; static int pyrf_cpu_map__setup_types(void) { pyrf_cpu_map__type.tp_new = PyType_GenericNew; return PyType_Ready(&pyrf_cpu_map__type); } struct pyrf_thread_map { PyObject_HEAD struct thread_map *threads; }; static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, PyObject *args, PyObject *kwargs) { static char *kwlist[] = { "pid", "tid", NULL }; int pid = -1, tid = -1; if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, &pid, &tid)) return -1; pthreads->threads = thread_map__new(pid, tid); if (pthreads->threads == NULL) return -1; return 0; } static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) { thread_map__delete(pthreads->threads); pthreads->ob_type->tp_free((PyObject*)pthreads); } static Py_ssize_t pyrf_thread_map__length(PyObject *obj) { struct pyrf_thread_map *pthreads = (void *)obj; return pthreads->threads->nr; } static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) { struct pyrf_thread_map *pthreads = (void *)obj; if (i >= pthreads->threads->nr) return NULL; return Py_BuildValue("i", pthreads->threads->map[i]); } static PySequenceMethods pyrf_thread_map__sequence_methods = { .sq_length = pyrf_thread_map__length, .sq_item = pyrf_thread_map__item, }; static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); static PyTypeObject pyrf_thread_map__type = { PyVarObject_HEAD_INIT(NULL, 0) .tp_name = "perf.thread_map", .tp_basicsize = sizeof(struct pyrf_thread_map), .tp_dealloc = (destructor)pyrf_thread_map__delete, .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, .tp_doc = pyrf_thread_map__doc, .tp_as_sequence = &pyrf_thread_map__sequence_methods, .tp_init = (initproc)pyrf_thread_map__init, }; static int pyrf_thread_map__setup_types(void) { pyrf_thread_map__type.tp_new = PyType_GenericNew; return PyType_Ready(&pyrf_thread_map__type); } struct pyrf_evsel { PyObject_HEAD struct perf_evsel evsel; }; static int pyrf_evsel__init(struct pyrf_evsel *pevsel, PyObject *args, PyObject *kwargs) { struct perf_event_attr attr = { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,