1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <Python.h>
2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <structmember.h>
3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <inttypes.h>
4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <poll.h>
5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evlist.h"
6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "evsel.h"
7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "event.h"
8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "cpumap.h"
9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "thread_map.h"
10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Support debug printing even though util/debug.c is not linked.  That means
13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * implementing 'verbose' and 'eprintf'.
14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint verbose;
16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint eprintf(int level, const char *fmt, ...)
18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	va_list args;
20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int ret = 0;
21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (verbose >= level) {
23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		va_start(args, fmt);
24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = vfprintf(stderr, fmt, args);
25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		va_end(args);
26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* Define PyVarObject_HEAD_INIT for python 2.5 */
32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#ifndef PyVarObject_HEAD_INIT
33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#endif
35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct throttle_event {
37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_event_header header;
38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u64			 time;
39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u64			 id;
40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u64			 stream_id;
41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengPyMODINIT_FUNC initperf(void);
44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define member_def(type, member, ptype, help) \
46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ #member, ptype, \
47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	  0, help }
49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define sample_member_def(name, member, ptype, help) \
51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ #name, ptype, \
52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	  0, help }
54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pyrf_event {
56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject_HEAD
57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_sample sample;
58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	union perf_event   event;
59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define sample_members \
62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_mmap_event__members[] = {
75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(perf_event_header, type, T_UINT, "event type"),
77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, pid, T_UINT, "event pid"),
78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, tid, T_UINT, "event tid"),
79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, len, T_ULONGLONG, "map length"),
81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *ret;
89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *s;
90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 "filename: %s }",
94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     pevent->event.mmap.pid, pevent->event.mmap.tid,
95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     pevent->event.mmap.start, pevent->event.mmap.len,
96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyErr_NoMemory();
98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyString_FromString(s);
100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(s);
101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_mmap_event__type = {
106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.mmap_event",
108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_mmap_event__doc,
111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_mmap_event__members,
112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_task_event__members[] = {
118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(perf_event_header, type, T_UINT, "event type"),
120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(fork_event, pid, T_UINT, "event pid"),
121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(fork_event, ppid, T_UINT, "event ppid"),
122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(fork_event, tid, T_UINT, "event tid"),
123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(fork_event, ptid, T_UINT, "event ptid"),
124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(fork_event, time, T_ULONGLONG, "timestamp"),
125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   "ptid: %u, time: %" PRIu64 "}",
132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.fork.pid,
134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.fork.ppid,
135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.fork.tid,
136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.fork.ptid,
137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.fork.time);
138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_task_event__type = {
141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.task_event",
143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_task_event__doc,
146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_task_event__members,
147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_task_event__repr,
148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_comm_event__members[] = {
153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(perf_event_header, type, T_UINT, "event type"),
155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(comm_event, pid, T_UINT, "event pid"),
156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(comm_event, tid, T_UINT, "event tid"),
157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.comm.pid,
165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.comm.tid,
166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.comm.comm);
167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_comm_event__type = {
170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.comm_event",
172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_comm_event__doc,
175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_comm_event__members,
176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_throttle_event__members[] = {
182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(perf_event_header, type, T_UINT, "event type"),
184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(throttle_event, id, T_ULONGLONG, "event id"),
186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   ", stream_id: %" PRIu64 " }",
196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   te->time, te->id, te->stream_id);
198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_throttle_event__type = {
201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.throttle_event",
203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_throttle_event__doc,
206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_throttle_event__members,
207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_lost_event__members[] = {
213e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
214e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(lost_event, id, T_ULONGLONG, "event id"),
215e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(lost_event, lost, T_ULONGLONG, "number of lost events"),
216e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
217e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
218e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
219e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
220e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
221e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *ret;
222e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *s;
223e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
224e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", "
225e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			 "lost: %#" PRIx64 " }",
226e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		     pevent->event.lost.id, pevent->event.lost.lost) < 0) {
227e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyErr_NoMemory();
228e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
229e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyString_FromString(s);
230e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(s);
231e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
232e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
233e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
234e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
235e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_lost_event__type = {
236e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
237e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.lost_event",
238e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
239e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
240e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_lost_event__doc,
241e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_lost_event__members,
242e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_lost_event__repr,
243e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
244e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
245e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
246e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
247e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_read_event__members[] = {
248e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
249e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(read_event, pid, T_UINT, "event pid"),
250e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(read_event, tid, T_UINT, "event tid"),
251e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
252e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
253e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
254e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
255e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
256e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
257e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.read.pid,
258e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   pevent->event.read.tid);
259e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
260e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 	 * FIXME: return the array of read values,
261e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 	 * making this method useful ;-)
262e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 	 */
263e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
264e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
265e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_read_event__type = {
266e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
267e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.read_event",
268e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
269e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
270e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_read_event__doc,
271e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_read_event__members,
272e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_read_event__repr,
273e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
274e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
275e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
276e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
277e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMemberDef pyrf_sample_event__members[] = {
278e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	sample_members
279e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	member_def(perf_event_header, type, T_UINT, "event type"),
280e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
281e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
282e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
283e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
284e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
285e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *ret;
286e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *s;
287e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
288e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (asprintf(&s, "{ type: sample }") < 0) {
289e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyErr_NoMemory();
290e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	} else {
291e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		ret = PyString_FromString(s);
292e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		free(s);
293e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
294e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return ret;
295e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
296e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
297e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_sample_event__type = {
298e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
299e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.sample_event",
300e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_event),
301e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
302e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_sample_event__doc,
303e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_members	= pyrf_sample_event__members,
304e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_repr	= (reprfunc)pyrf_sample_event__repr,
305e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
306e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
307e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_event__setup_types(void)
308e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
309e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err;
310e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_mmap_event__type.tp_new =
311e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_task_event__type.tp_new =
312e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_comm_event__type.tp_new =
313e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_lost_event__type.tp_new =
314e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_read_event__type.tp_new =
315e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_sample_event__type.tp_new =
316e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
317e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_mmap_event__type);
318e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
319e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
320e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_lost_event__type);
321e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
322e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
323e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_task_event__type);
324e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
325e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
326e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_comm_event__type);
327e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
328e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
329e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_throttle_event__type);
330e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
331e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
332e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_read_event__type);
333e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
334e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
335e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	err = PyType_Ready(&pyrf_sample_event__type);
336e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (err < 0)
337e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto out;
338e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengout:
339e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return err;
340e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
341e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
342e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject *pyrf_event__type[] = {
343e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
344e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,
345e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
346e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
347e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
348e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
349e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
350e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_READ]	 = &pyrf_read_event__type,
351e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,
352e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
353e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
354e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_event__new(union perf_event *event)
355e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
356e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_event *pevent;
357e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyTypeObject *ptype;
358e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
359e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event->header.type < PERF_RECORD_MMAP ||
360e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    event->header.type > PERF_RECORD_SAMPLE)
361e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
362e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
363e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	ptype = pyrf_event__type[event->header.type];
364e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevent = PyObject_New(struct pyrf_event, ptype);
365e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pevent != NULL)
366e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		memcpy(&pevent->event, event, event->header.size);
367e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return (PyObject *)pevent;
368e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
369e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
370e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pyrf_cpu_map {
371e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject_HEAD
372e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
373e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cpu_map *cpus;
374e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
375e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
376e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
377e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			      PyObject *args, PyObject *kwargs)
378e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
379e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "cpustr", NULL };
380e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	char *cpustr = NULL;
381e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
382e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
383e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 kwlist, &cpustr))
384e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
385e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
386e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pcpus->cpus = cpu_map__new(cpustr);
387e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pcpus->cpus == NULL)
388e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
389e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
390e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
391e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
392e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
393e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
394e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cpu_map__delete(pcpus->cpus);
395e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pcpus->ob_type->tp_free((PyObject*)pcpus);
396e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
397e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
398e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
399e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
400e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_cpu_map *pcpus = (void *)obj;
401e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
402e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pcpus->cpus->nr;
403e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
404e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
405e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
406e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
407e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_cpu_map *pcpus = (void *)obj;
408e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
409e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i >= pcpus->cpus->nr)
410e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
411e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
412e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_BuildValue("i", pcpus->cpus->map[i]);
413e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
414e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
415e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PySequenceMethods pyrf_cpu_map__sequence_methods = {
416e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_length = pyrf_cpu_map__length,
417e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_item   = pyrf_cpu_map__item,
418e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
419e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
420e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
421e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
422e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_cpu_map__type = {
423e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
424e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.cpu_map",
425e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
426e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
427e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
428e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_cpu_map__doc,
429e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
430e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_init	= (initproc)pyrf_cpu_map__init,
431e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
432e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
433e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_cpu_map__setup_types(void)
434e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
435e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
436e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyType_Ready(&pyrf_cpu_map__type);
437e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
438e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
439e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pyrf_thread_map {
440e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject_HEAD
441e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
442e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct thread_map *threads;
443e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
444e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
445e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
446e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				 PyObject *args, PyObject *kwargs)
447e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
448e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "pid", "tid", "uid", NULL };
449e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int pid = -1, tid = -1, uid = UINT_MAX;
450e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
451e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
452e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 kwlist, &pid, &tid, &uid))
453e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
454e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
455e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pthreads->threads = thread_map__new(pid, tid, uid);
456e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pthreads->threads == NULL)
457e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
458e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
459e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
460e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
461e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
462e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
463e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	thread_map__delete(pthreads->threads);
464e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pthreads->ob_type->tp_free((PyObject*)pthreads);
465e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
466e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
467e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic Py_ssize_t pyrf_thread_map__length(PyObject *obj)
468e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
469e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_thread_map *pthreads = (void *)obj;
470e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
471e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pthreads->threads->nr;
472e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
473e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
474e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
475e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
476e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_thread_map *pthreads = (void *)obj;
477e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
478e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i >= pthreads->threads->nr)
479e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
480e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
481e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_BuildValue("i", pthreads->threads->map[i]);
482e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
483e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
484e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PySequenceMethods pyrf_thread_map__sequence_methods = {
485e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_length = pyrf_thread_map__length,
486e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_item   = pyrf_thread_map__item,
487e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
488e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
489e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
490e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
491e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_thread_map__type = {
492e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
493e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.thread_map",
494e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_thread_map),
495e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
496e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
497e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_thread_map__doc,
498e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
499e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_init	= (initproc)pyrf_thread_map__init,
500e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
501e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
502e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_thread_map__setup_types(void)
503e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
504e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_thread_map__type.tp_new = PyType_GenericNew;
505e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyType_Ready(&pyrf_thread_map__type);
506e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
507e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
508e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pyrf_evsel {
509e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject_HEAD
510e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
511e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evsel evsel;
512e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
513e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
514e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_evsel__init(struct pyrf_evsel *pevsel,
515e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			    PyObject *args, PyObject *kwargs)
516e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
517e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_event_attr attr = {
518e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.type = PERF_TYPE_HARDWARE,
519e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.config = PERF_COUNT_HW_CPU_CYCLES,
520e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
521e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	};
522e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = {
523e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"type",
524e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"config",
525e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"sample_freq",
526e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"sample_period",
527e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"sample_type",
528e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"read_format",
529e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"disabled",
530e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"inherit",
531e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"pinned",
532e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"exclusive",
533e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"exclude_user",
534e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"exclude_kernel",
535e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"exclude_hv",
536e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"exclude_idle",
537e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"mmap",
538e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"comm",
539e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"freq",
540e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"inherit_stat",
541e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"enable_on_exec",
542e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"task",
543e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"watermark",
544e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"precise_ip",
545e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"mmap_data",
546e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"sample_id_all",
547e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"wakeup_events",
548e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"bp_type",
549e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"bp_addr",
550e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		"bp_len",
551e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		 NULL
552e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	};
553e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u64 sample_period = 0;
554e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	u32 disabled = 0,
555e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    inherit = 0,
556e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pinned = 0,
557e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    exclusive = 0,
558e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    exclude_user = 0,
559e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    exclude_kernel = 0,
560e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    exclude_hv = 0,
561e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    exclude_idle = 0,
562e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    mmap = 0,
563e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    comm = 0,
564e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    freq = 1,
565e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    inherit_stat = 0,
566e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    enable_on_exec = 0,
567e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    task = 0,
568e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    watermark = 0,
569e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    precise_ip = 0,
570e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    mmap_data = 0,
571e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    sample_id_all = 1;
572e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int idx = 0;
573e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
574e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
575e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
576e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &attr.type, &attr.config, &attr.sample_freq,
577e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &sample_period, &attr.sample_type,
578e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &attr.read_format, &disabled, &inherit,
579e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &pinned, &exclusive, &exclude_user,
580e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &exclude_kernel, &exclude_hv, &exclude_idle,
581e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &mmap, &comm, &freq, &inherit_stat,
582e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &enable_on_exec, &task, &watermark,
583e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &precise_ip, &mmap_data, &sample_id_all,
584e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &attr.wakeup_events, &attr.bp_type,
585e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &attr.bp_addr, &attr.bp_len, &idx))
586e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
587e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
588e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* union... */
589e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (sample_period != 0) {
590e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (attr.sample_freq != 0)
591e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return -1; /* FIXME: throw right exception */
592e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		attr.sample_period = sample_period;
593e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
594e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
595e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/* Bitfields */
596e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.disabled	    = disabled;
597e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.inherit	    = inherit;
598e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.pinned	    = pinned;
599e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.exclusive	    = exclusive;
600e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.exclude_user   = exclude_user;
601e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.exclude_kernel = exclude_kernel;
602e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.exclude_hv	    = exclude_hv;
603e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.exclude_idle   = exclude_idle;
604e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.mmap	    = mmap;
605e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.comm	    = comm;
606e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.freq	    = freq;
607e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.inherit_stat   = inherit_stat;
608e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.enable_on_exec = enable_on_exec;
609e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.task	    = task;
610e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.watermark	    = watermark;
611e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.precise_ip	    = precise_ip;
612e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.mmap_data	    = mmap_data;
613e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	attr.sample_id_all  = sample_id_all;
614e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
615e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evsel__init(&pevsel->evsel, &attr, idx);
616e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
617e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
618e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
619e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
620e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
621e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evsel__exit(&pevsel->evsel);
622e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevsel->ob_type->tp_free((PyObject*)pevsel);
623e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
624e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
625e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
626e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  PyObject *args, PyObject *kwargs)
627e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
628e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evsel *evsel = &pevsel->evsel;
629e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cpu_map *cpus = NULL;
630e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct thread_map *threads = NULL;
631e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *pcpus = NULL, *pthreads = NULL;
632e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int group = 0, inherit = 0;
633e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
634e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
635e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
636e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &pcpus, &pthreads, &group, &inherit))
637e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
638e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
639e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pthreads != NULL)
640e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		threads = ((struct pyrf_thread_map *)pthreads)->threads;
641e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
642e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (pcpus != NULL)
643e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
644e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
645e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	evsel->attr.inherit = inherit;
646e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	/*
647e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * This will group just the fds for this single evsel, to group
648e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 * multiple events, use evlist.open().
649e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	 */
650e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perf_evsel__open(evsel, cpus, threads) < 0) {
651e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyErr_SetFromErrno(PyExc_OSError);
652e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
653e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
654e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
655e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(Py_None);
656e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_None;
657e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
658e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
659e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMethodDef pyrf_evsel__methods[] = {
660e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
661e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "open",
662e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evsel__open,
663e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
664e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
665e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
666e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .ml_name = NULL, }
667e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
668e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
669e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
670e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
671e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_evsel__type = {
672e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
673e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.evsel",
674e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_evsel),
675e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_dealloc	= (destructor)pyrf_evsel__delete,
676e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
677e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_evsel__doc,
678e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_methods	= pyrf_evsel__methods,
679e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_init	= (initproc)pyrf_evsel__init,
680e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
681e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
682e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_evsel__setup_types(void)
683e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
684e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_evsel__type.tp_new = PyType_GenericNew;
685e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyType_Ready(&pyrf_evsel__type);
686e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
687e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
688e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstruct pyrf_evlist {
689e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject_HEAD
690e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
691e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist evlist;
692e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
693e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
694e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_evlist__init(struct pyrf_evlist *pevlist,
695e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			     PyObject *args, PyObject *kwargs __maybe_unused)
696e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
697e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *pcpus = NULL, *pthreads = NULL;
698e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct cpu_map *cpus;
699e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct thread_map *threads;
700e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
701e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
702e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return -1;
703e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
704e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	threads = ((struct pyrf_thread_map *)pthreads)->threads;
705e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
706e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evlist__init(&pevlist->evlist, cpus, threads);
707e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return 0;
708e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
709e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
710e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
711e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
712e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evlist__exit(&pevlist->evlist);
713e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pevlist->ob_type->tp_free((PyObject*)pevlist);
714e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
715e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
716e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
717e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   PyObject *args, PyObject *kwargs)
718e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
719e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
720e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "pages", "overwrite", NULL };
721e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int pages = 128, overwrite = false;
722e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
723e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
724e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &pages, &overwrite))
725e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
726e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
727e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
728e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyErr_SetFromErrno(PyExc_OSError);
729e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
730e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
731e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
732e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(Py_None);
733e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_None;
734e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
735e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
736e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
737e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   PyObject *args, PyObject *kwargs)
738e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
739e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
740e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "timeout", NULL };
741e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int timeout = -1, n;
742e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
743e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
744e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
745e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
746e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	n = poll(evlist->pollfd, evlist->nr_fds, timeout);
747e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (n < 0) {
748e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyErr_SetFromErrno(PyExc_OSError);
749e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
750e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
751e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
752e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_BuildValue("i", n);
753e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
754e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
755e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
756e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 PyObject *args __maybe_unused,
757e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 PyObject *kwargs __maybe_unused)
758e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
759e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
760e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng        PyObject *list = PyList_New(0);
761e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
762e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
763e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; i < evlist->nr_fds; ++i) {
764e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyObject *file;
765e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
766e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
767e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (fp == NULL)
768e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto free_list;
769e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
770e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		file = PyFile_FromFile(fp, "perf", "r", NULL);
771e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (file == NULL)
772e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto free_list;
773e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
774e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (PyList_Append(list, file) != 0) {
775e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			Py_DECREF(file);
776e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto free_list;
777e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		}
778e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
779e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		Py_DECREF(file);
780e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
781e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
782e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return list;
783e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengfree_list:
784e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyErr_NoMemory();
785e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
786e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
787e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
788e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
789e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  PyObject *args,
790e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				  PyObject *kwargs __maybe_unused)
791e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
792e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
793e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *pevsel;
794e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evsel *evsel;
795e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
796e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTuple(args, "O", &pevsel))
797e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
798e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
799e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(pevsel);
800e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
801e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	evsel->idx = evlist->nr_entries;
802e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	perf_evlist__add(evlist, evsel);
803e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
804e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_BuildValue("i", evlist->nr_entries);
805e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
806e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
807e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
808e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					  PyObject *args, PyObject *kwargs)
809e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
810e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
811e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	union perf_event *event;
812e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int sample_id_all = 1, cpu;
813e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
814e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int err;
815e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
816e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
817e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					 &cpu, &sample_id_all))
818e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
819e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
820e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	event = perf_evlist__mmap_read(evlist, cpu);
821e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (event != NULL) {
822e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyObject *pyevent = pyrf_event__new(event);
823e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
824e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
825e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		perf_evlist__mmap_consume(evlist, cpu);
826e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
827e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (pyevent == NULL)
828e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return PyErr_NoMemory();
829e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
830e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		err = perf_evlist__parse_sample(evlist, event, &pevent->sample);
831e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (err)
832e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			return PyErr_Format(PyExc_OSError,
833e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng					    "perf: can't parse sample, err=%d", err);
834e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return pyevent;
835e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
836e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
837e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(Py_None);
838e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_None;
839e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
840e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
841e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
842e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng				   PyObject *args, PyObject *kwargs)
843e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
844e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evlist *evlist = &pevlist->evlist;
845e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int group = 0;
846e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	static char *kwlist[] = { "group", NULL };
847e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
848e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, &group))
849e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
850e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
851e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (group)
852e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		perf_evlist__set_leader(evlist);
853e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
854e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (perf_evlist__open(evlist) < 0) {
855e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyErr_SetFromErrno(PyExc_OSError);
856e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
857e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
858e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
859e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(Py_None);
860e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_None;
861e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
862e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
863e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMethodDef pyrf_evlist__methods[] = {
864e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
865e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "mmap",
866e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
867e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
868e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
869e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
870e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
871e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "open",
872e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__open,
873e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
874e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("open the file descriptors.")
875e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
876e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
877e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "poll",
878e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
879e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
880e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
881e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
882e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
883e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "get_pollfd",
884e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
885e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
886e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
887e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
888e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
889e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "add",
890e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__add,
891e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
892e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
893e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
894e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{
895e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_name  = "read_on_cpu",
896e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
897e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_flags = METH_VARARGS | METH_KEYWORDS,
898e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		.ml_doc	  = PyDoc_STR("reads an event.")
899e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	},
900e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .ml_name = NULL, }
901e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
902e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
903e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic Py_ssize_t pyrf_evlist__length(PyObject *obj)
904e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
905e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_evlist *pevlist = (void *)obj;
906e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
907e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return pevlist->evlist.nr_entries;
908e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
909e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
910e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
911e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
912e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct pyrf_evlist *pevlist = (void *)obj;
913e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	struct perf_evsel *pos;
914e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
915e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (i >= pevlist->evlist.nr_entries)
916e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return NULL;
917e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
918e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	list_for_each_entry(pos, &pevlist->evlist.entries, node)
919e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (i-- == 0)
920e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			break;
921e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
922e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
923e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
924e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
925e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PySequenceMethods pyrf_evlist__sequence_methods = {
926e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_length = pyrf_evlist__length,
927e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.sq_item   = pyrf_evlist__item,
928e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
929e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
930e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
931e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
932e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyTypeObject pyrf_evlist__type = {
933e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyVarObject_HEAD_INIT(NULL, 0)
934e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_name	= "perf.evlist",
935e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_basicsize	= sizeof(struct pyrf_evlist),
936e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_dealloc	= (destructor)pyrf_evlist__delete,
937e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
938e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
939e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_doc		= pyrf_evlist__doc,
940e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_methods	= pyrf_evlist__methods,
941e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	.tp_init	= (initproc)pyrf_evlist__init,
942e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
943e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
944e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic int pyrf_evlist__setup_types(void)
945e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
946e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	pyrf_evlist__type.tp_new = PyType_GenericNew;
947e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	return PyType_Ready(&pyrf_evlist__type);
948e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
949e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
950e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic struct {
951e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	const char *name;
952e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int	    value;
953e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} perf__constants[] = {
954e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_HARDWARE",   PERF_TYPE_HARDWARE },
955e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_SOFTWARE",   PERF_TYPE_SOFTWARE },
956e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
957e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_HW_CACHE",   PERF_TYPE_HW_CACHE },
958e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_RAW",	     PERF_TYPE_RAW },
959e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
960e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
961e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CPU_CYCLES",	  PERF_COUNT_HW_CPU_CYCLES },
962e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_INSTRUCTIONS",	  PERF_COUNT_HW_INSTRUCTIONS },
963e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_REFERENCES",	  PERF_COUNT_HW_CACHE_REFERENCES },
964e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_MISSES",	  PERF_COUNT_HW_CACHE_MISSES },
965e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
966e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_BRANCH_MISSES",	  PERF_COUNT_HW_BRANCH_MISSES },
967e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_BUS_CYCLES",	  PERF_COUNT_HW_BUS_CYCLES },
968e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_L1D",		  PERF_COUNT_HW_CACHE_L1D },
969e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_L1I",		  PERF_COUNT_HW_CACHE_L1I },
970e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_LL",	  	  PERF_COUNT_HW_CACHE_LL },
971e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_DTLB",	  PERF_COUNT_HW_CACHE_DTLB },
972e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_ITLB",	  PERF_COUNT_HW_CACHE_ITLB },
973e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_BPU",		  PERF_COUNT_HW_CACHE_BPU },
974e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_OP_READ",	  PERF_COUNT_HW_CACHE_OP_READ },
975e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_OP_WRITE",	  PERF_COUNT_HW_CACHE_OP_WRITE },
976e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_OP_PREFETCH",	  PERF_COUNT_HW_CACHE_OP_PREFETCH },
977e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
978e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_CACHE_RESULT_MISS",   PERF_COUNT_HW_CACHE_RESULT_MISS },
979e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
980e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_STALLED_CYCLES_FRONTEND",	  PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
981e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_HW_STALLED_CYCLES_BACKEND",	  PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
982e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
983e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_CPU_CLOCK",	       PERF_COUNT_SW_CPU_CLOCK },
984e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_TASK_CLOCK",       PERF_COUNT_SW_TASK_CLOCK },
985e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_PAGE_FAULTS",      PERF_COUNT_SW_PAGE_FAULTS },
986e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
987e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_CPU_MIGRATIONS",   PERF_COUNT_SW_CPU_MIGRATIONS },
988e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_PAGE_FAULTS_MIN",  PERF_COUNT_SW_PAGE_FAULTS_MIN },
989e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_PAGE_FAULTS_MAJ",  PERF_COUNT_SW_PAGE_FAULTS_MAJ },
990e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
991e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
992e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "COUNT_SW_DUMMY",            PERF_COUNT_SW_DUMMY },
993e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
994e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_IP",	      PERF_SAMPLE_IP },
995e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_TID",	      PERF_SAMPLE_TID },
996e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_TIME",      PERF_SAMPLE_TIME },
997e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_ADDR",      PERF_SAMPLE_ADDR },
998e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_READ",      PERF_SAMPLE_READ },
999e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
1000e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_ID",	      PERF_SAMPLE_ID },
1001e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_CPU",	      PERF_SAMPLE_CPU },
1002e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_PERIOD",    PERF_SAMPLE_PERIOD },
1003e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
1004e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "SAMPLE_RAW",	      PERF_SAMPLE_RAW },
1005e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1006e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
1007e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
1008e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "FORMAT_ID",		       PERF_FORMAT_ID },
1009e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "FORMAT_GROUP",	       PERF_FORMAT_GROUP },
1010e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1011e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_MMAP",       PERF_RECORD_MMAP },
1012e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_LOST",       PERF_RECORD_LOST },
1013e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_COMM",       PERF_RECORD_COMM },
1014e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_EXIT",       PERF_RECORD_EXIT },
1015e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_THROTTLE",   PERF_RECORD_THROTTLE },
1016e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
1017e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_FORK",       PERF_RECORD_FORK },
1018e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_READ",       PERF_RECORD_READ },
1019e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ "RECORD_SAMPLE",     PERF_RECORD_SAMPLE },
1020e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .name = NULL, },
1021e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
1022e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1023e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic PyMethodDef perf__methods[] = {
1024e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	{ .ml_name = NULL, }
1025e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng};
1026e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1027e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen ChengPyMODINIT_FUNC initperf(void)
1028e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1029e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *obj;
1030e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	int i;
1031e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyObject *dict, *module = Py_InitModule("perf", perf__methods);
1032e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1033e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (module == NULL ||
1034e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pyrf_event__setup_types() < 0 ||
1035e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pyrf_evlist__setup_types() < 0 ||
1036e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pyrf_evsel__setup_types() < 0 ||
1037e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pyrf_thread_map__setup_types() < 0 ||
1038e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	    pyrf_cpu_map__setup_types() < 0)
1039e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		return;
1040e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1041e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	page_size = sysconf(_SC_PAGE_SIZE);
1042e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1043e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(&pyrf_evlist__type);
1044e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
1045e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1046e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(&pyrf_evsel__type);
1047e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
1048e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1049e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(&pyrf_thread_map__type);
1050e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
1051e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1052e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	Py_INCREF(&pyrf_cpu_map__type);
1053e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
1054e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1055e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	dict = PyModule_GetDict(module);
1056e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (dict == NULL)
1057e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		goto error;
1058e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1059e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	for (i = 0; perf__constants[i].name != NULL; i++) {
1060e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		obj = PyInt_FromLong(perf__constants[i].value);
1061e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		if (obj == NULL)
1062e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng			goto error;
1063e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyDict_SetItemString(dict, perf__constants[i].name, obj);
1064e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		Py_DECREF(obj);
1065e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	}
1066e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1067e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengerror:
1068e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng	if (PyErr_Occurred())
1069e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
1070e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1071e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng
1072e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/*
1073e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Dummy, to avoid dragging all the test_attr infrastructure in the python
1074e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * binding.
1075e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */
1076e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid test_attr__open(struct perf_event_attr *attr, pid_t pid, int cpu,
1077e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng                     int fd, int group_fd, unsigned long flags)
1078e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{
1079e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng}
1080