18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci#include <Python.h> 38c2ecf20Sopenharmony_ci#include <structmember.h> 48c2ecf20Sopenharmony_ci#include <inttypes.h> 58c2ecf20Sopenharmony_ci#include <poll.h> 68c2ecf20Sopenharmony_ci#include <linux/err.h> 78c2ecf20Sopenharmony_ci#include <perf/cpumap.h> 88c2ecf20Sopenharmony_ci#include <traceevent/event-parse.h> 98c2ecf20Sopenharmony_ci#include <perf/mmap.h> 108c2ecf20Sopenharmony_ci#include "evlist.h" 118c2ecf20Sopenharmony_ci#include "callchain.h" 128c2ecf20Sopenharmony_ci#include "evsel.h" 138c2ecf20Sopenharmony_ci#include "event.h" 148c2ecf20Sopenharmony_ci#include "print_binary.h" 158c2ecf20Sopenharmony_ci#include "thread_map.h" 168c2ecf20Sopenharmony_ci#include "trace-event.h" 178c2ecf20Sopenharmony_ci#include "mmap.h" 188c2ecf20Sopenharmony_ci#include "stat.h" 198c2ecf20Sopenharmony_ci#include "metricgroup.h" 208c2ecf20Sopenharmony_ci#include "util/env.h" 218c2ecf20Sopenharmony_ci#include <internal/lib.h> 228c2ecf20Sopenharmony_ci#include "util.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 258c2ecf20Sopenharmony_ci#define _PyUnicode_FromString(arg) \ 268c2ecf20Sopenharmony_ci PyString_FromString(arg) 278c2ecf20Sopenharmony_ci#define _PyUnicode_AsString(arg) \ 288c2ecf20Sopenharmony_ci PyString_AsString(arg) 298c2ecf20Sopenharmony_ci#define _PyUnicode_FromFormat(...) \ 308c2ecf20Sopenharmony_ci PyString_FromFormat(__VA_ARGS__) 318c2ecf20Sopenharmony_ci#define _PyLong_FromLong(arg) \ 328c2ecf20Sopenharmony_ci PyInt_FromLong(arg) 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci#else 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci#define _PyUnicode_FromString(arg) \ 378c2ecf20Sopenharmony_ci PyUnicode_FromString(arg) 388c2ecf20Sopenharmony_ci#define _PyUnicode_FromFormat(...) \ 398c2ecf20Sopenharmony_ci PyUnicode_FromFormat(__VA_ARGS__) 408c2ecf20Sopenharmony_ci#define _PyLong_FromLong(arg) \ 418c2ecf20Sopenharmony_ci PyLong_FromLong(arg) 428c2ecf20Sopenharmony_ci#endif 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci#ifndef Py_TYPE 458c2ecf20Sopenharmony_ci#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) 468c2ecf20Sopenharmony_ci#endif 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci/* 498c2ecf20Sopenharmony_ci * Provide these two so that we don't have to link against callchain.c and 508c2ecf20Sopenharmony_ci * start dragging hist.c, etc. 518c2ecf20Sopenharmony_ci */ 528c2ecf20Sopenharmony_cistruct callchain_param callchain_param; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ciint parse_callchain_record(const char *arg __maybe_unused, 558c2ecf20Sopenharmony_ci struct callchain_param *param __maybe_unused) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci return 0; 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_ci/* 618c2ecf20Sopenharmony_ci * Add this one here not to drag util/env.c 628c2ecf20Sopenharmony_ci */ 638c2ecf20Sopenharmony_cistruct perf_env perf_env; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci/* 668c2ecf20Sopenharmony_ci * Add this one here not to drag util/stat-shadow.c 678c2ecf20Sopenharmony_ci */ 688c2ecf20Sopenharmony_civoid perf_stat__collect_metric_expr(struct evlist *evsel_list) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 738c2ecf20Sopenharmony_ci * Add this one here not to drag util/metricgroup.c 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_ciint metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp, 768c2ecf20Sopenharmony_ci struct rblist *new_metric_events, 778c2ecf20Sopenharmony_ci struct rblist *old_metric_events) 788c2ecf20Sopenharmony_ci{ 798c2ecf20Sopenharmony_ci return 0; 808c2ecf20Sopenharmony_ci} 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci/* 838c2ecf20Sopenharmony_ci * Support debug printing even though util/debug.c is not linked. That means 848c2ecf20Sopenharmony_ci * implementing 'verbose' and 'eprintf'. 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_ciint verbose; 878c2ecf20Sopenharmony_ciint debug_peo_args; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciint eprintf(int level, int var, const char *fmt, ...); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ciint eprintf(int level, int var, const char *fmt, ...) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci va_list args; 948c2ecf20Sopenharmony_ci int ret = 0; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci if (var >= level) { 978c2ecf20Sopenharmony_ci va_start(args, fmt); 988c2ecf20Sopenharmony_ci ret = vfprintf(stderr, fmt, args); 998c2ecf20Sopenharmony_ci va_end(args); 1008c2ecf20Sopenharmony_ci } 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci return ret; 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/* Define PyVarObject_HEAD_INIT for python 2.5 */ 1068c2ecf20Sopenharmony_ci#ifndef PyVarObject_HEAD_INIT 1078c2ecf20Sopenharmony_ci# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 1088c2ecf20Sopenharmony_ci#endif 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 1118c2ecf20Sopenharmony_ciPyMODINIT_FUNC initperf(void); 1128c2ecf20Sopenharmony_ci#else 1138c2ecf20Sopenharmony_ciPyMODINIT_FUNC PyInit_perf(void); 1148c2ecf20Sopenharmony_ci#endif 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci#define member_def(type, member, ptype, help) \ 1178c2ecf20Sopenharmony_ci { #member, ptype, \ 1188c2ecf20Sopenharmony_ci offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 1198c2ecf20Sopenharmony_ci 0, help } 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_ci#define sample_member_def(name, member, ptype, help) \ 1228c2ecf20Sopenharmony_ci { #name, ptype, \ 1238c2ecf20Sopenharmony_ci offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 1248c2ecf20Sopenharmony_ci 0, help } 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_cistruct pyrf_event { 1278c2ecf20Sopenharmony_ci PyObject_HEAD 1288c2ecf20Sopenharmony_ci struct evsel *evsel; 1298c2ecf20Sopenharmony_ci struct perf_sample sample; 1308c2ecf20Sopenharmony_ci union perf_event event; 1318c2ecf20Sopenharmony_ci}; 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci#define sample_members \ 1348c2ecf20Sopenharmony_ci sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 1358c2ecf20Sopenharmony_ci sample_member_def(sample_pid, pid, T_INT, "event pid"), \ 1368c2ecf20Sopenharmony_ci sample_member_def(sample_tid, tid, T_INT, "event tid"), \ 1378c2ecf20Sopenharmony_ci sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ 1388c2ecf20Sopenharmony_ci sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ 1398c2ecf20Sopenharmony_ci sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ 1408c2ecf20Sopenharmony_ci sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ 1418c2ecf20Sopenharmony_ci sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ 1428c2ecf20Sopenharmony_ci sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_cistatic char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_mmap_event__members[] = { 1478c2ecf20Sopenharmony_ci sample_members 1488c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 1498c2ecf20Sopenharmony_ci member_def(perf_event_header, misc, T_UINT, "event misc"), 1508c2ecf20Sopenharmony_ci member_def(perf_record_mmap, pid, T_UINT, "event pid"), 1518c2ecf20Sopenharmony_ci member_def(perf_record_mmap, tid, T_UINT, "event tid"), 1528c2ecf20Sopenharmony_ci member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"), 1538c2ecf20Sopenharmony_ci member_def(perf_record_mmap, len, T_ULONGLONG, "map length"), 1548c2ecf20Sopenharmony_ci member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"), 1558c2ecf20Sopenharmony_ci member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"), 1568c2ecf20Sopenharmony_ci { .name = NULL, }, 1578c2ecf20Sopenharmony_ci}; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_cistatic PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) 1608c2ecf20Sopenharmony_ci{ 1618c2ecf20Sopenharmony_ci PyObject *ret; 1628c2ecf20Sopenharmony_ci char *s; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", " 1658c2ecf20Sopenharmony_ci "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", " 1668c2ecf20Sopenharmony_ci "filename: %s }", 1678c2ecf20Sopenharmony_ci pevent->event.mmap.pid, pevent->event.mmap.tid, 1688c2ecf20Sopenharmony_ci pevent->event.mmap.start, pevent->event.mmap.len, 1698c2ecf20Sopenharmony_ci pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { 1708c2ecf20Sopenharmony_ci ret = PyErr_NoMemory(); 1718c2ecf20Sopenharmony_ci } else { 1728c2ecf20Sopenharmony_ci ret = _PyUnicode_FromString(s); 1738c2ecf20Sopenharmony_ci free(s); 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci return ret; 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_mmap_event__type = { 1798c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 1808c2ecf20Sopenharmony_ci .tp_name = "perf.mmap_event", 1818c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 1828c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 1838c2ecf20Sopenharmony_ci .tp_doc = pyrf_mmap_event__doc, 1848c2ecf20Sopenharmony_ci .tp_members = pyrf_mmap_event__members, 1858c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_mmap_event__repr, 1868c2ecf20Sopenharmony_ci}; 1878c2ecf20Sopenharmony_ci 1888c2ecf20Sopenharmony_cistatic char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_task_event__members[] = { 1918c2ecf20Sopenharmony_ci sample_members 1928c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 1938c2ecf20Sopenharmony_ci member_def(perf_record_fork, pid, T_UINT, "event pid"), 1948c2ecf20Sopenharmony_ci member_def(perf_record_fork, ppid, T_UINT, "event ppid"), 1958c2ecf20Sopenharmony_ci member_def(perf_record_fork, tid, T_UINT, "event tid"), 1968c2ecf20Sopenharmony_ci member_def(perf_record_fork, ptid, T_UINT, "event ptid"), 1978c2ecf20Sopenharmony_ci member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"), 1988c2ecf20Sopenharmony_ci { .name = NULL, }, 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) 2028c2ecf20Sopenharmony_ci{ 2038c2ecf20Sopenharmony_ci return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " 2048c2ecf20Sopenharmony_ci "ptid: %u, time: %" PRI_lu64 "}", 2058c2ecf20Sopenharmony_ci pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", 2068c2ecf20Sopenharmony_ci pevent->event.fork.pid, 2078c2ecf20Sopenharmony_ci pevent->event.fork.ppid, 2088c2ecf20Sopenharmony_ci pevent->event.fork.tid, 2098c2ecf20Sopenharmony_ci pevent->event.fork.ptid, 2108c2ecf20Sopenharmony_ci pevent->event.fork.time); 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_task_event__type = { 2148c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 2158c2ecf20Sopenharmony_ci .tp_name = "perf.task_event", 2168c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 2178c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 2188c2ecf20Sopenharmony_ci .tp_doc = pyrf_task_event__doc, 2198c2ecf20Sopenharmony_ci .tp_members = pyrf_task_event__members, 2208c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_task_event__repr, 2218c2ecf20Sopenharmony_ci}; 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_cistatic char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_comm_event__members[] = { 2268c2ecf20Sopenharmony_ci sample_members 2278c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 2288c2ecf20Sopenharmony_ci member_def(perf_record_comm, pid, T_UINT, "event pid"), 2298c2ecf20Sopenharmony_ci member_def(perf_record_comm, tid, T_UINT, "event tid"), 2308c2ecf20Sopenharmony_ci member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"), 2318c2ecf20Sopenharmony_ci { .name = NULL, }, 2328c2ecf20Sopenharmony_ci}; 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", 2378c2ecf20Sopenharmony_ci pevent->event.comm.pid, 2388c2ecf20Sopenharmony_ci pevent->event.comm.tid, 2398c2ecf20Sopenharmony_ci pevent->event.comm.comm); 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_comm_event__type = { 2438c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 2448c2ecf20Sopenharmony_ci .tp_name = "perf.comm_event", 2458c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 2468c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 2478c2ecf20Sopenharmony_ci .tp_doc = pyrf_comm_event__doc, 2488c2ecf20Sopenharmony_ci .tp_members = pyrf_comm_event__members, 2498c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_comm_event__repr, 2508c2ecf20Sopenharmony_ci}; 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_throttle_event__members[] = { 2558c2ecf20Sopenharmony_ci sample_members 2568c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 2578c2ecf20Sopenharmony_ci member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"), 2588c2ecf20Sopenharmony_ci member_def(perf_record_throttle, id, T_ULONGLONG, "event id"), 2598c2ecf20Sopenharmony_ci member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"), 2608c2ecf20Sopenharmony_ci { .name = NULL, }, 2618c2ecf20Sopenharmony_ci}; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cistatic PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) 2648c2ecf20Sopenharmony_ci{ 2658c2ecf20Sopenharmony_ci struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1); 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64 2688c2ecf20Sopenharmony_ci ", stream_id: %" PRI_lu64 " }", 2698c2ecf20Sopenharmony_ci pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", 2708c2ecf20Sopenharmony_ci te->time, te->id, te->stream_id); 2718c2ecf20Sopenharmony_ci} 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_throttle_event__type = { 2748c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 2758c2ecf20Sopenharmony_ci .tp_name = "perf.throttle_event", 2768c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 2778c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 2788c2ecf20Sopenharmony_ci .tp_doc = pyrf_throttle_event__doc, 2798c2ecf20Sopenharmony_ci .tp_members = pyrf_throttle_event__members, 2808c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_throttle_event__repr, 2818c2ecf20Sopenharmony_ci}; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_cistatic char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object."); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_lost_event__members[] = { 2868c2ecf20Sopenharmony_ci sample_members 2878c2ecf20Sopenharmony_ci member_def(perf_record_lost, id, T_ULONGLONG, "event id"), 2888c2ecf20Sopenharmony_ci member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"), 2898c2ecf20Sopenharmony_ci { .name = NULL, }, 2908c2ecf20Sopenharmony_ci}; 2918c2ecf20Sopenharmony_ci 2928c2ecf20Sopenharmony_cistatic PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci PyObject *ret; 2958c2ecf20Sopenharmony_ci char *s; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", " 2988c2ecf20Sopenharmony_ci "lost: %#" PRI_lx64 " }", 2998c2ecf20Sopenharmony_ci pevent->event.lost.id, pevent->event.lost.lost) < 0) { 3008c2ecf20Sopenharmony_ci ret = PyErr_NoMemory(); 3018c2ecf20Sopenharmony_ci } else { 3028c2ecf20Sopenharmony_ci ret = _PyUnicode_FromString(s); 3038c2ecf20Sopenharmony_ci free(s); 3048c2ecf20Sopenharmony_ci } 3058c2ecf20Sopenharmony_ci return ret; 3068c2ecf20Sopenharmony_ci} 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_lost_event__type = { 3098c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 3108c2ecf20Sopenharmony_ci .tp_name = "perf.lost_event", 3118c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 3128c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 3138c2ecf20Sopenharmony_ci .tp_doc = pyrf_lost_event__doc, 3148c2ecf20Sopenharmony_ci .tp_members = pyrf_lost_event__members, 3158c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_lost_event__repr, 3168c2ecf20Sopenharmony_ci}; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_cistatic char pyrf_read_event__doc[] = PyDoc_STR("perf read event object."); 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_read_event__members[] = { 3218c2ecf20Sopenharmony_ci sample_members 3228c2ecf20Sopenharmony_ci member_def(perf_record_read, pid, T_UINT, "event pid"), 3238c2ecf20Sopenharmony_ci member_def(perf_record_read, tid, T_UINT, "event tid"), 3248c2ecf20Sopenharmony_ci { .name = NULL, }, 3258c2ecf20Sopenharmony_ci}; 3268c2ecf20Sopenharmony_ci 3278c2ecf20Sopenharmony_cistatic PyObject *pyrf_read_event__repr(struct pyrf_event *pevent) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }", 3308c2ecf20Sopenharmony_ci pevent->event.read.pid, 3318c2ecf20Sopenharmony_ci pevent->event.read.tid); 3328c2ecf20Sopenharmony_ci /* 3338c2ecf20Sopenharmony_ci * FIXME: return the array of read values, 3348c2ecf20Sopenharmony_ci * making this method useful ;-) 3358c2ecf20Sopenharmony_ci */ 3368c2ecf20Sopenharmony_ci} 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_read_event__type = { 3398c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 3408c2ecf20Sopenharmony_ci .tp_name = "perf.read_event", 3418c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 3428c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 3438c2ecf20Sopenharmony_ci .tp_doc = pyrf_read_event__doc, 3448c2ecf20Sopenharmony_ci .tp_members = pyrf_read_event__members, 3458c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_read_event__repr, 3468c2ecf20Sopenharmony_ci}; 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_cistatic char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object."); 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_sample_event__members[] = { 3518c2ecf20Sopenharmony_ci sample_members 3528c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 3538c2ecf20Sopenharmony_ci { .name = NULL, }, 3548c2ecf20Sopenharmony_ci}; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cistatic PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent) 3578c2ecf20Sopenharmony_ci{ 3588c2ecf20Sopenharmony_ci PyObject *ret; 3598c2ecf20Sopenharmony_ci char *s; 3608c2ecf20Sopenharmony_ci 3618c2ecf20Sopenharmony_ci if (asprintf(&s, "{ type: sample }") < 0) { 3628c2ecf20Sopenharmony_ci ret = PyErr_NoMemory(); 3638c2ecf20Sopenharmony_ci } else { 3648c2ecf20Sopenharmony_ci ret = _PyUnicode_FromString(s); 3658c2ecf20Sopenharmony_ci free(s); 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ci return ret; 3688c2ecf20Sopenharmony_ci} 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_cistatic bool is_tracepoint(struct pyrf_event *pevent) 3718c2ecf20Sopenharmony_ci{ 3728c2ecf20Sopenharmony_ci return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT; 3738c2ecf20Sopenharmony_ci} 3748c2ecf20Sopenharmony_ci 3758c2ecf20Sopenharmony_cistatic PyObject* 3768c2ecf20Sopenharmony_citracepoint_field(struct pyrf_event *pe, struct tep_format_field *field) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci struct tep_handle *pevent = field->event->tep; 3798c2ecf20Sopenharmony_ci void *data = pe->sample.raw_data; 3808c2ecf20Sopenharmony_ci PyObject *ret = NULL; 3818c2ecf20Sopenharmony_ci unsigned long long val; 3828c2ecf20Sopenharmony_ci unsigned int offset, len; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci if (field->flags & TEP_FIELD_IS_ARRAY) { 3858c2ecf20Sopenharmony_ci offset = field->offset; 3868c2ecf20Sopenharmony_ci len = field->size; 3878c2ecf20Sopenharmony_ci if (field->flags & TEP_FIELD_IS_DYNAMIC) { 3888c2ecf20Sopenharmony_ci val = tep_read_number(pevent, data + offset, len); 3898c2ecf20Sopenharmony_ci offset = val; 3908c2ecf20Sopenharmony_ci len = offset >> 16; 3918c2ecf20Sopenharmony_ci offset &= 0xffff; 3928c2ecf20Sopenharmony_ci } 3938c2ecf20Sopenharmony_ci if (field->flags & TEP_FIELD_IS_STRING && 3948c2ecf20Sopenharmony_ci is_printable_array(data + offset, len)) { 3958c2ecf20Sopenharmony_ci ret = _PyUnicode_FromString((char *)data + offset); 3968c2ecf20Sopenharmony_ci } else { 3978c2ecf20Sopenharmony_ci ret = PyByteArray_FromStringAndSize((const char *) data + offset, len); 3988c2ecf20Sopenharmony_ci field->flags &= ~TEP_FIELD_IS_STRING; 3998c2ecf20Sopenharmony_ci } 4008c2ecf20Sopenharmony_ci } else { 4018c2ecf20Sopenharmony_ci val = tep_read_number(pevent, data + field->offset, 4028c2ecf20Sopenharmony_ci field->size); 4038c2ecf20Sopenharmony_ci if (field->flags & TEP_FIELD_IS_POINTER) 4048c2ecf20Sopenharmony_ci ret = PyLong_FromUnsignedLong((unsigned long) val); 4058c2ecf20Sopenharmony_ci else if (field->flags & TEP_FIELD_IS_SIGNED) 4068c2ecf20Sopenharmony_ci ret = PyLong_FromLong((long) val); 4078c2ecf20Sopenharmony_ci else 4088c2ecf20Sopenharmony_ci ret = PyLong_FromUnsignedLong((unsigned long) val); 4098c2ecf20Sopenharmony_ci } 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci return ret; 4128c2ecf20Sopenharmony_ci} 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_cistatic PyObject* 4158c2ecf20Sopenharmony_ciget_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name) 4168c2ecf20Sopenharmony_ci{ 4178c2ecf20Sopenharmony_ci const char *str = _PyUnicode_AsString(PyObject_Str(attr_name)); 4188c2ecf20Sopenharmony_ci struct evsel *evsel = pevent->evsel; 4198c2ecf20Sopenharmony_ci struct tep_format_field *field; 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci if (!evsel->tp_format) { 4228c2ecf20Sopenharmony_ci struct tep_event *tp_format; 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_ci tp_format = trace_event__tp_format_id(evsel->core.attr.config); 4258c2ecf20Sopenharmony_ci if (!tp_format) 4268c2ecf20Sopenharmony_ci return NULL; 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci evsel->tp_format = tp_format; 4298c2ecf20Sopenharmony_ci } 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci field = tep_find_any_field(evsel->tp_format, str); 4328c2ecf20Sopenharmony_ci if (!field) 4338c2ecf20Sopenharmony_ci return NULL; 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci return tracepoint_field(pevent, field); 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_cistatic PyObject* 4398c2ecf20Sopenharmony_cipyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name) 4408c2ecf20Sopenharmony_ci{ 4418c2ecf20Sopenharmony_ci PyObject *obj = NULL; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci if (is_tracepoint(pevent)) 4448c2ecf20Sopenharmony_ci obj = get_tracepoint_field(pevent, attr_name); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name); 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_sample_event__type = { 4508c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 4518c2ecf20Sopenharmony_ci .tp_name = "perf.sample_event", 4528c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 4538c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 4548c2ecf20Sopenharmony_ci .tp_doc = pyrf_sample_event__doc, 4558c2ecf20Sopenharmony_ci .tp_members = pyrf_sample_event__members, 4568c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_sample_event__repr, 4578c2ecf20Sopenharmony_ci .tp_getattro = (getattrofunc) pyrf_sample_event__getattro, 4588c2ecf20Sopenharmony_ci}; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_cistatic char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object."); 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_cistatic PyMemberDef pyrf_context_switch_event__members[] = { 4638c2ecf20Sopenharmony_ci sample_members 4648c2ecf20Sopenharmony_ci member_def(perf_event_header, type, T_UINT, "event type"), 4658c2ecf20Sopenharmony_ci member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"), 4668c2ecf20Sopenharmony_ci member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"), 4678c2ecf20Sopenharmony_ci { .name = NULL, }, 4688c2ecf20Sopenharmony_ci}; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_cistatic PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent) 4718c2ecf20Sopenharmony_ci{ 4728c2ecf20Sopenharmony_ci PyObject *ret; 4738c2ecf20Sopenharmony_ci char *s; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }", 4768c2ecf20Sopenharmony_ci pevent->event.context_switch.next_prev_pid, 4778c2ecf20Sopenharmony_ci pevent->event.context_switch.next_prev_tid, 4788c2ecf20Sopenharmony_ci !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) { 4798c2ecf20Sopenharmony_ci ret = PyErr_NoMemory(); 4808c2ecf20Sopenharmony_ci } else { 4818c2ecf20Sopenharmony_ci ret = _PyUnicode_FromString(s); 4828c2ecf20Sopenharmony_ci free(s); 4838c2ecf20Sopenharmony_ci } 4848c2ecf20Sopenharmony_ci return ret; 4858c2ecf20Sopenharmony_ci} 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_context_switch_event__type = { 4888c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 4898c2ecf20Sopenharmony_ci .tp_name = "perf.context_switch_event", 4908c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_event), 4918c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 4928c2ecf20Sopenharmony_ci .tp_doc = pyrf_context_switch_event__doc, 4938c2ecf20Sopenharmony_ci .tp_members = pyrf_context_switch_event__members, 4948c2ecf20Sopenharmony_ci .tp_repr = (reprfunc)pyrf_context_switch_event__repr, 4958c2ecf20Sopenharmony_ci}; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_cistatic int pyrf_event__setup_types(void) 4988c2ecf20Sopenharmony_ci{ 4998c2ecf20Sopenharmony_ci int err; 5008c2ecf20Sopenharmony_ci pyrf_mmap_event__type.tp_new = 5018c2ecf20Sopenharmony_ci pyrf_task_event__type.tp_new = 5028c2ecf20Sopenharmony_ci pyrf_comm_event__type.tp_new = 5038c2ecf20Sopenharmony_ci pyrf_lost_event__type.tp_new = 5048c2ecf20Sopenharmony_ci pyrf_read_event__type.tp_new = 5058c2ecf20Sopenharmony_ci pyrf_sample_event__type.tp_new = 5068c2ecf20Sopenharmony_ci pyrf_context_switch_event__type.tp_new = 5078c2ecf20Sopenharmony_ci pyrf_throttle_event__type.tp_new = PyType_GenericNew; 5088c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_mmap_event__type); 5098c2ecf20Sopenharmony_ci if (err < 0) 5108c2ecf20Sopenharmony_ci goto out; 5118c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_lost_event__type); 5128c2ecf20Sopenharmony_ci if (err < 0) 5138c2ecf20Sopenharmony_ci goto out; 5148c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_task_event__type); 5158c2ecf20Sopenharmony_ci if (err < 0) 5168c2ecf20Sopenharmony_ci goto out; 5178c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_comm_event__type); 5188c2ecf20Sopenharmony_ci if (err < 0) 5198c2ecf20Sopenharmony_ci goto out; 5208c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_throttle_event__type); 5218c2ecf20Sopenharmony_ci if (err < 0) 5228c2ecf20Sopenharmony_ci goto out; 5238c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_read_event__type); 5248c2ecf20Sopenharmony_ci if (err < 0) 5258c2ecf20Sopenharmony_ci goto out; 5268c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_sample_event__type); 5278c2ecf20Sopenharmony_ci if (err < 0) 5288c2ecf20Sopenharmony_ci goto out; 5298c2ecf20Sopenharmony_ci err = PyType_Ready(&pyrf_context_switch_event__type); 5308c2ecf20Sopenharmony_ci if (err < 0) 5318c2ecf20Sopenharmony_ci goto out; 5328c2ecf20Sopenharmony_ciout: 5338c2ecf20Sopenharmony_ci return err; 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_cistatic PyTypeObject *pyrf_event__type[] = { 5378c2ecf20Sopenharmony_ci [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, 5388c2ecf20Sopenharmony_ci [PERF_RECORD_LOST] = &pyrf_lost_event__type, 5398c2ecf20Sopenharmony_ci [PERF_RECORD_COMM] = &pyrf_comm_event__type, 5408c2ecf20Sopenharmony_ci [PERF_RECORD_EXIT] = &pyrf_task_event__type, 5418c2ecf20Sopenharmony_ci [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, 5428c2ecf20Sopenharmony_ci [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, 5438c2ecf20Sopenharmony_ci [PERF_RECORD_FORK] = &pyrf_task_event__type, 5448c2ecf20Sopenharmony_ci [PERF_RECORD_READ] = &pyrf_read_event__type, 5458c2ecf20Sopenharmony_ci [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type, 5468c2ecf20Sopenharmony_ci [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type, 5478c2ecf20Sopenharmony_ci [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type, 5488c2ecf20Sopenharmony_ci}; 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_cistatic PyObject *pyrf_event__new(union perf_event *event) 5518c2ecf20Sopenharmony_ci{ 5528c2ecf20Sopenharmony_ci struct pyrf_event *pevent; 5538c2ecf20Sopenharmony_ci PyTypeObject *ptype; 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_ci if ((event->header.type < PERF_RECORD_MMAP || 5568c2ecf20Sopenharmony_ci event->header.type > PERF_RECORD_SAMPLE) && 5578c2ecf20Sopenharmony_ci !(event->header.type == PERF_RECORD_SWITCH || 5588c2ecf20Sopenharmony_ci event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)) 5598c2ecf20Sopenharmony_ci return NULL; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci ptype = pyrf_event__type[event->header.type]; 5628c2ecf20Sopenharmony_ci pevent = PyObject_New(struct pyrf_event, ptype); 5638c2ecf20Sopenharmony_ci if (pevent != NULL) 5648c2ecf20Sopenharmony_ci memcpy(&pevent->event, event, event->header.size); 5658c2ecf20Sopenharmony_ci return (PyObject *)pevent; 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_cistruct pyrf_cpu_map { 5698c2ecf20Sopenharmony_ci PyObject_HEAD 5708c2ecf20Sopenharmony_ci 5718c2ecf20Sopenharmony_ci struct perf_cpu_map *cpus; 5728c2ecf20Sopenharmony_ci}; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_cistatic int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, 5758c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 5768c2ecf20Sopenharmony_ci{ 5778c2ecf20Sopenharmony_ci static char *kwlist[] = { "cpustr", NULL }; 5788c2ecf20Sopenharmony_ci char *cpustr = NULL; 5798c2ecf20Sopenharmony_ci 5808c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", 5818c2ecf20Sopenharmony_ci kwlist, &cpustr)) 5828c2ecf20Sopenharmony_ci return -1; 5838c2ecf20Sopenharmony_ci 5848c2ecf20Sopenharmony_ci pcpus->cpus = perf_cpu_map__new(cpustr); 5858c2ecf20Sopenharmony_ci if (pcpus->cpus == NULL) 5868c2ecf20Sopenharmony_ci return -1; 5878c2ecf20Sopenharmony_ci return 0; 5888c2ecf20Sopenharmony_ci} 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_cistatic void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) 5918c2ecf20Sopenharmony_ci{ 5928c2ecf20Sopenharmony_ci perf_cpu_map__put(pcpus->cpus); 5938c2ecf20Sopenharmony_ci Py_TYPE(pcpus)->tp_free((PyObject*)pcpus); 5948c2ecf20Sopenharmony_ci} 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_cistatic Py_ssize_t pyrf_cpu_map__length(PyObject *obj) 5978c2ecf20Sopenharmony_ci{ 5988c2ecf20Sopenharmony_ci struct pyrf_cpu_map *pcpus = (void *)obj; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci return pcpus->cpus->nr; 6018c2ecf20Sopenharmony_ci} 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_cistatic PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) 6048c2ecf20Sopenharmony_ci{ 6058c2ecf20Sopenharmony_ci struct pyrf_cpu_map *pcpus = (void *)obj; 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci if (i >= pcpus->cpus->nr) 6088c2ecf20Sopenharmony_ci return NULL; 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_ci return Py_BuildValue("i", pcpus->cpus->map[i]); 6118c2ecf20Sopenharmony_ci} 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_cistatic PySequenceMethods pyrf_cpu_map__sequence_methods = { 6148c2ecf20Sopenharmony_ci .sq_length = pyrf_cpu_map__length, 6158c2ecf20Sopenharmony_ci .sq_item = pyrf_cpu_map__item, 6168c2ecf20Sopenharmony_ci}; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_cistatic char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_cpu_map__type = { 6218c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 6228c2ecf20Sopenharmony_ci .tp_name = "perf.cpu_map", 6238c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_cpu_map), 6248c2ecf20Sopenharmony_ci .tp_dealloc = (destructor)pyrf_cpu_map__delete, 6258c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 6268c2ecf20Sopenharmony_ci .tp_doc = pyrf_cpu_map__doc, 6278c2ecf20Sopenharmony_ci .tp_as_sequence = &pyrf_cpu_map__sequence_methods, 6288c2ecf20Sopenharmony_ci .tp_init = (initproc)pyrf_cpu_map__init, 6298c2ecf20Sopenharmony_ci}; 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_cistatic int pyrf_cpu_map__setup_types(void) 6328c2ecf20Sopenharmony_ci{ 6338c2ecf20Sopenharmony_ci pyrf_cpu_map__type.tp_new = PyType_GenericNew; 6348c2ecf20Sopenharmony_ci return PyType_Ready(&pyrf_cpu_map__type); 6358c2ecf20Sopenharmony_ci} 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_cistruct pyrf_thread_map { 6388c2ecf20Sopenharmony_ci PyObject_HEAD 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci struct perf_thread_map *threads; 6418c2ecf20Sopenharmony_ci}; 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, 6448c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 6458c2ecf20Sopenharmony_ci{ 6468c2ecf20Sopenharmony_ci static char *kwlist[] = { "pid", "tid", "uid", NULL }; 6478c2ecf20Sopenharmony_ci int pid = -1, tid = -1, uid = UINT_MAX; 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii", 6508c2ecf20Sopenharmony_ci kwlist, &pid, &tid, &uid)) 6518c2ecf20Sopenharmony_ci return -1; 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci pthreads->threads = thread_map__new(pid, tid, uid); 6548c2ecf20Sopenharmony_ci if (pthreads->threads == NULL) 6558c2ecf20Sopenharmony_ci return -1; 6568c2ecf20Sopenharmony_ci return 0; 6578c2ecf20Sopenharmony_ci} 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_cistatic void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) 6608c2ecf20Sopenharmony_ci{ 6618c2ecf20Sopenharmony_ci perf_thread_map__put(pthreads->threads); 6628c2ecf20Sopenharmony_ci Py_TYPE(pthreads)->tp_free((PyObject*)pthreads); 6638c2ecf20Sopenharmony_ci} 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_cistatic Py_ssize_t pyrf_thread_map__length(PyObject *obj) 6668c2ecf20Sopenharmony_ci{ 6678c2ecf20Sopenharmony_ci struct pyrf_thread_map *pthreads = (void *)obj; 6688c2ecf20Sopenharmony_ci 6698c2ecf20Sopenharmony_ci return pthreads->threads->nr; 6708c2ecf20Sopenharmony_ci} 6718c2ecf20Sopenharmony_ci 6728c2ecf20Sopenharmony_cistatic PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) 6738c2ecf20Sopenharmony_ci{ 6748c2ecf20Sopenharmony_ci struct pyrf_thread_map *pthreads = (void *)obj; 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci if (i >= pthreads->threads->nr) 6778c2ecf20Sopenharmony_ci return NULL; 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci return Py_BuildValue("i", pthreads->threads->map[i]); 6808c2ecf20Sopenharmony_ci} 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_cistatic PySequenceMethods pyrf_thread_map__sequence_methods = { 6838c2ecf20Sopenharmony_ci .sq_length = pyrf_thread_map__length, 6848c2ecf20Sopenharmony_ci .sq_item = pyrf_thread_map__item, 6858c2ecf20Sopenharmony_ci}; 6868c2ecf20Sopenharmony_ci 6878c2ecf20Sopenharmony_cistatic char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_thread_map__type = { 6908c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 6918c2ecf20Sopenharmony_ci .tp_name = "perf.thread_map", 6928c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_thread_map), 6938c2ecf20Sopenharmony_ci .tp_dealloc = (destructor)pyrf_thread_map__delete, 6948c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 6958c2ecf20Sopenharmony_ci .tp_doc = pyrf_thread_map__doc, 6968c2ecf20Sopenharmony_ci .tp_as_sequence = &pyrf_thread_map__sequence_methods, 6978c2ecf20Sopenharmony_ci .tp_init = (initproc)pyrf_thread_map__init, 6988c2ecf20Sopenharmony_ci}; 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_cistatic int pyrf_thread_map__setup_types(void) 7018c2ecf20Sopenharmony_ci{ 7028c2ecf20Sopenharmony_ci pyrf_thread_map__type.tp_new = PyType_GenericNew; 7038c2ecf20Sopenharmony_ci return PyType_Ready(&pyrf_thread_map__type); 7048c2ecf20Sopenharmony_ci} 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_cistruct pyrf_evsel { 7078c2ecf20Sopenharmony_ci PyObject_HEAD 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci struct evsel evsel; 7108c2ecf20Sopenharmony_ci}; 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_cistatic int pyrf_evsel__init(struct pyrf_evsel *pevsel, 7138c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 7148c2ecf20Sopenharmony_ci{ 7158c2ecf20Sopenharmony_ci struct perf_event_attr attr = { 7168c2ecf20Sopenharmony_ci .type = PERF_TYPE_HARDWARE, 7178c2ecf20Sopenharmony_ci .config = PERF_COUNT_HW_CPU_CYCLES, 7188c2ecf20Sopenharmony_ci .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID, 7198c2ecf20Sopenharmony_ci }; 7208c2ecf20Sopenharmony_ci static char *kwlist[] = { 7218c2ecf20Sopenharmony_ci "type", 7228c2ecf20Sopenharmony_ci "config", 7238c2ecf20Sopenharmony_ci "sample_freq", 7248c2ecf20Sopenharmony_ci "sample_period", 7258c2ecf20Sopenharmony_ci "sample_type", 7268c2ecf20Sopenharmony_ci "read_format", 7278c2ecf20Sopenharmony_ci "disabled", 7288c2ecf20Sopenharmony_ci "inherit", 7298c2ecf20Sopenharmony_ci "pinned", 7308c2ecf20Sopenharmony_ci "exclusive", 7318c2ecf20Sopenharmony_ci "exclude_user", 7328c2ecf20Sopenharmony_ci "exclude_kernel", 7338c2ecf20Sopenharmony_ci "exclude_hv", 7348c2ecf20Sopenharmony_ci "exclude_idle", 7358c2ecf20Sopenharmony_ci "mmap", 7368c2ecf20Sopenharmony_ci "context_switch", 7378c2ecf20Sopenharmony_ci "comm", 7388c2ecf20Sopenharmony_ci "freq", 7398c2ecf20Sopenharmony_ci "inherit_stat", 7408c2ecf20Sopenharmony_ci "enable_on_exec", 7418c2ecf20Sopenharmony_ci "task", 7428c2ecf20Sopenharmony_ci "watermark", 7438c2ecf20Sopenharmony_ci "precise_ip", 7448c2ecf20Sopenharmony_ci "mmap_data", 7458c2ecf20Sopenharmony_ci "sample_id_all", 7468c2ecf20Sopenharmony_ci "wakeup_events", 7478c2ecf20Sopenharmony_ci "bp_type", 7488c2ecf20Sopenharmony_ci "bp_addr", 7498c2ecf20Sopenharmony_ci "bp_len", 7508c2ecf20Sopenharmony_ci NULL 7518c2ecf20Sopenharmony_ci }; 7528c2ecf20Sopenharmony_ci u64 sample_period = 0; 7538c2ecf20Sopenharmony_ci u32 disabled = 0, 7548c2ecf20Sopenharmony_ci inherit = 0, 7558c2ecf20Sopenharmony_ci pinned = 0, 7568c2ecf20Sopenharmony_ci exclusive = 0, 7578c2ecf20Sopenharmony_ci exclude_user = 0, 7588c2ecf20Sopenharmony_ci exclude_kernel = 0, 7598c2ecf20Sopenharmony_ci exclude_hv = 0, 7608c2ecf20Sopenharmony_ci exclude_idle = 0, 7618c2ecf20Sopenharmony_ci mmap = 0, 7628c2ecf20Sopenharmony_ci context_switch = 0, 7638c2ecf20Sopenharmony_ci comm = 0, 7648c2ecf20Sopenharmony_ci freq = 1, 7658c2ecf20Sopenharmony_ci inherit_stat = 0, 7668c2ecf20Sopenharmony_ci enable_on_exec = 0, 7678c2ecf20Sopenharmony_ci task = 0, 7688c2ecf20Sopenharmony_ci watermark = 0, 7698c2ecf20Sopenharmony_ci precise_ip = 0, 7708c2ecf20Sopenharmony_ci mmap_data = 0, 7718c2ecf20Sopenharmony_ci sample_id_all = 1; 7728c2ecf20Sopenharmony_ci int idx = 0; 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, 7758c2ecf20Sopenharmony_ci "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist, 7768c2ecf20Sopenharmony_ci &attr.type, &attr.config, &attr.sample_freq, 7778c2ecf20Sopenharmony_ci &sample_period, &attr.sample_type, 7788c2ecf20Sopenharmony_ci &attr.read_format, &disabled, &inherit, 7798c2ecf20Sopenharmony_ci &pinned, &exclusive, &exclude_user, 7808c2ecf20Sopenharmony_ci &exclude_kernel, &exclude_hv, &exclude_idle, 7818c2ecf20Sopenharmony_ci &mmap, &context_switch, &comm, &freq, &inherit_stat, 7828c2ecf20Sopenharmony_ci &enable_on_exec, &task, &watermark, 7838c2ecf20Sopenharmony_ci &precise_ip, &mmap_data, &sample_id_all, 7848c2ecf20Sopenharmony_ci &attr.wakeup_events, &attr.bp_type, 7858c2ecf20Sopenharmony_ci &attr.bp_addr, &attr.bp_len, &idx)) 7868c2ecf20Sopenharmony_ci return -1; 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci /* union... */ 7898c2ecf20Sopenharmony_ci if (sample_period != 0) { 7908c2ecf20Sopenharmony_ci if (attr.sample_freq != 0) 7918c2ecf20Sopenharmony_ci return -1; /* FIXME: throw right exception */ 7928c2ecf20Sopenharmony_ci attr.sample_period = sample_period; 7938c2ecf20Sopenharmony_ci } 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_ci /* Bitfields */ 7968c2ecf20Sopenharmony_ci attr.disabled = disabled; 7978c2ecf20Sopenharmony_ci attr.inherit = inherit; 7988c2ecf20Sopenharmony_ci attr.pinned = pinned; 7998c2ecf20Sopenharmony_ci attr.exclusive = exclusive; 8008c2ecf20Sopenharmony_ci attr.exclude_user = exclude_user; 8018c2ecf20Sopenharmony_ci attr.exclude_kernel = exclude_kernel; 8028c2ecf20Sopenharmony_ci attr.exclude_hv = exclude_hv; 8038c2ecf20Sopenharmony_ci attr.exclude_idle = exclude_idle; 8048c2ecf20Sopenharmony_ci attr.mmap = mmap; 8058c2ecf20Sopenharmony_ci attr.context_switch = context_switch; 8068c2ecf20Sopenharmony_ci attr.comm = comm; 8078c2ecf20Sopenharmony_ci attr.freq = freq; 8088c2ecf20Sopenharmony_ci attr.inherit_stat = inherit_stat; 8098c2ecf20Sopenharmony_ci attr.enable_on_exec = enable_on_exec; 8108c2ecf20Sopenharmony_ci attr.task = task; 8118c2ecf20Sopenharmony_ci attr.watermark = watermark; 8128c2ecf20Sopenharmony_ci attr.precise_ip = precise_ip; 8138c2ecf20Sopenharmony_ci attr.mmap_data = mmap_data; 8148c2ecf20Sopenharmony_ci attr.sample_id_all = sample_id_all; 8158c2ecf20Sopenharmony_ci attr.size = sizeof(attr); 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci evsel__init(&pevsel->evsel, &attr, idx); 8188c2ecf20Sopenharmony_ci return 0; 8198c2ecf20Sopenharmony_ci} 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_cistatic void pyrf_evsel__delete(struct pyrf_evsel *pevsel) 8228c2ecf20Sopenharmony_ci{ 8238c2ecf20Sopenharmony_ci evsel__exit(&pevsel->evsel); 8248c2ecf20Sopenharmony_ci Py_TYPE(pevsel)->tp_free((PyObject*)pevsel); 8258c2ecf20Sopenharmony_ci} 8268c2ecf20Sopenharmony_ci 8278c2ecf20Sopenharmony_cistatic PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, 8288c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 8298c2ecf20Sopenharmony_ci{ 8308c2ecf20Sopenharmony_ci struct evsel *evsel = &pevsel->evsel; 8318c2ecf20Sopenharmony_ci struct perf_cpu_map *cpus = NULL; 8328c2ecf20Sopenharmony_ci struct perf_thread_map *threads = NULL; 8338c2ecf20Sopenharmony_ci PyObject *pcpus = NULL, *pthreads = NULL; 8348c2ecf20Sopenharmony_ci int group = 0, inherit = 0; 8358c2ecf20Sopenharmony_ci static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; 8368c2ecf20Sopenharmony_ci 8378c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 8388c2ecf20Sopenharmony_ci &pcpus, &pthreads, &group, &inherit)) 8398c2ecf20Sopenharmony_ci return NULL; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_ci if (pthreads != NULL) 8428c2ecf20Sopenharmony_ci threads = ((struct pyrf_thread_map *)pthreads)->threads; 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci if (pcpus != NULL) 8458c2ecf20Sopenharmony_ci cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci evsel->core.attr.inherit = inherit; 8488c2ecf20Sopenharmony_ci /* 8498c2ecf20Sopenharmony_ci * This will group just the fds for this single evsel, to group 8508c2ecf20Sopenharmony_ci * multiple events, use evlist.open(). 8518c2ecf20Sopenharmony_ci */ 8528c2ecf20Sopenharmony_ci if (evsel__open(evsel, cpus, threads) < 0) { 8538c2ecf20Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 8548c2ecf20Sopenharmony_ci return NULL; 8558c2ecf20Sopenharmony_ci } 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci Py_INCREF(Py_None); 8588c2ecf20Sopenharmony_ci return Py_None; 8598c2ecf20Sopenharmony_ci} 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_cistatic PyMethodDef pyrf_evsel__methods[] = { 8628c2ecf20Sopenharmony_ci { 8638c2ecf20Sopenharmony_ci .ml_name = "open", 8648c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evsel__open, 8658c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 8668c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("open the event selector file descriptor table.") 8678c2ecf20Sopenharmony_ci }, 8688c2ecf20Sopenharmony_ci { .ml_name = NULL, } 8698c2ecf20Sopenharmony_ci}; 8708c2ecf20Sopenharmony_ci 8718c2ecf20Sopenharmony_cistatic char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); 8728c2ecf20Sopenharmony_ci 8738c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_evsel__type = { 8748c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 8758c2ecf20Sopenharmony_ci .tp_name = "perf.evsel", 8768c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_evsel), 8778c2ecf20Sopenharmony_ci .tp_dealloc = (destructor)pyrf_evsel__delete, 8788c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 8798c2ecf20Sopenharmony_ci .tp_doc = pyrf_evsel__doc, 8808c2ecf20Sopenharmony_ci .tp_methods = pyrf_evsel__methods, 8818c2ecf20Sopenharmony_ci .tp_init = (initproc)pyrf_evsel__init, 8828c2ecf20Sopenharmony_ci}; 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_cistatic int pyrf_evsel__setup_types(void) 8858c2ecf20Sopenharmony_ci{ 8868c2ecf20Sopenharmony_ci pyrf_evsel__type.tp_new = PyType_GenericNew; 8878c2ecf20Sopenharmony_ci return PyType_Ready(&pyrf_evsel__type); 8888c2ecf20Sopenharmony_ci} 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_cistruct pyrf_evlist { 8918c2ecf20Sopenharmony_ci PyObject_HEAD 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci struct evlist evlist; 8948c2ecf20Sopenharmony_ci}; 8958c2ecf20Sopenharmony_ci 8968c2ecf20Sopenharmony_cistatic int pyrf_evlist__init(struct pyrf_evlist *pevlist, 8978c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs __maybe_unused) 8988c2ecf20Sopenharmony_ci{ 8998c2ecf20Sopenharmony_ci PyObject *pcpus = NULL, *pthreads = NULL; 9008c2ecf20Sopenharmony_ci struct perf_cpu_map *cpus; 9018c2ecf20Sopenharmony_ci struct perf_thread_map *threads; 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) 9048c2ecf20Sopenharmony_ci return -1; 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci threads = ((struct pyrf_thread_map *)pthreads)->threads; 9078c2ecf20Sopenharmony_ci cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 9088c2ecf20Sopenharmony_ci evlist__init(&pevlist->evlist, cpus, threads); 9098c2ecf20Sopenharmony_ci return 0; 9108c2ecf20Sopenharmony_ci} 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_cistatic void pyrf_evlist__delete(struct pyrf_evlist *pevlist) 9138c2ecf20Sopenharmony_ci{ 9148c2ecf20Sopenharmony_ci evlist__exit(&pevlist->evlist); 9158c2ecf20Sopenharmony_ci Py_TYPE(pevlist)->tp_free((PyObject*)pevlist); 9168c2ecf20Sopenharmony_ci} 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, 9198c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 9208c2ecf20Sopenharmony_ci{ 9218c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 9228c2ecf20Sopenharmony_ci static char *kwlist[] = { "pages", "overwrite", NULL }; 9238c2ecf20Sopenharmony_ci int pages = 128, overwrite = false; 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, 9268c2ecf20Sopenharmony_ci &pages, &overwrite)) 9278c2ecf20Sopenharmony_ci return NULL; 9288c2ecf20Sopenharmony_ci 9298c2ecf20Sopenharmony_ci if (evlist__mmap(evlist, pages) < 0) { 9308c2ecf20Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 9318c2ecf20Sopenharmony_ci return NULL; 9328c2ecf20Sopenharmony_ci } 9338c2ecf20Sopenharmony_ci 9348c2ecf20Sopenharmony_ci Py_INCREF(Py_None); 9358c2ecf20Sopenharmony_ci return Py_None; 9368c2ecf20Sopenharmony_ci} 9378c2ecf20Sopenharmony_ci 9388c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, 9398c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 9408c2ecf20Sopenharmony_ci{ 9418c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 9428c2ecf20Sopenharmony_ci static char *kwlist[] = { "timeout", NULL }; 9438c2ecf20Sopenharmony_ci int timeout = -1, n; 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) 9468c2ecf20Sopenharmony_ci return NULL; 9478c2ecf20Sopenharmony_ci 9488c2ecf20Sopenharmony_ci n = evlist__poll(evlist, timeout); 9498c2ecf20Sopenharmony_ci if (n < 0) { 9508c2ecf20Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 9518c2ecf20Sopenharmony_ci return NULL; 9528c2ecf20Sopenharmony_ci } 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci return Py_BuildValue("i", n); 9558c2ecf20Sopenharmony_ci} 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, 9588c2ecf20Sopenharmony_ci PyObject *args __maybe_unused, 9598c2ecf20Sopenharmony_ci PyObject *kwargs __maybe_unused) 9608c2ecf20Sopenharmony_ci{ 9618c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 9628c2ecf20Sopenharmony_ci PyObject *list = PyList_New(0); 9638c2ecf20Sopenharmony_ci int i; 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_ci for (i = 0; i < evlist->core.pollfd.nr; ++i) { 9668c2ecf20Sopenharmony_ci PyObject *file; 9678c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 9688c2ecf20Sopenharmony_ci FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r"); 9698c2ecf20Sopenharmony_ci 9708c2ecf20Sopenharmony_ci if (fp == NULL) 9718c2ecf20Sopenharmony_ci goto free_list; 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci file = PyFile_FromFile(fp, "perf", "r", NULL); 9748c2ecf20Sopenharmony_ci#else 9758c2ecf20Sopenharmony_ci file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1, 9768c2ecf20Sopenharmony_ci NULL, NULL, NULL, 0); 9778c2ecf20Sopenharmony_ci#endif 9788c2ecf20Sopenharmony_ci if (file == NULL) 9798c2ecf20Sopenharmony_ci goto free_list; 9808c2ecf20Sopenharmony_ci 9818c2ecf20Sopenharmony_ci if (PyList_Append(list, file) != 0) { 9828c2ecf20Sopenharmony_ci Py_DECREF(file); 9838c2ecf20Sopenharmony_ci goto free_list; 9848c2ecf20Sopenharmony_ci } 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci Py_DECREF(file); 9878c2ecf20Sopenharmony_ci } 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci return list; 9908c2ecf20Sopenharmony_cifree_list: 9918c2ecf20Sopenharmony_ci return PyErr_NoMemory(); 9928c2ecf20Sopenharmony_ci} 9938c2ecf20Sopenharmony_ci 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, 9968c2ecf20Sopenharmony_ci PyObject *args, 9978c2ecf20Sopenharmony_ci PyObject *kwargs __maybe_unused) 9988c2ecf20Sopenharmony_ci{ 9998c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 10008c2ecf20Sopenharmony_ci PyObject *pevsel; 10018c2ecf20Sopenharmony_ci struct evsel *evsel; 10028c2ecf20Sopenharmony_ci 10038c2ecf20Sopenharmony_ci if (!PyArg_ParseTuple(args, "O", &pevsel)) 10048c2ecf20Sopenharmony_ci return NULL; 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci Py_INCREF(pevsel); 10078c2ecf20Sopenharmony_ci evsel = &((struct pyrf_evsel *)pevsel)->evsel; 10088c2ecf20Sopenharmony_ci evsel->idx = evlist->core.nr_entries; 10098c2ecf20Sopenharmony_ci evlist__add(evlist, evsel); 10108c2ecf20Sopenharmony_ci 10118c2ecf20Sopenharmony_ci return Py_BuildValue("i", evlist->core.nr_entries); 10128c2ecf20Sopenharmony_ci} 10138c2ecf20Sopenharmony_ci 10148c2ecf20Sopenharmony_cistatic struct mmap *get_md(struct evlist *evlist, int cpu) 10158c2ecf20Sopenharmony_ci{ 10168c2ecf20Sopenharmony_ci int i; 10178c2ecf20Sopenharmony_ci 10188c2ecf20Sopenharmony_ci for (i = 0; i < evlist->core.nr_mmaps; i++) { 10198c2ecf20Sopenharmony_ci struct mmap *md = &evlist->mmap[i]; 10208c2ecf20Sopenharmony_ci 10218c2ecf20Sopenharmony_ci if (md->core.cpu == cpu) 10228c2ecf20Sopenharmony_ci return md; 10238c2ecf20Sopenharmony_ci } 10248c2ecf20Sopenharmony_ci 10258c2ecf20Sopenharmony_ci return NULL; 10268c2ecf20Sopenharmony_ci} 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, 10298c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 10308c2ecf20Sopenharmony_ci{ 10318c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 10328c2ecf20Sopenharmony_ci union perf_event *event; 10338c2ecf20Sopenharmony_ci int sample_id_all = 1, cpu; 10348c2ecf20Sopenharmony_ci static char *kwlist[] = { "cpu", "sample_id_all", NULL }; 10358c2ecf20Sopenharmony_ci struct mmap *md; 10368c2ecf20Sopenharmony_ci int err; 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 10398c2ecf20Sopenharmony_ci &cpu, &sample_id_all)) 10408c2ecf20Sopenharmony_ci return NULL; 10418c2ecf20Sopenharmony_ci 10428c2ecf20Sopenharmony_ci md = get_md(evlist, cpu); 10438c2ecf20Sopenharmony_ci if (!md) 10448c2ecf20Sopenharmony_ci return NULL; 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci if (perf_mmap__read_init(&md->core) < 0) 10478c2ecf20Sopenharmony_ci goto end; 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_ci event = perf_mmap__read_event(&md->core); 10508c2ecf20Sopenharmony_ci if (event != NULL) { 10518c2ecf20Sopenharmony_ci PyObject *pyevent = pyrf_event__new(event); 10528c2ecf20Sopenharmony_ci struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 10538c2ecf20Sopenharmony_ci struct evsel *evsel; 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci if (pyevent == NULL) 10568c2ecf20Sopenharmony_ci return PyErr_NoMemory(); 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci evsel = perf_evlist__event2evsel(evlist, event); 10598c2ecf20Sopenharmony_ci if (!evsel) { 10608c2ecf20Sopenharmony_ci Py_INCREF(Py_None); 10618c2ecf20Sopenharmony_ci return Py_None; 10628c2ecf20Sopenharmony_ci } 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_ci pevent->evsel = evsel; 10658c2ecf20Sopenharmony_ci 10668c2ecf20Sopenharmony_ci err = evsel__parse_sample(evsel, event, &pevent->sample); 10678c2ecf20Sopenharmony_ci 10688c2ecf20Sopenharmony_ci /* Consume the even only after we parsed it out. */ 10698c2ecf20Sopenharmony_ci perf_mmap__consume(&md->core); 10708c2ecf20Sopenharmony_ci 10718c2ecf20Sopenharmony_ci if (err) 10728c2ecf20Sopenharmony_ci return PyErr_Format(PyExc_OSError, 10738c2ecf20Sopenharmony_ci "perf: can't parse sample, err=%d", err); 10748c2ecf20Sopenharmony_ci return pyevent; 10758c2ecf20Sopenharmony_ci } 10768c2ecf20Sopenharmony_ciend: 10778c2ecf20Sopenharmony_ci Py_INCREF(Py_None); 10788c2ecf20Sopenharmony_ci return Py_None; 10798c2ecf20Sopenharmony_ci} 10808c2ecf20Sopenharmony_ci 10818c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist, 10828c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 10838c2ecf20Sopenharmony_ci{ 10848c2ecf20Sopenharmony_ci struct evlist *evlist = &pevlist->evlist; 10858c2ecf20Sopenharmony_ci int group = 0; 10868c2ecf20Sopenharmony_ci static char *kwlist[] = { "group", NULL }; 10878c2ecf20Sopenharmony_ci 10888c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group)) 10898c2ecf20Sopenharmony_ci return NULL; 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci if (group) 10928c2ecf20Sopenharmony_ci perf_evlist__set_leader(evlist); 10938c2ecf20Sopenharmony_ci 10948c2ecf20Sopenharmony_ci if (evlist__open(evlist) < 0) { 10958c2ecf20Sopenharmony_ci PyErr_SetFromErrno(PyExc_OSError); 10968c2ecf20Sopenharmony_ci return NULL; 10978c2ecf20Sopenharmony_ci } 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci Py_INCREF(Py_None); 11008c2ecf20Sopenharmony_ci return Py_None; 11018c2ecf20Sopenharmony_ci} 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_cistatic PyMethodDef pyrf_evlist__methods[] = { 11048c2ecf20Sopenharmony_ci { 11058c2ecf20Sopenharmony_ci .ml_name = "mmap", 11068c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__mmap, 11078c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11088c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("mmap the file descriptor table.") 11098c2ecf20Sopenharmony_ci }, 11108c2ecf20Sopenharmony_ci { 11118c2ecf20Sopenharmony_ci .ml_name = "open", 11128c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__open, 11138c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11148c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("open the file descriptors.") 11158c2ecf20Sopenharmony_ci }, 11168c2ecf20Sopenharmony_ci { 11178c2ecf20Sopenharmony_ci .ml_name = "poll", 11188c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__poll, 11198c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11208c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("poll the file descriptor table.") 11218c2ecf20Sopenharmony_ci }, 11228c2ecf20Sopenharmony_ci { 11238c2ecf20Sopenharmony_ci .ml_name = "get_pollfd", 11248c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd, 11258c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11268c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("get the poll file descriptor table.") 11278c2ecf20Sopenharmony_ci }, 11288c2ecf20Sopenharmony_ci { 11298c2ecf20Sopenharmony_ci .ml_name = "add", 11308c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__add, 11318c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11328c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("adds an event selector to the list.") 11338c2ecf20Sopenharmony_ci }, 11348c2ecf20Sopenharmony_ci { 11358c2ecf20Sopenharmony_ci .ml_name = "read_on_cpu", 11368c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu, 11378c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 11388c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("reads an event.") 11398c2ecf20Sopenharmony_ci }, 11408c2ecf20Sopenharmony_ci { .ml_name = NULL, } 11418c2ecf20Sopenharmony_ci}; 11428c2ecf20Sopenharmony_ci 11438c2ecf20Sopenharmony_cistatic Py_ssize_t pyrf_evlist__length(PyObject *obj) 11448c2ecf20Sopenharmony_ci{ 11458c2ecf20Sopenharmony_ci struct pyrf_evlist *pevlist = (void *)obj; 11468c2ecf20Sopenharmony_ci 11478c2ecf20Sopenharmony_ci return pevlist->evlist.core.nr_entries; 11488c2ecf20Sopenharmony_ci} 11498c2ecf20Sopenharmony_ci 11508c2ecf20Sopenharmony_cistatic PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) 11518c2ecf20Sopenharmony_ci{ 11528c2ecf20Sopenharmony_ci struct pyrf_evlist *pevlist = (void *)obj; 11538c2ecf20Sopenharmony_ci struct evsel *pos; 11548c2ecf20Sopenharmony_ci 11558c2ecf20Sopenharmony_ci if (i >= pevlist->evlist.core.nr_entries) 11568c2ecf20Sopenharmony_ci return NULL; 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci evlist__for_each_entry(&pevlist->evlist, pos) { 11598c2ecf20Sopenharmony_ci if (i-- == 0) 11608c2ecf20Sopenharmony_ci break; 11618c2ecf20Sopenharmony_ci } 11628c2ecf20Sopenharmony_ci 11638c2ecf20Sopenharmony_ci return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); 11648c2ecf20Sopenharmony_ci} 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_cistatic PySequenceMethods pyrf_evlist__sequence_methods = { 11678c2ecf20Sopenharmony_ci .sq_length = pyrf_evlist__length, 11688c2ecf20Sopenharmony_ci .sq_item = pyrf_evlist__item, 11698c2ecf20Sopenharmony_ci}; 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_cistatic char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object."); 11728c2ecf20Sopenharmony_ci 11738c2ecf20Sopenharmony_cistatic PyTypeObject pyrf_evlist__type = { 11748c2ecf20Sopenharmony_ci PyVarObject_HEAD_INIT(NULL, 0) 11758c2ecf20Sopenharmony_ci .tp_name = "perf.evlist", 11768c2ecf20Sopenharmony_ci .tp_basicsize = sizeof(struct pyrf_evlist), 11778c2ecf20Sopenharmony_ci .tp_dealloc = (destructor)pyrf_evlist__delete, 11788c2ecf20Sopenharmony_ci .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 11798c2ecf20Sopenharmony_ci .tp_as_sequence = &pyrf_evlist__sequence_methods, 11808c2ecf20Sopenharmony_ci .tp_doc = pyrf_evlist__doc, 11818c2ecf20Sopenharmony_ci .tp_methods = pyrf_evlist__methods, 11828c2ecf20Sopenharmony_ci .tp_init = (initproc)pyrf_evlist__init, 11838c2ecf20Sopenharmony_ci}; 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_cistatic int pyrf_evlist__setup_types(void) 11868c2ecf20Sopenharmony_ci{ 11878c2ecf20Sopenharmony_ci pyrf_evlist__type.tp_new = PyType_GenericNew; 11888c2ecf20Sopenharmony_ci return PyType_Ready(&pyrf_evlist__type); 11898c2ecf20Sopenharmony_ci} 11908c2ecf20Sopenharmony_ci 11918c2ecf20Sopenharmony_ci#define PERF_CONST(name) { #name, PERF_##name } 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_cistatic struct { 11948c2ecf20Sopenharmony_ci const char *name; 11958c2ecf20Sopenharmony_ci int value; 11968c2ecf20Sopenharmony_ci} perf__constants[] = { 11978c2ecf20Sopenharmony_ci PERF_CONST(TYPE_HARDWARE), 11988c2ecf20Sopenharmony_ci PERF_CONST(TYPE_SOFTWARE), 11998c2ecf20Sopenharmony_ci PERF_CONST(TYPE_TRACEPOINT), 12008c2ecf20Sopenharmony_ci PERF_CONST(TYPE_HW_CACHE), 12018c2ecf20Sopenharmony_ci PERF_CONST(TYPE_RAW), 12028c2ecf20Sopenharmony_ci PERF_CONST(TYPE_BREAKPOINT), 12038c2ecf20Sopenharmony_ci 12048c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CPU_CYCLES), 12058c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_INSTRUCTIONS), 12068c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_REFERENCES), 12078c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_MISSES), 12088c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS), 12098c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_BRANCH_MISSES), 12108c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_BUS_CYCLES), 12118c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_L1D), 12128c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_L1I), 12138c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_LL), 12148c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_DTLB), 12158c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_ITLB), 12168c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_BPU), 12178c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_OP_READ), 12188c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_OP_WRITE), 12198c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH), 12208c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS), 12218c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_CACHE_RESULT_MISS), 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND), 12248c2ecf20Sopenharmony_ci PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND), 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_CPU_CLOCK), 12278c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_TASK_CLOCK), 12288c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_PAGE_FAULTS), 12298c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_CONTEXT_SWITCHES), 12308c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_CPU_MIGRATIONS), 12318c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN), 12328c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ), 12338c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS), 12348c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_EMULATION_FAULTS), 12358c2ecf20Sopenharmony_ci PERF_CONST(COUNT_SW_DUMMY), 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_IP), 12388c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_TID), 12398c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_TIME), 12408c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_ADDR), 12418c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_READ), 12428c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_CALLCHAIN), 12438c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_ID), 12448c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_CPU), 12458c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_PERIOD), 12468c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_STREAM_ID), 12478c2ecf20Sopenharmony_ci PERF_CONST(SAMPLE_RAW), 12488c2ecf20Sopenharmony_ci 12498c2ecf20Sopenharmony_ci PERF_CONST(FORMAT_TOTAL_TIME_ENABLED), 12508c2ecf20Sopenharmony_ci PERF_CONST(FORMAT_TOTAL_TIME_RUNNING), 12518c2ecf20Sopenharmony_ci PERF_CONST(FORMAT_ID), 12528c2ecf20Sopenharmony_ci PERF_CONST(FORMAT_GROUP), 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci PERF_CONST(RECORD_MMAP), 12558c2ecf20Sopenharmony_ci PERF_CONST(RECORD_LOST), 12568c2ecf20Sopenharmony_ci PERF_CONST(RECORD_COMM), 12578c2ecf20Sopenharmony_ci PERF_CONST(RECORD_EXIT), 12588c2ecf20Sopenharmony_ci PERF_CONST(RECORD_THROTTLE), 12598c2ecf20Sopenharmony_ci PERF_CONST(RECORD_UNTHROTTLE), 12608c2ecf20Sopenharmony_ci PERF_CONST(RECORD_FORK), 12618c2ecf20Sopenharmony_ci PERF_CONST(RECORD_READ), 12628c2ecf20Sopenharmony_ci PERF_CONST(RECORD_SAMPLE), 12638c2ecf20Sopenharmony_ci PERF_CONST(RECORD_MMAP2), 12648c2ecf20Sopenharmony_ci PERF_CONST(RECORD_AUX), 12658c2ecf20Sopenharmony_ci PERF_CONST(RECORD_ITRACE_START), 12668c2ecf20Sopenharmony_ci PERF_CONST(RECORD_LOST_SAMPLES), 12678c2ecf20Sopenharmony_ci PERF_CONST(RECORD_SWITCH), 12688c2ecf20Sopenharmony_ci PERF_CONST(RECORD_SWITCH_CPU_WIDE), 12698c2ecf20Sopenharmony_ci 12708c2ecf20Sopenharmony_ci PERF_CONST(RECORD_MISC_SWITCH_OUT), 12718c2ecf20Sopenharmony_ci { .name = NULL, }, 12728c2ecf20Sopenharmony_ci}; 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_cistatic PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel, 12758c2ecf20Sopenharmony_ci PyObject *args, PyObject *kwargs) 12768c2ecf20Sopenharmony_ci{ 12778c2ecf20Sopenharmony_ci struct tep_event *tp_format; 12788c2ecf20Sopenharmony_ci static char *kwlist[] = { "sys", "name", NULL }; 12798c2ecf20Sopenharmony_ci char *sys = NULL; 12808c2ecf20Sopenharmony_ci char *name = NULL; 12818c2ecf20Sopenharmony_ci 12828c2ecf20Sopenharmony_ci if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist, 12838c2ecf20Sopenharmony_ci &sys, &name)) 12848c2ecf20Sopenharmony_ci return NULL; 12858c2ecf20Sopenharmony_ci 12868c2ecf20Sopenharmony_ci tp_format = trace_event__tp_format(sys, name); 12878c2ecf20Sopenharmony_ci if (IS_ERR(tp_format)) 12888c2ecf20Sopenharmony_ci return _PyLong_FromLong(-1); 12898c2ecf20Sopenharmony_ci 12908c2ecf20Sopenharmony_ci return _PyLong_FromLong(tp_format->id); 12918c2ecf20Sopenharmony_ci} 12928c2ecf20Sopenharmony_ci 12938c2ecf20Sopenharmony_cistatic PyMethodDef perf__methods[] = { 12948c2ecf20Sopenharmony_ci { 12958c2ecf20Sopenharmony_ci .ml_name = "tracepoint", 12968c2ecf20Sopenharmony_ci .ml_meth = (PyCFunction) pyrf__tracepoint, 12978c2ecf20Sopenharmony_ci .ml_flags = METH_VARARGS | METH_KEYWORDS, 12988c2ecf20Sopenharmony_ci .ml_doc = PyDoc_STR("Get tracepoint config.") 12998c2ecf20Sopenharmony_ci }, 13008c2ecf20Sopenharmony_ci { .ml_name = NULL, } 13018c2ecf20Sopenharmony_ci}; 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 13048c2ecf20Sopenharmony_ciPyMODINIT_FUNC initperf(void) 13058c2ecf20Sopenharmony_ci#else 13068c2ecf20Sopenharmony_ciPyMODINIT_FUNC PyInit_perf(void) 13078c2ecf20Sopenharmony_ci#endif 13088c2ecf20Sopenharmony_ci{ 13098c2ecf20Sopenharmony_ci PyObject *obj; 13108c2ecf20Sopenharmony_ci int i; 13118c2ecf20Sopenharmony_ci PyObject *dict; 13128c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 13138c2ecf20Sopenharmony_ci PyObject *module = Py_InitModule("perf", perf__methods); 13148c2ecf20Sopenharmony_ci#else 13158c2ecf20Sopenharmony_ci static struct PyModuleDef moduledef = { 13168c2ecf20Sopenharmony_ci PyModuleDef_HEAD_INIT, 13178c2ecf20Sopenharmony_ci "perf", /* m_name */ 13188c2ecf20Sopenharmony_ci "", /* m_doc */ 13198c2ecf20Sopenharmony_ci -1, /* m_size */ 13208c2ecf20Sopenharmony_ci perf__methods, /* m_methods */ 13218c2ecf20Sopenharmony_ci NULL, /* m_reload */ 13228c2ecf20Sopenharmony_ci NULL, /* m_traverse */ 13238c2ecf20Sopenharmony_ci NULL, /* m_clear */ 13248c2ecf20Sopenharmony_ci NULL, /* m_free */ 13258c2ecf20Sopenharmony_ci }; 13268c2ecf20Sopenharmony_ci PyObject *module = PyModule_Create(&moduledef); 13278c2ecf20Sopenharmony_ci#endif 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_ci if (module == NULL || 13308c2ecf20Sopenharmony_ci pyrf_event__setup_types() < 0 || 13318c2ecf20Sopenharmony_ci pyrf_evlist__setup_types() < 0 || 13328c2ecf20Sopenharmony_ci pyrf_evsel__setup_types() < 0 || 13338c2ecf20Sopenharmony_ci pyrf_thread_map__setup_types() < 0 || 13348c2ecf20Sopenharmony_ci pyrf_cpu_map__setup_types() < 0) 13358c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION < 3 13368c2ecf20Sopenharmony_ci return; 13378c2ecf20Sopenharmony_ci#else 13388c2ecf20Sopenharmony_ci return module; 13398c2ecf20Sopenharmony_ci#endif 13408c2ecf20Sopenharmony_ci 13418c2ecf20Sopenharmony_ci /* The page_size is placed in util object. */ 13428c2ecf20Sopenharmony_ci page_size = sysconf(_SC_PAGE_SIZE); 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_evlist__type); 13458c2ecf20Sopenharmony_ci PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type); 13468c2ecf20Sopenharmony_ci 13478c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_evsel__type); 13488c2ecf20Sopenharmony_ci PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type); 13498c2ecf20Sopenharmony_ci 13508c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_mmap_event__type); 13518c2ecf20Sopenharmony_ci PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type); 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_lost_event__type); 13548c2ecf20Sopenharmony_ci PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type); 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_comm_event__type); 13578c2ecf20Sopenharmony_ci PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_task_event__type); 13608c2ecf20Sopenharmony_ci PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type); 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_throttle_event__type); 13638c2ecf20Sopenharmony_ci PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type); 13648c2ecf20Sopenharmony_ci 13658c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_task_event__type); 13668c2ecf20Sopenharmony_ci PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type); 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_read_event__type); 13698c2ecf20Sopenharmony_ci PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type); 13708c2ecf20Sopenharmony_ci 13718c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_sample_event__type); 13728c2ecf20Sopenharmony_ci PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type); 13738c2ecf20Sopenharmony_ci 13748c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_context_switch_event__type); 13758c2ecf20Sopenharmony_ci PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type); 13768c2ecf20Sopenharmony_ci 13778c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_thread_map__type); 13788c2ecf20Sopenharmony_ci PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type); 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci Py_INCREF(&pyrf_cpu_map__type); 13818c2ecf20Sopenharmony_ci PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type); 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci dict = PyModule_GetDict(module); 13848c2ecf20Sopenharmony_ci if (dict == NULL) 13858c2ecf20Sopenharmony_ci goto error; 13868c2ecf20Sopenharmony_ci 13878c2ecf20Sopenharmony_ci for (i = 0; perf__constants[i].name != NULL; i++) { 13888c2ecf20Sopenharmony_ci obj = _PyLong_FromLong(perf__constants[i].value); 13898c2ecf20Sopenharmony_ci if (obj == NULL) 13908c2ecf20Sopenharmony_ci goto error; 13918c2ecf20Sopenharmony_ci PyDict_SetItemString(dict, perf__constants[i].name, obj); 13928c2ecf20Sopenharmony_ci Py_DECREF(obj); 13938c2ecf20Sopenharmony_ci } 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_cierror: 13968c2ecf20Sopenharmony_ci if (PyErr_Occurred()) 13978c2ecf20Sopenharmony_ci PyErr_SetString(PyExc_ImportError, "perf: Init failed!"); 13988c2ecf20Sopenharmony_ci#if PY_MAJOR_VERSION >= 3 13998c2ecf20Sopenharmony_ci return module; 14008c2ecf20Sopenharmony_ci#endif 14018c2ecf20Sopenharmony_ci} 14028c2ecf20Sopenharmony_ci 14038c2ecf20Sopenharmony_ci/* 14048c2ecf20Sopenharmony_ci * Dummy, to avoid dragging all the test_attr infrastructure in the python 14058c2ecf20Sopenharmony_ci * binding. 14068c2ecf20Sopenharmony_ci */ 14078c2ecf20Sopenharmony_civoid test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu, 14088c2ecf20Sopenharmony_ci int fd, int group_fd, unsigned long flags) 14098c2ecf20Sopenharmony_ci{ 14108c2ecf20Sopenharmony_ci} 1411