1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun #include <Python.h>
3*4882a593Smuzhiyun #include <structmember.h>
4*4882a593Smuzhiyun #include <inttypes.h>
5*4882a593Smuzhiyun #include <poll.h>
6*4882a593Smuzhiyun #include <linux/err.h>
7*4882a593Smuzhiyun #include <perf/cpumap.h>
8*4882a593Smuzhiyun #include <traceevent/event-parse.h>
9*4882a593Smuzhiyun #include <perf/mmap.h>
10*4882a593Smuzhiyun #include "evlist.h"
11*4882a593Smuzhiyun #include "callchain.h"
12*4882a593Smuzhiyun #include "evsel.h"
13*4882a593Smuzhiyun #include "event.h"
14*4882a593Smuzhiyun #include "print_binary.h"
15*4882a593Smuzhiyun #include "thread_map.h"
16*4882a593Smuzhiyun #include "trace-event.h"
17*4882a593Smuzhiyun #include "mmap.h"
18*4882a593Smuzhiyun #include "stat.h"
19*4882a593Smuzhiyun #include "metricgroup.h"
20*4882a593Smuzhiyun #include "util/env.h"
21*4882a593Smuzhiyun #include <internal/lib.h>
22*4882a593Smuzhiyun #include "util.h"
23*4882a593Smuzhiyun
24*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
25*4882a593Smuzhiyun #define _PyUnicode_FromString(arg) \
26*4882a593Smuzhiyun PyString_FromString(arg)
27*4882a593Smuzhiyun #define _PyUnicode_AsString(arg) \
28*4882a593Smuzhiyun PyString_AsString(arg)
29*4882a593Smuzhiyun #define _PyUnicode_FromFormat(...) \
30*4882a593Smuzhiyun PyString_FromFormat(__VA_ARGS__)
31*4882a593Smuzhiyun #define _PyLong_FromLong(arg) \
32*4882a593Smuzhiyun PyInt_FromLong(arg)
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun #else
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun #define _PyUnicode_FromString(arg) \
37*4882a593Smuzhiyun PyUnicode_FromString(arg)
38*4882a593Smuzhiyun #define _PyUnicode_FromFormat(...) \
39*4882a593Smuzhiyun PyUnicode_FromFormat(__VA_ARGS__)
40*4882a593Smuzhiyun #define _PyLong_FromLong(arg) \
41*4882a593Smuzhiyun PyLong_FromLong(arg)
42*4882a593Smuzhiyun #endif
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun #ifndef Py_TYPE
45*4882a593Smuzhiyun #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
46*4882a593Smuzhiyun #endif
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun * Provide these two so that we don't have to link against callchain.c and
50*4882a593Smuzhiyun * start dragging hist.c, etc.
51*4882a593Smuzhiyun */
52*4882a593Smuzhiyun struct callchain_param callchain_param;
53*4882a593Smuzhiyun
parse_callchain_record(const char * arg __maybe_unused,struct callchain_param * param __maybe_unused)54*4882a593Smuzhiyun int parse_callchain_record(const char *arg __maybe_unused,
55*4882a593Smuzhiyun struct callchain_param *param __maybe_unused)
56*4882a593Smuzhiyun {
57*4882a593Smuzhiyun return 0;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun /*
61*4882a593Smuzhiyun * Add this one here not to drag util/env.c
62*4882a593Smuzhiyun */
63*4882a593Smuzhiyun struct perf_env perf_env;
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun /*
66*4882a593Smuzhiyun * Add this one here not to drag util/stat-shadow.c
67*4882a593Smuzhiyun */
perf_stat__collect_metric_expr(struct evlist * evsel_list)68*4882a593Smuzhiyun void perf_stat__collect_metric_expr(struct evlist *evsel_list)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun }
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun /*
73*4882a593Smuzhiyun * Add this one here not to drag util/metricgroup.c
74*4882a593Smuzhiyun */
metricgroup__copy_metric_events(struct evlist * evlist,struct cgroup * cgrp,struct rblist * new_metric_events,struct rblist * old_metric_events)75*4882a593Smuzhiyun int metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
76*4882a593Smuzhiyun struct rblist *new_metric_events,
77*4882a593Smuzhiyun struct rblist *old_metric_events)
78*4882a593Smuzhiyun {
79*4882a593Smuzhiyun return 0;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /*
83*4882a593Smuzhiyun * Support debug printing even though util/debug.c is not linked. That means
84*4882a593Smuzhiyun * implementing 'verbose' and 'eprintf'.
85*4882a593Smuzhiyun */
86*4882a593Smuzhiyun int verbose;
87*4882a593Smuzhiyun int debug_peo_args;
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun int eprintf(int level, int var, const char *fmt, ...);
90*4882a593Smuzhiyun
eprintf(int level,int var,const char * fmt,...)91*4882a593Smuzhiyun int eprintf(int level, int var, const char *fmt, ...)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun va_list args;
94*4882a593Smuzhiyun int ret = 0;
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun if (var >= level) {
97*4882a593Smuzhiyun va_start(args, fmt);
98*4882a593Smuzhiyun ret = vfprintf(stderr, fmt, args);
99*4882a593Smuzhiyun va_end(args);
100*4882a593Smuzhiyun }
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun return ret;
103*4882a593Smuzhiyun }
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun /* Define PyVarObject_HEAD_INIT for python 2.5 */
106*4882a593Smuzhiyun #ifndef PyVarObject_HEAD_INIT
107*4882a593Smuzhiyun # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
108*4882a593Smuzhiyun #endif
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
111*4882a593Smuzhiyun PyMODINIT_FUNC initperf(void);
112*4882a593Smuzhiyun #else
113*4882a593Smuzhiyun PyMODINIT_FUNC PyInit_perf(void);
114*4882a593Smuzhiyun #endif
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun #define member_def(type, member, ptype, help) \
117*4882a593Smuzhiyun { #member, ptype, \
118*4882a593Smuzhiyun offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
119*4882a593Smuzhiyun 0, help }
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun #define sample_member_def(name, member, ptype, help) \
122*4882a593Smuzhiyun { #name, ptype, \
123*4882a593Smuzhiyun offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
124*4882a593Smuzhiyun 0, help }
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun struct pyrf_event {
127*4882a593Smuzhiyun PyObject_HEAD
128*4882a593Smuzhiyun struct evsel *evsel;
129*4882a593Smuzhiyun struct perf_sample sample;
130*4882a593Smuzhiyun union perf_event event;
131*4882a593Smuzhiyun };
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #define sample_members \
134*4882a593Smuzhiyun sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
135*4882a593Smuzhiyun sample_member_def(sample_pid, pid, T_INT, "event pid"), \
136*4882a593Smuzhiyun sample_member_def(sample_tid, tid, T_INT, "event tid"), \
137*4882a593Smuzhiyun sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
138*4882a593Smuzhiyun sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
139*4882a593Smuzhiyun sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
140*4882a593Smuzhiyun sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
141*4882a593Smuzhiyun sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
142*4882a593Smuzhiyun sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun static PyMemberDef pyrf_mmap_event__members[] = {
147*4882a593Smuzhiyun sample_members
148*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
149*4882a593Smuzhiyun member_def(perf_event_header, misc, T_UINT, "event misc"),
150*4882a593Smuzhiyun member_def(perf_record_mmap, pid, T_UINT, "event pid"),
151*4882a593Smuzhiyun member_def(perf_record_mmap, tid, T_UINT, "event tid"),
152*4882a593Smuzhiyun member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"),
153*4882a593Smuzhiyun member_def(perf_record_mmap, len, T_ULONGLONG, "map length"),
154*4882a593Smuzhiyun member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"),
155*4882a593Smuzhiyun member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"),
156*4882a593Smuzhiyun { .name = NULL, },
157*4882a593Smuzhiyun };
158*4882a593Smuzhiyun
pyrf_mmap_event__repr(struct pyrf_event * pevent)159*4882a593Smuzhiyun static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun PyObject *ret;
162*4882a593Smuzhiyun char *s;
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", "
165*4882a593Smuzhiyun "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", "
166*4882a593Smuzhiyun "filename: %s }",
167*4882a593Smuzhiyun pevent->event.mmap.pid, pevent->event.mmap.tid,
168*4882a593Smuzhiyun pevent->event.mmap.start, pevent->event.mmap.len,
169*4882a593Smuzhiyun pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
170*4882a593Smuzhiyun ret = PyErr_NoMemory();
171*4882a593Smuzhiyun } else {
172*4882a593Smuzhiyun ret = _PyUnicode_FromString(s);
173*4882a593Smuzhiyun free(s);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun return ret;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun static PyTypeObject pyrf_mmap_event__type = {
179*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
180*4882a593Smuzhiyun .tp_name = "perf.mmap_event",
181*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
182*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
183*4882a593Smuzhiyun .tp_doc = pyrf_mmap_event__doc,
184*4882a593Smuzhiyun .tp_members = pyrf_mmap_event__members,
185*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_mmap_event__repr,
186*4882a593Smuzhiyun };
187*4882a593Smuzhiyun
188*4882a593Smuzhiyun static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun static PyMemberDef pyrf_task_event__members[] = {
191*4882a593Smuzhiyun sample_members
192*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
193*4882a593Smuzhiyun member_def(perf_record_fork, pid, T_UINT, "event pid"),
194*4882a593Smuzhiyun member_def(perf_record_fork, ppid, T_UINT, "event ppid"),
195*4882a593Smuzhiyun member_def(perf_record_fork, tid, T_UINT, "event tid"),
196*4882a593Smuzhiyun member_def(perf_record_fork, ptid, T_UINT, "event ptid"),
197*4882a593Smuzhiyun member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"),
198*4882a593Smuzhiyun { .name = NULL, },
199*4882a593Smuzhiyun };
200*4882a593Smuzhiyun
pyrf_task_event__repr(struct pyrf_event * pevent)201*4882a593Smuzhiyun static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
204*4882a593Smuzhiyun "ptid: %u, time: %" PRI_lu64 "}",
205*4882a593Smuzhiyun pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
206*4882a593Smuzhiyun pevent->event.fork.pid,
207*4882a593Smuzhiyun pevent->event.fork.ppid,
208*4882a593Smuzhiyun pevent->event.fork.tid,
209*4882a593Smuzhiyun pevent->event.fork.ptid,
210*4882a593Smuzhiyun pevent->event.fork.time);
211*4882a593Smuzhiyun }
212*4882a593Smuzhiyun
213*4882a593Smuzhiyun static PyTypeObject pyrf_task_event__type = {
214*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
215*4882a593Smuzhiyun .tp_name = "perf.task_event",
216*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
217*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
218*4882a593Smuzhiyun .tp_doc = pyrf_task_event__doc,
219*4882a593Smuzhiyun .tp_members = pyrf_task_event__members,
220*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_task_event__repr,
221*4882a593Smuzhiyun };
222*4882a593Smuzhiyun
223*4882a593Smuzhiyun static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
224*4882a593Smuzhiyun
225*4882a593Smuzhiyun static PyMemberDef pyrf_comm_event__members[] = {
226*4882a593Smuzhiyun sample_members
227*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
228*4882a593Smuzhiyun member_def(perf_record_comm, pid, T_UINT, "event pid"),
229*4882a593Smuzhiyun member_def(perf_record_comm, tid, T_UINT, "event tid"),
230*4882a593Smuzhiyun member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"),
231*4882a593Smuzhiyun { .name = NULL, },
232*4882a593Smuzhiyun };
233*4882a593Smuzhiyun
pyrf_comm_event__repr(struct pyrf_event * pevent)234*4882a593Smuzhiyun static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
237*4882a593Smuzhiyun pevent->event.comm.pid,
238*4882a593Smuzhiyun pevent->event.comm.tid,
239*4882a593Smuzhiyun pevent->event.comm.comm);
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun static PyTypeObject pyrf_comm_event__type = {
243*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
244*4882a593Smuzhiyun .tp_name = "perf.comm_event",
245*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
246*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
247*4882a593Smuzhiyun .tp_doc = pyrf_comm_event__doc,
248*4882a593Smuzhiyun .tp_members = pyrf_comm_event__members,
249*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_comm_event__repr,
250*4882a593Smuzhiyun };
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun static PyMemberDef pyrf_throttle_event__members[] = {
255*4882a593Smuzhiyun sample_members
256*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
257*4882a593Smuzhiyun member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"),
258*4882a593Smuzhiyun member_def(perf_record_throttle, id, T_ULONGLONG, "event id"),
259*4882a593Smuzhiyun member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"),
260*4882a593Smuzhiyun { .name = NULL, },
261*4882a593Smuzhiyun };
262*4882a593Smuzhiyun
pyrf_throttle_event__repr(struct pyrf_event * pevent)263*4882a593Smuzhiyun static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
264*4882a593Smuzhiyun {
265*4882a593Smuzhiyun struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1);
266*4882a593Smuzhiyun
267*4882a593Smuzhiyun return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64
268*4882a593Smuzhiyun ", stream_id: %" PRI_lu64 " }",
269*4882a593Smuzhiyun pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
270*4882a593Smuzhiyun te->time, te->id, te->stream_id);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun static PyTypeObject pyrf_throttle_event__type = {
274*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
275*4882a593Smuzhiyun .tp_name = "perf.throttle_event",
276*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
277*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
278*4882a593Smuzhiyun .tp_doc = pyrf_throttle_event__doc,
279*4882a593Smuzhiyun .tp_members = pyrf_throttle_event__members,
280*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_throttle_event__repr,
281*4882a593Smuzhiyun };
282*4882a593Smuzhiyun
283*4882a593Smuzhiyun static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun static PyMemberDef pyrf_lost_event__members[] = {
286*4882a593Smuzhiyun sample_members
287*4882a593Smuzhiyun member_def(perf_record_lost, id, T_ULONGLONG, "event id"),
288*4882a593Smuzhiyun member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"),
289*4882a593Smuzhiyun { .name = NULL, },
290*4882a593Smuzhiyun };
291*4882a593Smuzhiyun
pyrf_lost_event__repr(struct pyrf_event * pevent)292*4882a593Smuzhiyun static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
293*4882a593Smuzhiyun {
294*4882a593Smuzhiyun PyObject *ret;
295*4882a593Smuzhiyun char *s;
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", "
298*4882a593Smuzhiyun "lost: %#" PRI_lx64 " }",
299*4882a593Smuzhiyun pevent->event.lost.id, pevent->event.lost.lost) < 0) {
300*4882a593Smuzhiyun ret = PyErr_NoMemory();
301*4882a593Smuzhiyun } else {
302*4882a593Smuzhiyun ret = _PyUnicode_FromString(s);
303*4882a593Smuzhiyun free(s);
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun return ret;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun static PyTypeObject pyrf_lost_event__type = {
309*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
310*4882a593Smuzhiyun .tp_name = "perf.lost_event",
311*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
312*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
313*4882a593Smuzhiyun .tp_doc = pyrf_lost_event__doc,
314*4882a593Smuzhiyun .tp_members = pyrf_lost_event__members,
315*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_lost_event__repr,
316*4882a593Smuzhiyun };
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun static PyMemberDef pyrf_read_event__members[] = {
321*4882a593Smuzhiyun sample_members
322*4882a593Smuzhiyun member_def(perf_record_read, pid, T_UINT, "event pid"),
323*4882a593Smuzhiyun member_def(perf_record_read, tid, T_UINT, "event tid"),
324*4882a593Smuzhiyun { .name = NULL, },
325*4882a593Smuzhiyun };
326*4882a593Smuzhiyun
pyrf_read_event__repr(struct pyrf_event * pevent)327*4882a593Smuzhiyun static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
330*4882a593Smuzhiyun pevent->event.read.pid,
331*4882a593Smuzhiyun pevent->event.read.tid);
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun * FIXME: return the array of read values,
334*4882a593Smuzhiyun * making this method useful ;-)
335*4882a593Smuzhiyun */
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun static PyTypeObject pyrf_read_event__type = {
339*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
340*4882a593Smuzhiyun .tp_name = "perf.read_event",
341*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
342*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
343*4882a593Smuzhiyun .tp_doc = pyrf_read_event__doc,
344*4882a593Smuzhiyun .tp_members = pyrf_read_event__members,
345*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_read_event__repr,
346*4882a593Smuzhiyun };
347*4882a593Smuzhiyun
348*4882a593Smuzhiyun static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun static PyMemberDef pyrf_sample_event__members[] = {
351*4882a593Smuzhiyun sample_members
352*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
353*4882a593Smuzhiyun { .name = NULL, },
354*4882a593Smuzhiyun };
355*4882a593Smuzhiyun
pyrf_sample_event__repr(struct pyrf_event * pevent)356*4882a593Smuzhiyun static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun PyObject *ret;
359*4882a593Smuzhiyun char *s;
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun if (asprintf(&s, "{ type: sample }") < 0) {
362*4882a593Smuzhiyun ret = PyErr_NoMemory();
363*4882a593Smuzhiyun } else {
364*4882a593Smuzhiyun ret = _PyUnicode_FromString(s);
365*4882a593Smuzhiyun free(s);
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun return ret;
368*4882a593Smuzhiyun }
369*4882a593Smuzhiyun
is_tracepoint(struct pyrf_event * pevent)370*4882a593Smuzhiyun static bool is_tracepoint(struct pyrf_event *pevent)
371*4882a593Smuzhiyun {
372*4882a593Smuzhiyun return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun static PyObject*
tracepoint_field(struct pyrf_event * pe,struct tep_format_field * field)376*4882a593Smuzhiyun tracepoint_field(struct pyrf_event *pe, struct tep_format_field *field)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun struct tep_handle *pevent = field->event->tep;
379*4882a593Smuzhiyun void *data = pe->sample.raw_data;
380*4882a593Smuzhiyun PyObject *ret = NULL;
381*4882a593Smuzhiyun unsigned long long val;
382*4882a593Smuzhiyun unsigned int offset, len;
383*4882a593Smuzhiyun
384*4882a593Smuzhiyun if (field->flags & TEP_FIELD_IS_ARRAY) {
385*4882a593Smuzhiyun offset = field->offset;
386*4882a593Smuzhiyun len = field->size;
387*4882a593Smuzhiyun if (field->flags & TEP_FIELD_IS_DYNAMIC) {
388*4882a593Smuzhiyun val = tep_read_number(pevent, data + offset, len);
389*4882a593Smuzhiyun offset = val;
390*4882a593Smuzhiyun len = offset >> 16;
391*4882a593Smuzhiyun offset &= 0xffff;
392*4882a593Smuzhiyun }
393*4882a593Smuzhiyun if (field->flags & TEP_FIELD_IS_STRING &&
394*4882a593Smuzhiyun is_printable_array(data + offset, len)) {
395*4882a593Smuzhiyun ret = _PyUnicode_FromString((char *)data + offset);
396*4882a593Smuzhiyun } else {
397*4882a593Smuzhiyun ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
398*4882a593Smuzhiyun field->flags &= ~TEP_FIELD_IS_STRING;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun } else {
401*4882a593Smuzhiyun val = tep_read_number(pevent, data + field->offset,
402*4882a593Smuzhiyun field->size);
403*4882a593Smuzhiyun if (field->flags & TEP_FIELD_IS_POINTER)
404*4882a593Smuzhiyun ret = PyLong_FromUnsignedLong((unsigned long) val);
405*4882a593Smuzhiyun else if (field->flags & TEP_FIELD_IS_SIGNED)
406*4882a593Smuzhiyun ret = PyLong_FromLong((long) val);
407*4882a593Smuzhiyun else
408*4882a593Smuzhiyun ret = PyLong_FromUnsignedLong((unsigned long) val);
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun
411*4882a593Smuzhiyun return ret;
412*4882a593Smuzhiyun }
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun static PyObject*
get_tracepoint_field(struct pyrf_event * pevent,PyObject * attr_name)415*4882a593Smuzhiyun get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun const char *str = _PyUnicode_AsString(PyObject_Str(attr_name));
418*4882a593Smuzhiyun struct evsel *evsel = pevent->evsel;
419*4882a593Smuzhiyun struct tep_format_field *field;
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (!evsel->tp_format) {
422*4882a593Smuzhiyun struct tep_event *tp_format;
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun tp_format = trace_event__tp_format_id(evsel->core.attr.config);
425*4882a593Smuzhiyun if (!tp_format)
426*4882a593Smuzhiyun return NULL;
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun evsel->tp_format = tp_format;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun field = tep_find_any_field(evsel->tp_format, str);
432*4882a593Smuzhiyun if (!field)
433*4882a593Smuzhiyun return NULL;
434*4882a593Smuzhiyun
435*4882a593Smuzhiyun return tracepoint_field(pevent, field);
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun static PyObject*
pyrf_sample_event__getattro(struct pyrf_event * pevent,PyObject * attr_name)439*4882a593Smuzhiyun pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
440*4882a593Smuzhiyun {
441*4882a593Smuzhiyun PyObject *obj = NULL;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun if (is_tracepoint(pevent))
444*4882a593Smuzhiyun obj = get_tracepoint_field(pevent, attr_name);
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun static PyTypeObject pyrf_sample_event__type = {
450*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
451*4882a593Smuzhiyun .tp_name = "perf.sample_event",
452*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
453*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
454*4882a593Smuzhiyun .tp_doc = pyrf_sample_event__doc,
455*4882a593Smuzhiyun .tp_members = pyrf_sample_event__members,
456*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_sample_event__repr,
457*4882a593Smuzhiyun .tp_getattro = (getattrofunc) pyrf_sample_event__getattro,
458*4882a593Smuzhiyun };
459*4882a593Smuzhiyun
460*4882a593Smuzhiyun static char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun static PyMemberDef pyrf_context_switch_event__members[] = {
463*4882a593Smuzhiyun sample_members
464*4882a593Smuzhiyun member_def(perf_event_header, type, T_UINT, "event type"),
465*4882a593Smuzhiyun member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"),
466*4882a593Smuzhiyun member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"),
467*4882a593Smuzhiyun { .name = NULL, },
468*4882a593Smuzhiyun };
469*4882a593Smuzhiyun
pyrf_context_switch_event__repr(struct pyrf_event * pevent)470*4882a593Smuzhiyun static PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
471*4882a593Smuzhiyun {
472*4882a593Smuzhiyun PyObject *ret;
473*4882a593Smuzhiyun char *s;
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
476*4882a593Smuzhiyun pevent->event.context_switch.next_prev_pid,
477*4882a593Smuzhiyun pevent->event.context_switch.next_prev_tid,
478*4882a593Smuzhiyun !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
479*4882a593Smuzhiyun ret = PyErr_NoMemory();
480*4882a593Smuzhiyun } else {
481*4882a593Smuzhiyun ret = _PyUnicode_FromString(s);
482*4882a593Smuzhiyun free(s);
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun return ret;
485*4882a593Smuzhiyun }
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun static PyTypeObject pyrf_context_switch_event__type = {
488*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
489*4882a593Smuzhiyun .tp_name = "perf.context_switch_event",
490*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_event),
491*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
492*4882a593Smuzhiyun .tp_doc = pyrf_context_switch_event__doc,
493*4882a593Smuzhiyun .tp_members = pyrf_context_switch_event__members,
494*4882a593Smuzhiyun .tp_repr = (reprfunc)pyrf_context_switch_event__repr,
495*4882a593Smuzhiyun };
496*4882a593Smuzhiyun
pyrf_event__setup_types(void)497*4882a593Smuzhiyun static int pyrf_event__setup_types(void)
498*4882a593Smuzhiyun {
499*4882a593Smuzhiyun int err;
500*4882a593Smuzhiyun pyrf_mmap_event__type.tp_new =
501*4882a593Smuzhiyun pyrf_task_event__type.tp_new =
502*4882a593Smuzhiyun pyrf_comm_event__type.tp_new =
503*4882a593Smuzhiyun pyrf_lost_event__type.tp_new =
504*4882a593Smuzhiyun pyrf_read_event__type.tp_new =
505*4882a593Smuzhiyun pyrf_sample_event__type.tp_new =
506*4882a593Smuzhiyun pyrf_context_switch_event__type.tp_new =
507*4882a593Smuzhiyun pyrf_throttle_event__type.tp_new = PyType_GenericNew;
508*4882a593Smuzhiyun err = PyType_Ready(&pyrf_mmap_event__type);
509*4882a593Smuzhiyun if (err < 0)
510*4882a593Smuzhiyun goto out;
511*4882a593Smuzhiyun err = PyType_Ready(&pyrf_lost_event__type);
512*4882a593Smuzhiyun if (err < 0)
513*4882a593Smuzhiyun goto out;
514*4882a593Smuzhiyun err = PyType_Ready(&pyrf_task_event__type);
515*4882a593Smuzhiyun if (err < 0)
516*4882a593Smuzhiyun goto out;
517*4882a593Smuzhiyun err = PyType_Ready(&pyrf_comm_event__type);
518*4882a593Smuzhiyun if (err < 0)
519*4882a593Smuzhiyun goto out;
520*4882a593Smuzhiyun err = PyType_Ready(&pyrf_throttle_event__type);
521*4882a593Smuzhiyun if (err < 0)
522*4882a593Smuzhiyun goto out;
523*4882a593Smuzhiyun err = PyType_Ready(&pyrf_read_event__type);
524*4882a593Smuzhiyun if (err < 0)
525*4882a593Smuzhiyun goto out;
526*4882a593Smuzhiyun err = PyType_Ready(&pyrf_sample_event__type);
527*4882a593Smuzhiyun if (err < 0)
528*4882a593Smuzhiyun goto out;
529*4882a593Smuzhiyun err = PyType_Ready(&pyrf_context_switch_event__type);
530*4882a593Smuzhiyun if (err < 0)
531*4882a593Smuzhiyun goto out;
532*4882a593Smuzhiyun out:
533*4882a593Smuzhiyun return err;
534*4882a593Smuzhiyun }
535*4882a593Smuzhiyun
536*4882a593Smuzhiyun static PyTypeObject *pyrf_event__type[] = {
537*4882a593Smuzhiyun [PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
538*4882a593Smuzhiyun [PERF_RECORD_LOST] = &pyrf_lost_event__type,
539*4882a593Smuzhiyun [PERF_RECORD_COMM] = &pyrf_comm_event__type,
540*4882a593Smuzhiyun [PERF_RECORD_EXIT] = &pyrf_task_event__type,
541*4882a593Smuzhiyun [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
542*4882a593Smuzhiyun [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
543*4882a593Smuzhiyun [PERF_RECORD_FORK] = &pyrf_task_event__type,
544*4882a593Smuzhiyun [PERF_RECORD_READ] = &pyrf_read_event__type,
545*4882a593Smuzhiyun [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
546*4882a593Smuzhiyun [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type,
547*4882a593Smuzhiyun [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type,
548*4882a593Smuzhiyun };
549*4882a593Smuzhiyun
pyrf_event__new(union perf_event * event)550*4882a593Smuzhiyun static PyObject *pyrf_event__new(union perf_event *event)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun struct pyrf_event *pevent;
553*4882a593Smuzhiyun PyTypeObject *ptype;
554*4882a593Smuzhiyun
555*4882a593Smuzhiyun if ((event->header.type < PERF_RECORD_MMAP ||
556*4882a593Smuzhiyun event->header.type > PERF_RECORD_SAMPLE) &&
557*4882a593Smuzhiyun !(event->header.type == PERF_RECORD_SWITCH ||
558*4882a593Smuzhiyun event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
559*4882a593Smuzhiyun return NULL;
560*4882a593Smuzhiyun
561*4882a593Smuzhiyun ptype = pyrf_event__type[event->header.type];
562*4882a593Smuzhiyun pevent = PyObject_New(struct pyrf_event, ptype);
563*4882a593Smuzhiyun if (pevent != NULL)
564*4882a593Smuzhiyun memcpy(&pevent->event, event, event->header.size);
565*4882a593Smuzhiyun return (PyObject *)pevent;
566*4882a593Smuzhiyun }
567*4882a593Smuzhiyun
568*4882a593Smuzhiyun struct pyrf_cpu_map {
569*4882a593Smuzhiyun PyObject_HEAD
570*4882a593Smuzhiyun
571*4882a593Smuzhiyun struct perf_cpu_map *cpus;
572*4882a593Smuzhiyun };
573*4882a593Smuzhiyun
pyrf_cpu_map__init(struct pyrf_cpu_map * pcpus,PyObject * args,PyObject * kwargs)574*4882a593Smuzhiyun static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
575*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun static char *kwlist[] = { "cpustr", NULL };
578*4882a593Smuzhiyun char *cpustr = NULL;
579*4882a593Smuzhiyun
580*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
581*4882a593Smuzhiyun kwlist, &cpustr))
582*4882a593Smuzhiyun return -1;
583*4882a593Smuzhiyun
584*4882a593Smuzhiyun pcpus->cpus = perf_cpu_map__new(cpustr);
585*4882a593Smuzhiyun if (pcpus->cpus == NULL)
586*4882a593Smuzhiyun return -1;
587*4882a593Smuzhiyun return 0;
588*4882a593Smuzhiyun }
589*4882a593Smuzhiyun
pyrf_cpu_map__delete(struct pyrf_cpu_map * pcpus)590*4882a593Smuzhiyun static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
591*4882a593Smuzhiyun {
592*4882a593Smuzhiyun perf_cpu_map__put(pcpus->cpus);
593*4882a593Smuzhiyun Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
594*4882a593Smuzhiyun }
595*4882a593Smuzhiyun
pyrf_cpu_map__length(PyObject * obj)596*4882a593Smuzhiyun static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
597*4882a593Smuzhiyun {
598*4882a593Smuzhiyun struct pyrf_cpu_map *pcpus = (void *)obj;
599*4882a593Smuzhiyun
600*4882a593Smuzhiyun return pcpus->cpus->nr;
601*4882a593Smuzhiyun }
602*4882a593Smuzhiyun
pyrf_cpu_map__item(PyObject * obj,Py_ssize_t i)603*4882a593Smuzhiyun static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
604*4882a593Smuzhiyun {
605*4882a593Smuzhiyun struct pyrf_cpu_map *pcpus = (void *)obj;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun if (i >= pcpus->cpus->nr)
608*4882a593Smuzhiyun return NULL;
609*4882a593Smuzhiyun
610*4882a593Smuzhiyun return Py_BuildValue("i", pcpus->cpus->map[i]);
611*4882a593Smuzhiyun }
612*4882a593Smuzhiyun
613*4882a593Smuzhiyun static PySequenceMethods pyrf_cpu_map__sequence_methods = {
614*4882a593Smuzhiyun .sq_length = pyrf_cpu_map__length,
615*4882a593Smuzhiyun .sq_item = pyrf_cpu_map__item,
616*4882a593Smuzhiyun };
617*4882a593Smuzhiyun
618*4882a593Smuzhiyun static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
619*4882a593Smuzhiyun
620*4882a593Smuzhiyun static PyTypeObject pyrf_cpu_map__type = {
621*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
622*4882a593Smuzhiyun .tp_name = "perf.cpu_map",
623*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_cpu_map),
624*4882a593Smuzhiyun .tp_dealloc = (destructor)pyrf_cpu_map__delete,
625*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
626*4882a593Smuzhiyun .tp_doc = pyrf_cpu_map__doc,
627*4882a593Smuzhiyun .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
628*4882a593Smuzhiyun .tp_init = (initproc)pyrf_cpu_map__init,
629*4882a593Smuzhiyun };
630*4882a593Smuzhiyun
pyrf_cpu_map__setup_types(void)631*4882a593Smuzhiyun static int pyrf_cpu_map__setup_types(void)
632*4882a593Smuzhiyun {
633*4882a593Smuzhiyun pyrf_cpu_map__type.tp_new = PyType_GenericNew;
634*4882a593Smuzhiyun return PyType_Ready(&pyrf_cpu_map__type);
635*4882a593Smuzhiyun }
636*4882a593Smuzhiyun
637*4882a593Smuzhiyun struct pyrf_thread_map {
638*4882a593Smuzhiyun PyObject_HEAD
639*4882a593Smuzhiyun
640*4882a593Smuzhiyun struct perf_thread_map *threads;
641*4882a593Smuzhiyun };
642*4882a593Smuzhiyun
pyrf_thread_map__init(struct pyrf_thread_map * pthreads,PyObject * args,PyObject * kwargs)643*4882a593Smuzhiyun static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
644*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
645*4882a593Smuzhiyun {
646*4882a593Smuzhiyun static char *kwlist[] = { "pid", "tid", "uid", NULL };
647*4882a593Smuzhiyun int pid = -1, tid = -1, uid = UINT_MAX;
648*4882a593Smuzhiyun
649*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
650*4882a593Smuzhiyun kwlist, &pid, &tid, &uid))
651*4882a593Smuzhiyun return -1;
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun pthreads->threads = thread_map__new(pid, tid, uid);
654*4882a593Smuzhiyun if (pthreads->threads == NULL)
655*4882a593Smuzhiyun return -1;
656*4882a593Smuzhiyun return 0;
657*4882a593Smuzhiyun }
658*4882a593Smuzhiyun
pyrf_thread_map__delete(struct pyrf_thread_map * pthreads)659*4882a593Smuzhiyun static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
660*4882a593Smuzhiyun {
661*4882a593Smuzhiyun perf_thread_map__put(pthreads->threads);
662*4882a593Smuzhiyun Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
663*4882a593Smuzhiyun }
664*4882a593Smuzhiyun
pyrf_thread_map__length(PyObject * obj)665*4882a593Smuzhiyun static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun struct pyrf_thread_map *pthreads = (void *)obj;
668*4882a593Smuzhiyun
669*4882a593Smuzhiyun return pthreads->threads->nr;
670*4882a593Smuzhiyun }
671*4882a593Smuzhiyun
pyrf_thread_map__item(PyObject * obj,Py_ssize_t i)672*4882a593Smuzhiyun static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun struct pyrf_thread_map *pthreads = (void *)obj;
675*4882a593Smuzhiyun
676*4882a593Smuzhiyun if (i >= pthreads->threads->nr)
677*4882a593Smuzhiyun return NULL;
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun return Py_BuildValue("i", pthreads->threads->map[i]);
680*4882a593Smuzhiyun }
681*4882a593Smuzhiyun
682*4882a593Smuzhiyun static PySequenceMethods pyrf_thread_map__sequence_methods = {
683*4882a593Smuzhiyun .sq_length = pyrf_thread_map__length,
684*4882a593Smuzhiyun .sq_item = pyrf_thread_map__item,
685*4882a593Smuzhiyun };
686*4882a593Smuzhiyun
687*4882a593Smuzhiyun static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun static PyTypeObject pyrf_thread_map__type = {
690*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
691*4882a593Smuzhiyun .tp_name = "perf.thread_map",
692*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_thread_map),
693*4882a593Smuzhiyun .tp_dealloc = (destructor)pyrf_thread_map__delete,
694*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
695*4882a593Smuzhiyun .tp_doc = pyrf_thread_map__doc,
696*4882a593Smuzhiyun .tp_as_sequence = &pyrf_thread_map__sequence_methods,
697*4882a593Smuzhiyun .tp_init = (initproc)pyrf_thread_map__init,
698*4882a593Smuzhiyun };
699*4882a593Smuzhiyun
pyrf_thread_map__setup_types(void)700*4882a593Smuzhiyun static int pyrf_thread_map__setup_types(void)
701*4882a593Smuzhiyun {
702*4882a593Smuzhiyun pyrf_thread_map__type.tp_new = PyType_GenericNew;
703*4882a593Smuzhiyun return PyType_Ready(&pyrf_thread_map__type);
704*4882a593Smuzhiyun }
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun struct pyrf_evsel {
707*4882a593Smuzhiyun PyObject_HEAD
708*4882a593Smuzhiyun
709*4882a593Smuzhiyun struct evsel evsel;
710*4882a593Smuzhiyun };
711*4882a593Smuzhiyun
pyrf_evsel__init(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)712*4882a593Smuzhiyun static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
713*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
714*4882a593Smuzhiyun {
715*4882a593Smuzhiyun struct perf_event_attr attr = {
716*4882a593Smuzhiyun .type = PERF_TYPE_HARDWARE,
717*4882a593Smuzhiyun .config = PERF_COUNT_HW_CPU_CYCLES,
718*4882a593Smuzhiyun .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
719*4882a593Smuzhiyun };
720*4882a593Smuzhiyun static char *kwlist[] = {
721*4882a593Smuzhiyun "type",
722*4882a593Smuzhiyun "config",
723*4882a593Smuzhiyun "sample_freq",
724*4882a593Smuzhiyun "sample_period",
725*4882a593Smuzhiyun "sample_type",
726*4882a593Smuzhiyun "read_format",
727*4882a593Smuzhiyun "disabled",
728*4882a593Smuzhiyun "inherit",
729*4882a593Smuzhiyun "pinned",
730*4882a593Smuzhiyun "exclusive",
731*4882a593Smuzhiyun "exclude_user",
732*4882a593Smuzhiyun "exclude_kernel",
733*4882a593Smuzhiyun "exclude_hv",
734*4882a593Smuzhiyun "exclude_idle",
735*4882a593Smuzhiyun "mmap",
736*4882a593Smuzhiyun "context_switch",
737*4882a593Smuzhiyun "comm",
738*4882a593Smuzhiyun "freq",
739*4882a593Smuzhiyun "inherit_stat",
740*4882a593Smuzhiyun "enable_on_exec",
741*4882a593Smuzhiyun "task",
742*4882a593Smuzhiyun "watermark",
743*4882a593Smuzhiyun "precise_ip",
744*4882a593Smuzhiyun "mmap_data",
745*4882a593Smuzhiyun "sample_id_all",
746*4882a593Smuzhiyun "wakeup_events",
747*4882a593Smuzhiyun "bp_type",
748*4882a593Smuzhiyun "bp_addr",
749*4882a593Smuzhiyun "bp_len",
750*4882a593Smuzhiyun NULL
751*4882a593Smuzhiyun };
752*4882a593Smuzhiyun u64 sample_period = 0;
753*4882a593Smuzhiyun u32 disabled = 0,
754*4882a593Smuzhiyun inherit = 0,
755*4882a593Smuzhiyun pinned = 0,
756*4882a593Smuzhiyun exclusive = 0,
757*4882a593Smuzhiyun exclude_user = 0,
758*4882a593Smuzhiyun exclude_kernel = 0,
759*4882a593Smuzhiyun exclude_hv = 0,
760*4882a593Smuzhiyun exclude_idle = 0,
761*4882a593Smuzhiyun mmap = 0,
762*4882a593Smuzhiyun context_switch = 0,
763*4882a593Smuzhiyun comm = 0,
764*4882a593Smuzhiyun freq = 1,
765*4882a593Smuzhiyun inherit_stat = 0,
766*4882a593Smuzhiyun enable_on_exec = 0,
767*4882a593Smuzhiyun task = 0,
768*4882a593Smuzhiyun watermark = 0,
769*4882a593Smuzhiyun precise_ip = 0,
770*4882a593Smuzhiyun mmap_data = 0,
771*4882a593Smuzhiyun sample_id_all = 1;
772*4882a593Smuzhiyun int idx = 0;
773*4882a593Smuzhiyun
774*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs,
775*4882a593Smuzhiyun "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
776*4882a593Smuzhiyun &attr.type, &attr.config, &attr.sample_freq,
777*4882a593Smuzhiyun &sample_period, &attr.sample_type,
778*4882a593Smuzhiyun &attr.read_format, &disabled, &inherit,
779*4882a593Smuzhiyun &pinned, &exclusive, &exclude_user,
780*4882a593Smuzhiyun &exclude_kernel, &exclude_hv, &exclude_idle,
781*4882a593Smuzhiyun &mmap, &context_switch, &comm, &freq, &inherit_stat,
782*4882a593Smuzhiyun &enable_on_exec, &task, &watermark,
783*4882a593Smuzhiyun &precise_ip, &mmap_data, &sample_id_all,
784*4882a593Smuzhiyun &attr.wakeup_events, &attr.bp_type,
785*4882a593Smuzhiyun &attr.bp_addr, &attr.bp_len, &idx))
786*4882a593Smuzhiyun return -1;
787*4882a593Smuzhiyun
788*4882a593Smuzhiyun /* union... */
789*4882a593Smuzhiyun if (sample_period != 0) {
790*4882a593Smuzhiyun if (attr.sample_freq != 0)
791*4882a593Smuzhiyun return -1; /* FIXME: throw right exception */
792*4882a593Smuzhiyun attr.sample_period = sample_period;
793*4882a593Smuzhiyun }
794*4882a593Smuzhiyun
795*4882a593Smuzhiyun /* Bitfields */
796*4882a593Smuzhiyun attr.disabled = disabled;
797*4882a593Smuzhiyun attr.inherit = inherit;
798*4882a593Smuzhiyun attr.pinned = pinned;
799*4882a593Smuzhiyun attr.exclusive = exclusive;
800*4882a593Smuzhiyun attr.exclude_user = exclude_user;
801*4882a593Smuzhiyun attr.exclude_kernel = exclude_kernel;
802*4882a593Smuzhiyun attr.exclude_hv = exclude_hv;
803*4882a593Smuzhiyun attr.exclude_idle = exclude_idle;
804*4882a593Smuzhiyun attr.mmap = mmap;
805*4882a593Smuzhiyun attr.context_switch = context_switch;
806*4882a593Smuzhiyun attr.comm = comm;
807*4882a593Smuzhiyun attr.freq = freq;
808*4882a593Smuzhiyun attr.inherit_stat = inherit_stat;
809*4882a593Smuzhiyun attr.enable_on_exec = enable_on_exec;
810*4882a593Smuzhiyun attr.task = task;
811*4882a593Smuzhiyun attr.watermark = watermark;
812*4882a593Smuzhiyun attr.precise_ip = precise_ip;
813*4882a593Smuzhiyun attr.mmap_data = mmap_data;
814*4882a593Smuzhiyun attr.sample_id_all = sample_id_all;
815*4882a593Smuzhiyun attr.size = sizeof(attr);
816*4882a593Smuzhiyun
817*4882a593Smuzhiyun evsel__init(&pevsel->evsel, &attr, idx);
818*4882a593Smuzhiyun return 0;
819*4882a593Smuzhiyun }
820*4882a593Smuzhiyun
pyrf_evsel__delete(struct pyrf_evsel * pevsel)821*4882a593Smuzhiyun static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
822*4882a593Smuzhiyun {
823*4882a593Smuzhiyun evsel__exit(&pevsel->evsel);
824*4882a593Smuzhiyun Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
825*4882a593Smuzhiyun }
826*4882a593Smuzhiyun
pyrf_evsel__open(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)827*4882a593Smuzhiyun static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
828*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun struct evsel *evsel = &pevsel->evsel;
831*4882a593Smuzhiyun struct perf_cpu_map *cpus = NULL;
832*4882a593Smuzhiyun struct perf_thread_map *threads = NULL;
833*4882a593Smuzhiyun PyObject *pcpus = NULL, *pthreads = NULL;
834*4882a593Smuzhiyun int group = 0, inherit = 0;
835*4882a593Smuzhiyun static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
836*4882a593Smuzhiyun
837*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
838*4882a593Smuzhiyun &pcpus, &pthreads, &group, &inherit))
839*4882a593Smuzhiyun return NULL;
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun if (pthreads != NULL)
842*4882a593Smuzhiyun threads = ((struct pyrf_thread_map *)pthreads)->threads;
843*4882a593Smuzhiyun
844*4882a593Smuzhiyun if (pcpus != NULL)
845*4882a593Smuzhiyun cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
846*4882a593Smuzhiyun
847*4882a593Smuzhiyun evsel->core.attr.inherit = inherit;
848*4882a593Smuzhiyun /*
849*4882a593Smuzhiyun * This will group just the fds for this single evsel, to group
850*4882a593Smuzhiyun * multiple events, use evlist.open().
851*4882a593Smuzhiyun */
852*4882a593Smuzhiyun if (evsel__open(evsel, cpus, threads) < 0) {
853*4882a593Smuzhiyun PyErr_SetFromErrno(PyExc_OSError);
854*4882a593Smuzhiyun return NULL;
855*4882a593Smuzhiyun }
856*4882a593Smuzhiyun
857*4882a593Smuzhiyun Py_INCREF(Py_None);
858*4882a593Smuzhiyun return Py_None;
859*4882a593Smuzhiyun }
860*4882a593Smuzhiyun
861*4882a593Smuzhiyun static PyMethodDef pyrf_evsel__methods[] = {
862*4882a593Smuzhiyun {
863*4882a593Smuzhiyun .ml_name = "open",
864*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evsel__open,
865*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
866*4882a593Smuzhiyun .ml_doc = PyDoc_STR("open the event selector file descriptor table.")
867*4882a593Smuzhiyun },
868*4882a593Smuzhiyun { .ml_name = NULL, }
869*4882a593Smuzhiyun };
870*4882a593Smuzhiyun
871*4882a593Smuzhiyun static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
872*4882a593Smuzhiyun
873*4882a593Smuzhiyun static PyTypeObject pyrf_evsel__type = {
874*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
875*4882a593Smuzhiyun .tp_name = "perf.evsel",
876*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_evsel),
877*4882a593Smuzhiyun .tp_dealloc = (destructor)pyrf_evsel__delete,
878*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
879*4882a593Smuzhiyun .tp_doc = pyrf_evsel__doc,
880*4882a593Smuzhiyun .tp_methods = pyrf_evsel__methods,
881*4882a593Smuzhiyun .tp_init = (initproc)pyrf_evsel__init,
882*4882a593Smuzhiyun };
883*4882a593Smuzhiyun
pyrf_evsel__setup_types(void)884*4882a593Smuzhiyun static int pyrf_evsel__setup_types(void)
885*4882a593Smuzhiyun {
886*4882a593Smuzhiyun pyrf_evsel__type.tp_new = PyType_GenericNew;
887*4882a593Smuzhiyun return PyType_Ready(&pyrf_evsel__type);
888*4882a593Smuzhiyun }
889*4882a593Smuzhiyun
890*4882a593Smuzhiyun struct pyrf_evlist {
891*4882a593Smuzhiyun PyObject_HEAD
892*4882a593Smuzhiyun
893*4882a593Smuzhiyun struct evlist evlist;
894*4882a593Smuzhiyun };
895*4882a593Smuzhiyun
pyrf_evlist__init(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs __maybe_unused)896*4882a593Smuzhiyun static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
897*4882a593Smuzhiyun PyObject *args, PyObject *kwargs __maybe_unused)
898*4882a593Smuzhiyun {
899*4882a593Smuzhiyun PyObject *pcpus = NULL, *pthreads = NULL;
900*4882a593Smuzhiyun struct perf_cpu_map *cpus;
901*4882a593Smuzhiyun struct perf_thread_map *threads;
902*4882a593Smuzhiyun
903*4882a593Smuzhiyun if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
904*4882a593Smuzhiyun return -1;
905*4882a593Smuzhiyun
906*4882a593Smuzhiyun threads = ((struct pyrf_thread_map *)pthreads)->threads;
907*4882a593Smuzhiyun cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
908*4882a593Smuzhiyun evlist__init(&pevlist->evlist, cpus, threads);
909*4882a593Smuzhiyun return 0;
910*4882a593Smuzhiyun }
911*4882a593Smuzhiyun
pyrf_evlist__delete(struct pyrf_evlist * pevlist)912*4882a593Smuzhiyun static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
913*4882a593Smuzhiyun {
914*4882a593Smuzhiyun evlist__exit(&pevlist->evlist);
915*4882a593Smuzhiyun Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
916*4882a593Smuzhiyun }
917*4882a593Smuzhiyun
pyrf_evlist__mmap(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)918*4882a593Smuzhiyun static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
919*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
920*4882a593Smuzhiyun {
921*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
922*4882a593Smuzhiyun static char *kwlist[] = { "pages", "overwrite", NULL };
923*4882a593Smuzhiyun int pages = 128, overwrite = false;
924*4882a593Smuzhiyun
925*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
926*4882a593Smuzhiyun &pages, &overwrite))
927*4882a593Smuzhiyun return NULL;
928*4882a593Smuzhiyun
929*4882a593Smuzhiyun if (evlist__mmap(evlist, pages) < 0) {
930*4882a593Smuzhiyun PyErr_SetFromErrno(PyExc_OSError);
931*4882a593Smuzhiyun return NULL;
932*4882a593Smuzhiyun }
933*4882a593Smuzhiyun
934*4882a593Smuzhiyun Py_INCREF(Py_None);
935*4882a593Smuzhiyun return Py_None;
936*4882a593Smuzhiyun }
937*4882a593Smuzhiyun
pyrf_evlist__poll(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)938*4882a593Smuzhiyun static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
939*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
940*4882a593Smuzhiyun {
941*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
942*4882a593Smuzhiyun static char *kwlist[] = { "timeout", NULL };
943*4882a593Smuzhiyun int timeout = -1, n;
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
946*4882a593Smuzhiyun return NULL;
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun n = evlist__poll(evlist, timeout);
949*4882a593Smuzhiyun if (n < 0) {
950*4882a593Smuzhiyun PyErr_SetFromErrno(PyExc_OSError);
951*4882a593Smuzhiyun return NULL;
952*4882a593Smuzhiyun }
953*4882a593Smuzhiyun
954*4882a593Smuzhiyun return Py_BuildValue("i", n);
955*4882a593Smuzhiyun }
956*4882a593Smuzhiyun
pyrf_evlist__get_pollfd(struct pyrf_evlist * pevlist,PyObject * args __maybe_unused,PyObject * kwargs __maybe_unused)957*4882a593Smuzhiyun static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
958*4882a593Smuzhiyun PyObject *args __maybe_unused,
959*4882a593Smuzhiyun PyObject *kwargs __maybe_unused)
960*4882a593Smuzhiyun {
961*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
962*4882a593Smuzhiyun PyObject *list = PyList_New(0);
963*4882a593Smuzhiyun int i;
964*4882a593Smuzhiyun
965*4882a593Smuzhiyun for (i = 0; i < evlist->core.pollfd.nr; ++i) {
966*4882a593Smuzhiyun PyObject *file;
967*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
968*4882a593Smuzhiyun FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r");
969*4882a593Smuzhiyun
970*4882a593Smuzhiyun if (fp == NULL)
971*4882a593Smuzhiyun goto free_list;
972*4882a593Smuzhiyun
973*4882a593Smuzhiyun file = PyFile_FromFile(fp, "perf", "r", NULL);
974*4882a593Smuzhiyun #else
975*4882a593Smuzhiyun file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1,
976*4882a593Smuzhiyun NULL, NULL, NULL, 0);
977*4882a593Smuzhiyun #endif
978*4882a593Smuzhiyun if (file == NULL)
979*4882a593Smuzhiyun goto free_list;
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun if (PyList_Append(list, file) != 0) {
982*4882a593Smuzhiyun Py_DECREF(file);
983*4882a593Smuzhiyun goto free_list;
984*4882a593Smuzhiyun }
985*4882a593Smuzhiyun
986*4882a593Smuzhiyun Py_DECREF(file);
987*4882a593Smuzhiyun }
988*4882a593Smuzhiyun
989*4882a593Smuzhiyun return list;
990*4882a593Smuzhiyun free_list:
991*4882a593Smuzhiyun return PyErr_NoMemory();
992*4882a593Smuzhiyun }
993*4882a593Smuzhiyun
994*4882a593Smuzhiyun
pyrf_evlist__add(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs __maybe_unused)995*4882a593Smuzhiyun static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
996*4882a593Smuzhiyun PyObject *args,
997*4882a593Smuzhiyun PyObject *kwargs __maybe_unused)
998*4882a593Smuzhiyun {
999*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
1000*4882a593Smuzhiyun PyObject *pevsel;
1001*4882a593Smuzhiyun struct evsel *evsel;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun if (!PyArg_ParseTuple(args, "O", &pevsel))
1004*4882a593Smuzhiyun return NULL;
1005*4882a593Smuzhiyun
1006*4882a593Smuzhiyun Py_INCREF(pevsel);
1007*4882a593Smuzhiyun evsel = &((struct pyrf_evsel *)pevsel)->evsel;
1008*4882a593Smuzhiyun evsel->idx = evlist->core.nr_entries;
1009*4882a593Smuzhiyun evlist__add(evlist, evsel);
1010*4882a593Smuzhiyun
1011*4882a593Smuzhiyun return Py_BuildValue("i", evlist->core.nr_entries);
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun
get_md(struct evlist * evlist,int cpu)1014*4882a593Smuzhiyun static struct mmap *get_md(struct evlist *evlist, int cpu)
1015*4882a593Smuzhiyun {
1016*4882a593Smuzhiyun int i;
1017*4882a593Smuzhiyun
1018*4882a593Smuzhiyun for (i = 0; i < evlist->core.nr_mmaps; i++) {
1019*4882a593Smuzhiyun struct mmap *md = &evlist->mmap[i];
1020*4882a593Smuzhiyun
1021*4882a593Smuzhiyun if (md->core.cpu == cpu)
1022*4882a593Smuzhiyun return md;
1023*4882a593Smuzhiyun }
1024*4882a593Smuzhiyun
1025*4882a593Smuzhiyun return NULL;
1026*4882a593Smuzhiyun }
1027*4882a593Smuzhiyun
pyrf_evlist__read_on_cpu(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)1028*4882a593Smuzhiyun static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
1029*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
1030*4882a593Smuzhiyun {
1031*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
1032*4882a593Smuzhiyun union perf_event *event;
1033*4882a593Smuzhiyun int sample_id_all = 1, cpu;
1034*4882a593Smuzhiyun static char *kwlist[] = { "cpu", "sample_id_all", NULL };
1035*4882a593Smuzhiyun struct mmap *md;
1036*4882a593Smuzhiyun int err;
1037*4882a593Smuzhiyun
1038*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
1039*4882a593Smuzhiyun &cpu, &sample_id_all))
1040*4882a593Smuzhiyun return NULL;
1041*4882a593Smuzhiyun
1042*4882a593Smuzhiyun md = get_md(evlist, cpu);
1043*4882a593Smuzhiyun if (!md)
1044*4882a593Smuzhiyun return NULL;
1045*4882a593Smuzhiyun
1046*4882a593Smuzhiyun if (perf_mmap__read_init(&md->core) < 0)
1047*4882a593Smuzhiyun goto end;
1048*4882a593Smuzhiyun
1049*4882a593Smuzhiyun event = perf_mmap__read_event(&md->core);
1050*4882a593Smuzhiyun if (event != NULL) {
1051*4882a593Smuzhiyun PyObject *pyevent = pyrf_event__new(event);
1052*4882a593Smuzhiyun struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
1053*4882a593Smuzhiyun struct evsel *evsel;
1054*4882a593Smuzhiyun
1055*4882a593Smuzhiyun if (pyevent == NULL)
1056*4882a593Smuzhiyun return PyErr_NoMemory();
1057*4882a593Smuzhiyun
1058*4882a593Smuzhiyun evsel = perf_evlist__event2evsel(evlist, event);
1059*4882a593Smuzhiyun if (!evsel) {
1060*4882a593Smuzhiyun Py_INCREF(Py_None);
1061*4882a593Smuzhiyun return Py_None;
1062*4882a593Smuzhiyun }
1063*4882a593Smuzhiyun
1064*4882a593Smuzhiyun pevent->evsel = evsel;
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun err = evsel__parse_sample(evsel, event, &pevent->sample);
1067*4882a593Smuzhiyun
1068*4882a593Smuzhiyun /* Consume the even only after we parsed it out. */
1069*4882a593Smuzhiyun perf_mmap__consume(&md->core);
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun if (err)
1072*4882a593Smuzhiyun return PyErr_Format(PyExc_OSError,
1073*4882a593Smuzhiyun "perf: can't parse sample, err=%d", err);
1074*4882a593Smuzhiyun return pyevent;
1075*4882a593Smuzhiyun }
1076*4882a593Smuzhiyun end:
1077*4882a593Smuzhiyun Py_INCREF(Py_None);
1078*4882a593Smuzhiyun return Py_None;
1079*4882a593Smuzhiyun }
1080*4882a593Smuzhiyun
pyrf_evlist__open(struct pyrf_evlist * pevlist,PyObject * args,PyObject * kwargs)1081*4882a593Smuzhiyun static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
1082*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
1083*4882a593Smuzhiyun {
1084*4882a593Smuzhiyun struct evlist *evlist = &pevlist->evlist;
1085*4882a593Smuzhiyun int group = 0;
1086*4882a593Smuzhiyun static char *kwlist[] = { "group", NULL };
1087*4882a593Smuzhiyun
1088*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
1089*4882a593Smuzhiyun return NULL;
1090*4882a593Smuzhiyun
1091*4882a593Smuzhiyun if (group)
1092*4882a593Smuzhiyun perf_evlist__set_leader(evlist);
1093*4882a593Smuzhiyun
1094*4882a593Smuzhiyun if (evlist__open(evlist) < 0) {
1095*4882a593Smuzhiyun PyErr_SetFromErrno(PyExc_OSError);
1096*4882a593Smuzhiyun return NULL;
1097*4882a593Smuzhiyun }
1098*4882a593Smuzhiyun
1099*4882a593Smuzhiyun Py_INCREF(Py_None);
1100*4882a593Smuzhiyun return Py_None;
1101*4882a593Smuzhiyun }
1102*4882a593Smuzhiyun
1103*4882a593Smuzhiyun static PyMethodDef pyrf_evlist__methods[] = {
1104*4882a593Smuzhiyun {
1105*4882a593Smuzhiyun .ml_name = "mmap",
1106*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__mmap,
1107*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1108*4882a593Smuzhiyun .ml_doc = PyDoc_STR("mmap the file descriptor table.")
1109*4882a593Smuzhiyun },
1110*4882a593Smuzhiyun {
1111*4882a593Smuzhiyun .ml_name = "open",
1112*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__open,
1113*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1114*4882a593Smuzhiyun .ml_doc = PyDoc_STR("open the file descriptors.")
1115*4882a593Smuzhiyun },
1116*4882a593Smuzhiyun {
1117*4882a593Smuzhiyun .ml_name = "poll",
1118*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__poll,
1119*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1120*4882a593Smuzhiyun .ml_doc = PyDoc_STR("poll the file descriptor table.")
1121*4882a593Smuzhiyun },
1122*4882a593Smuzhiyun {
1123*4882a593Smuzhiyun .ml_name = "get_pollfd",
1124*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
1125*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1126*4882a593Smuzhiyun .ml_doc = PyDoc_STR("get the poll file descriptor table.")
1127*4882a593Smuzhiyun },
1128*4882a593Smuzhiyun {
1129*4882a593Smuzhiyun .ml_name = "add",
1130*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__add,
1131*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1132*4882a593Smuzhiyun .ml_doc = PyDoc_STR("adds an event selector to the list.")
1133*4882a593Smuzhiyun },
1134*4882a593Smuzhiyun {
1135*4882a593Smuzhiyun .ml_name = "read_on_cpu",
1136*4882a593Smuzhiyun .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
1137*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1138*4882a593Smuzhiyun .ml_doc = PyDoc_STR("reads an event.")
1139*4882a593Smuzhiyun },
1140*4882a593Smuzhiyun { .ml_name = NULL, }
1141*4882a593Smuzhiyun };
1142*4882a593Smuzhiyun
pyrf_evlist__length(PyObject * obj)1143*4882a593Smuzhiyun static Py_ssize_t pyrf_evlist__length(PyObject *obj)
1144*4882a593Smuzhiyun {
1145*4882a593Smuzhiyun struct pyrf_evlist *pevlist = (void *)obj;
1146*4882a593Smuzhiyun
1147*4882a593Smuzhiyun return pevlist->evlist.core.nr_entries;
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun
pyrf_evlist__item(PyObject * obj,Py_ssize_t i)1150*4882a593Smuzhiyun static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
1151*4882a593Smuzhiyun {
1152*4882a593Smuzhiyun struct pyrf_evlist *pevlist = (void *)obj;
1153*4882a593Smuzhiyun struct evsel *pos;
1154*4882a593Smuzhiyun
1155*4882a593Smuzhiyun if (i >= pevlist->evlist.core.nr_entries)
1156*4882a593Smuzhiyun return NULL;
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun evlist__for_each_entry(&pevlist->evlist, pos) {
1159*4882a593Smuzhiyun if (i-- == 0)
1160*4882a593Smuzhiyun break;
1161*4882a593Smuzhiyun }
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
1164*4882a593Smuzhiyun }
1165*4882a593Smuzhiyun
1166*4882a593Smuzhiyun static PySequenceMethods pyrf_evlist__sequence_methods = {
1167*4882a593Smuzhiyun .sq_length = pyrf_evlist__length,
1168*4882a593Smuzhiyun .sq_item = pyrf_evlist__item,
1169*4882a593Smuzhiyun };
1170*4882a593Smuzhiyun
1171*4882a593Smuzhiyun static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
1172*4882a593Smuzhiyun
1173*4882a593Smuzhiyun static PyTypeObject pyrf_evlist__type = {
1174*4882a593Smuzhiyun PyVarObject_HEAD_INIT(NULL, 0)
1175*4882a593Smuzhiyun .tp_name = "perf.evlist",
1176*4882a593Smuzhiyun .tp_basicsize = sizeof(struct pyrf_evlist),
1177*4882a593Smuzhiyun .tp_dealloc = (destructor)pyrf_evlist__delete,
1178*4882a593Smuzhiyun .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
1179*4882a593Smuzhiyun .tp_as_sequence = &pyrf_evlist__sequence_methods,
1180*4882a593Smuzhiyun .tp_doc = pyrf_evlist__doc,
1181*4882a593Smuzhiyun .tp_methods = pyrf_evlist__methods,
1182*4882a593Smuzhiyun .tp_init = (initproc)pyrf_evlist__init,
1183*4882a593Smuzhiyun };
1184*4882a593Smuzhiyun
pyrf_evlist__setup_types(void)1185*4882a593Smuzhiyun static int pyrf_evlist__setup_types(void)
1186*4882a593Smuzhiyun {
1187*4882a593Smuzhiyun pyrf_evlist__type.tp_new = PyType_GenericNew;
1188*4882a593Smuzhiyun return PyType_Ready(&pyrf_evlist__type);
1189*4882a593Smuzhiyun }
1190*4882a593Smuzhiyun
1191*4882a593Smuzhiyun #define PERF_CONST(name) { #name, PERF_##name }
1192*4882a593Smuzhiyun
1193*4882a593Smuzhiyun static struct {
1194*4882a593Smuzhiyun const char *name;
1195*4882a593Smuzhiyun int value;
1196*4882a593Smuzhiyun } perf__constants[] = {
1197*4882a593Smuzhiyun PERF_CONST(TYPE_HARDWARE),
1198*4882a593Smuzhiyun PERF_CONST(TYPE_SOFTWARE),
1199*4882a593Smuzhiyun PERF_CONST(TYPE_TRACEPOINT),
1200*4882a593Smuzhiyun PERF_CONST(TYPE_HW_CACHE),
1201*4882a593Smuzhiyun PERF_CONST(TYPE_RAW),
1202*4882a593Smuzhiyun PERF_CONST(TYPE_BREAKPOINT),
1203*4882a593Smuzhiyun
1204*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CPU_CYCLES),
1205*4882a593Smuzhiyun PERF_CONST(COUNT_HW_INSTRUCTIONS),
1206*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_REFERENCES),
1207*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_MISSES),
1208*4882a593Smuzhiyun PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
1209*4882a593Smuzhiyun PERF_CONST(COUNT_HW_BRANCH_MISSES),
1210*4882a593Smuzhiyun PERF_CONST(COUNT_HW_BUS_CYCLES),
1211*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_L1D),
1212*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_L1I),
1213*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_LL),
1214*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_DTLB),
1215*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_ITLB),
1216*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_BPU),
1217*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_OP_READ),
1218*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
1219*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
1220*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
1221*4882a593Smuzhiyun PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
1222*4882a593Smuzhiyun
1223*4882a593Smuzhiyun PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
1224*4882a593Smuzhiyun PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
1225*4882a593Smuzhiyun
1226*4882a593Smuzhiyun PERF_CONST(COUNT_SW_CPU_CLOCK),
1227*4882a593Smuzhiyun PERF_CONST(COUNT_SW_TASK_CLOCK),
1228*4882a593Smuzhiyun PERF_CONST(COUNT_SW_PAGE_FAULTS),
1229*4882a593Smuzhiyun PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
1230*4882a593Smuzhiyun PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
1231*4882a593Smuzhiyun PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
1232*4882a593Smuzhiyun PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
1233*4882a593Smuzhiyun PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
1234*4882a593Smuzhiyun PERF_CONST(COUNT_SW_EMULATION_FAULTS),
1235*4882a593Smuzhiyun PERF_CONST(COUNT_SW_DUMMY),
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun PERF_CONST(SAMPLE_IP),
1238*4882a593Smuzhiyun PERF_CONST(SAMPLE_TID),
1239*4882a593Smuzhiyun PERF_CONST(SAMPLE_TIME),
1240*4882a593Smuzhiyun PERF_CONST(SAMPLE_ADDR),
1241*4882a593Smuzhiyun PERF_CONST(SAMPLE_READ),
1242*4882a593Smuzhiyun PERF_CONST(SAMPLE_CALLCHAIN),
1243*4882a593Smuzhiyun PERF_CONST(SAMPLE_ID),
1244*4882a593Smuzhiyun PERF_CONST(SAMPLE_CPU),
1245*4882a593Smuzhiyun PERF_CONST(SAMPLE_PERIOD),
1246*4882a593Smuzhiyun PERF_CONST(SAMPLE_STREAM_ID),
1247*4882a593Smuzhiyun PERF_CONST(SAMPLE_RAW),
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
1250*4882a593Smuzhiyun PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
1251*4882a593Smuzhiyun PERF_CONST(FORMAT_ID),
1252*4882a593Smuzhiyun PERF_CONST(FORMAT_GROUP),
1253*4882a593Smuzhiyun
1254*4882a593Smuzhiyun PERF_CONST(RECORD_MMAP),
1255*4882a593Smuzhiyun PERF_CONST(RECORD_LOST),
1256*4882a593Smuzhiyun PERF_CONST(RECORD_COMM),
1257*4882a593Smuzhiyun PERF_CONST(RECORD_EXIT),
1258*4882a593Smuzhiyun PERF_CONST(RECORD_THROTTLE),
1259*4882a593Smuzhiyun PERF_CONST(RECORD_UNTHROTTLE),
1260*4882a593Smuzhiyun PERF_CONST(RECORD_FORK),
1261*4882a593Smuzhiyun PERF_CONST(RECORD_READ),
1262*4882a593Smuzhiyun PERF_CONST(RECORD_SAMPLE),
1263*4882a593Smuzhiyun PERF_CONST(RECORD_MMAP2),
1264*4882a593Smuzhiyun PERF_CONST(RECORD_AUX),
1265*4882a593Smuzhiyun PERF_CONST(RECORD_ITRACE_START),
1266*4882a593Smuzhiyun PERF_CONST(RECORD_LOST_SAMPLES),
1267*4882a593Smuzhiyun PERF_CONST(RECORD_SWITCH),
1268*4882a593Smuzhiyun PERF_CONST(RECORD_SWITCH_CPU_WIDE),
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun PERF_CONST(RECORD_MISC_SWITCH_OUT),
1271*4882a593Smuzhiyun { .name = NULL, },
1272*4882a593Smuzhiyun };
1273*4882a593Smuzhiyun
pyrf__tracepoint(struct pyrf_evsel * pevsel,PyObject * args,PyObject * kwargs)1274*4882a593Smuzhiyun static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
1275*4882a593Smuzhiyun PyObject *args, PyObject *kwargs)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun struct tep_event *tp_format;
1278*4882a593Smuzhiyun static char *kwlist[] = { "sys", "name", NULL };
1279*4882a593Smuzhiyun char *sys = NULL;
1280*4882a593Smuzhiyun char *name = NULL;
1281*4882a593Smuzhiyun
1282*4882a593Smuzhiyun if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
1283*4882a593Smuzhiyun &sys, &name))
1284*4882a593Smuzhiyun return NULL;
1285*4882a593Smuzhiyun
1286*4882a593Smuzhiyun tp_format = trace_event__tp_format(sys, name);
1287*4882a593Smuzhiyun if (IS_ERR(tp_format))
1288*4882a593Smuzhiyun return _PyLong_FromLong(-1);
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun return _PyLong_FromLong(tp_format->id);
1291*4882a593Smuzhiyun }
1292*4882a593Smuzhiyun
1293*4882a593Smuzhiyun static PyMethodDef perf__methods[] = {
1294*4882a593Smuzhiyun {
1295*4882a593Smuzhiyun .ml_name = "tracepoint",
1296*4882a593Smuzhiyun .ml_meth = (PyCFunction) pyrf__tracepoint,
1297*4882a593Smuzhiyun .ml_flags = METH_VARARGS | METH_KEYWORDS,
1298*4882a593Smuzhiyun .ml_doc = PyDoc_STR("Get tracepoint config.")
1299*4882a593Smuzhiyun },
1300*4882a593Smuzhiyun { .ml_name = NULL, }
1301*4882a593Smuzhiyun };
1302*4882a593Smuzhiyun
1303*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
initperf(void)1304*4882a593Smuzhiyun PyMODINIT_FUNC initperf(void)
1305*4882a593Smuzhiyun #else
1306*4882a593Smuzhiyun PyMODINIT_FUNC PyInit_perf(void)
1307*4882a593Smuzhiyun #endif
1308*4882a593Smuzhiyun {
1309*4882a593Smuzhiyun PyObject *obj;
1310*4882a593Smuzhiyun int i;
1311*4882a593Smuzhiyun PyObject *dict;
1312*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
1313*4882a593Smuzhiyun PyObject *module = Py_InitModule("perf", perf__methods);
1314*4882a593Smuzhiyun #else
1315*4882a593Smuzhiyun static struct PyModuleDef moduledef = {
1316*4882a593Smuzhiyun PyModuleDef_HEAD_INIT,
1317*4882a593Smuzhiyun "perf", /* m_name */
1318*4882a593Smuzhiyun "", /* m_doc */
1319*4882a593Smuzhiyun -1, /* m_size */
1320*4882a593Smuzhiyun perf__methods, /* m_methods */
1321*4882a593Smuzhiyun NULL, /* m_reload */
1322*4882a593Smuzhiyun NULL, /* m_traverse */
1323*4882a593Smuzhiyun NULL, /* m_clear */
1324*4882a593Smuzhiyun NULL, /* m_free */
1325*4882a593Smuzhiyun };
1326*4882a593Smuzhiyun PyObject *module = PyModule_Create(&moduledef);
1327*4882a593Smuzhiyun #endif
1328*4882a593Smuzhiyun
1329*4882a593Smuzhiyun if (module == NULL ||
1330*4882a593Smuzhiyun pyrf_event__setup_types() < 0 ||
1331*4882a593Smuzhiyun pyrf_evlist__setup_types() < 0 ||
1332*4882a593Smuzhiyun pyrf_evsel__setup_types() < 0 ||
1333*4882a593Smuzhiyun pyrf_thread_map__setup_types() < 0 ||
1334*4882a593Smuzhiyun pyrf_cpu_map__setup_types() < 0)
1335*4882a593Smuzhiyun #if PY_MAJOR_VERSION < 3
1336*4882a593Smuzhiyun return;
1337*4882a593Smuzhiyun #else
1338*4882a593Smuzhiyun return module;
1339*4882a593Smuzhiyun #endif
1340*4882a593Smuzhiyun
1341*4882a593Smuzhiyun /* The page_size is placed in util object. */
1342*4882a593Smuzhiyun page_size = sysconf(_SC_PAGE_SIZE);
1343*4882a593Smuzhiyun
1344*4882a593Smuzhiyun Py_INCREF(&pyrf_evlist__type);
1345*4882a593Smuzhiyun PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
1346*4882a593Smuzhiyun
1347*4882a593Smuzhiyun Py_INCREF(&pyrf_evsel__type);
1348*4882a593Smuzhiyun PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1349*4882a593Smuzhiyun
1350*4882a593Smuzhiyun Py_INCREF(&pyrf_mmap_event__type);
1351*4882a593Smuzhiyun PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
1352*4882a593Smuzhiyun
1353*4882a593Smuzhiyun Py_INCREF(&pyrf_lost_event__type);
1354*4882a593Smuzhiyun PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
1355*4882a593Smuzhiyun
1356*4882a593Smuzhiyun Py_INCREF(&pyrf_comm_event__type);
1357*4882a593Smuzhiyun PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
1358*4882a593Smuzhiyun
1359*4882a593Smuzhiyun Py_INCREF(&pyrf_task_event__type);
1360*4882a593Smuzhiyun PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1361*4882a593Smuzhiyun
1362*4882a593Smuzhiyun Py_INCREF(&pyrf_throttle_event__type);
1363*4882a593Smuzhiyun PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
1364*4882a593Smuzhiyun
1365*4882a593Smuzhiyun Py_INCREF(&pyrf_task_event__type);
1366*4882a593Smuzhiyun PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
1367*4882a593Smuzhiyun
1368*4882a593Smuzhiyun Py_INCREF(&pyrf_read_event__type);
1369*4882a593Smuzhiyun PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
1370*4882a593Smuzhiyun
1371*4882a593Smuzhiyun Py_INCREF(&pyrf_sample_event__type);
1372*4882a593Smuzhiyun PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun Py_INCREF(&pyrf_context_switch_event__type);
1375*4882a593Smuzhiyun PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
1376*4882a593Smuzhiyun
1377*4882a593Smuzhiyun Py_INCREF(&pyrf_thread_map__type);
1378*4882a593Smuzhiyun PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun Py_INCREF(&pyrf_cpu_map__type);
1381*4882a593Smuzhiyun PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
1382*4882a593Smuzhiyun
1383*4882a593Smuzhiyun dict = PyModule_GetDict(module);
1384*4882a593Smuzhiyun if (dict == NULL)
1385*4882a593Smuzhiyun goto error;
1386*4882a593Smuzhiyun
1387*4882a593Smuzhiyun for (i = 0; perf__constants[i].name != NULL; i++) {
1388*4882a593Smuzhiyun obj = _PyLong_FromLong(perf__constants[i].value);
1389*4882a593Smuzhiyun if (obj == NULL)
1390*4882a593Smuzhiyun goto error;
1391*4882a593Smuzhiyun PyDict_SetItemString(dict, perf__constants[i].name, obj);
1392*4882a593Smuzhiyun Py_DECREF(obj);
1393*4882a593Smuzhiyun }
1394*4882a593Smuzhiyun
1395*4882a593Smuzhiyun error:
1396*4882a593Smuzhiyun if (PyErr_Occurred())
1397*4882a593Smuzhiyun PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1398*4882a593Smuzhiyun #if PY_MAJOR_VERSION >= 3
1399*4882a593Smuzhiyun return module;
1400*4882a593Smuzhiyun #endif
1401*4882a593Smuzhiyun }
1402*4882a593Smuzhiyun
1403*4882a593Smuzhiyun /*
1404*4882a593Smuzhiyun * Dummy, to avoid dragging all the test_attr infrastructure in the python
1405*4882a593Smuzhiyun * binding.
1406*4882a593Smuzhiyun */
test_attr__open(struct perf_event_attr * attr,pid_t pid,int cpu,int fd,int group_fd,unsigned long flags)1407*4882a593Smuzhiyun void test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
1408*4882a593Smuzhiyun int fd, int group_fd, unsigned long flags)
1409*4882a593Smuzhiyun {
1410*4882a593Smuzhiyun }
1411