xref: /kernel/linux/linux-6.6/tools/perf/util/python.c (revision 62306a36)
162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci#include <Python.h>
362306a36Sopenharmony_ci#include <structmember.h>
462306a36Sopenharmony_ci#include <inttypes.h>
562306a36Sopenharmony_ci#include <poll.h>
662306a36Sopenharmony_ci#include <linux/err.h>
762306a36Sopenharmony_ci#include <perf/cpumap.h>
862306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
962306a36Sopenharmony_ci#include <traceevent/event-parse.h>
1062306a36Sopenharmony_ci#endif
1162306a36Sopenharmony_ci#include <perf/mmap.h>
1262306a36Sopenharmony_ci#include "evlist.h"
1362306a36Sopenharmony_ci#include "callchain.h"
1462306a36Sopenharmony_ci#include "evsel.h"
1562306a36Sopenharmony_ci#include "event.h"
1662306a36Sopenharmony_ci#include "print_binary.h"
1762306a36Sopenharmony_ci#include "thread_map.h"
1862306a36Sopenharmony_ci#include "trace-event.h"
1962306a36Sopenharmony_ci#include "mmap.h"
2062306a36Sopenharmony_ci#include "stat.h"
2162306a36Sopenharmony_ci#include "metricgroup.h"
2262306a36Sopenharmony_ci#include "util/bpf-filter.h"
2362306a36Sopenharmony_ci#include "util/env.h"
2462306a36Sopenharmony_ci#include "util/pmu.h"
2562306a36Sopenharmony_ci#include "util/pmus.h"
2662306a36Sopenharmony_ci#include <internal/lib.h>
2762306a36Sopenharmony_ci#include "util.h"
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
3062306a36Sopenharmony_ci#define _PyUnicode_FromString(arg) \
3162306a36Sopenharmony_ci  PyString_FromString(arg)
3262306a36Sopenharmony_ci#define _PyUnicode_AsString(arg) \
3362306a36Sopenharmony_ci  PyString_AsString(arg)
3462306a36Sopenharmony_ci#define _PyUnicode_FromFormat(...) \
3562306a36Sopenharmony_ci  PyString_FromFormat(__VA_ARGS__)
3662306a36Sopenharmony_ci#define _PyLong_FromLong(arg) \
3762306a36Sopenharmony_ci  PyInt_FromLong(arg)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#else
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci#define _PyUnicode_FromString(arg) \
4262306a36Sopenharmony_ci  PyUnicode_FromString(arg)
4362306a36Sopenharmony_ci#define _PyUnicode_FromFormat(...) \
4462306a36Sopenharmony_ci  PyUnicode_FromFormat(__VA_ARGS__)
4562306a36Sopenharmony_ci#define _PyLong_FromLong(arg) \
4662306a36Sopenharmony_ci  PyLong_FromLong(arg)
4762306a36Sopenharmony_ci#endif
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci#ifndef Py_TYPE
5062306a36Sopenharmony_ci#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
5162306a36Sopenharmony_ci#endif
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/*
5462306a36Sopenharmony_ci * Avoid bringing in event parsing.
5562306a36Sopenharmony_ci */
5662306a36Sopenharmony_ciint parse_event(struct evlist *evlist __maybe_unused, const char *str __maybe_unused)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	return 0;
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/*
6262306a36Sopenharmony_ci * Provide these two so that we don't have to link against callchain.c and
6362306a36Sopenharmony_ci * start dragging hist.c, etc.
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_cistruct callchain_param callchain_param;
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ciint parse_callchain_record(const char *arg __maybe_unused,
6862306a36Sopenharmony_ci			   struct callchain_param *param __maybe_unused)
6962306a36Sopenharmony_ci{
7062306a36Sopenharmony_ci	return 0;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/*
7462306a36Sopenharmony_ci * Add these not to drag util/env.c
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_cistruct perf_env perf_env;
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ciconst char *perf_env__cpuid(struct perf_env *env __maybe_unused)
7962306a36Sopenharmony_ci{
8062306a36Sopenharmony_ci	return NULL;
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci// This one is a bit easier, wouldn't drag too much, but leave it as a stub we need it here
8462306a36Sopenharmony_ciconst char *perf_env__arch(struct perf_env *env __maybe_unused)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	return NULL;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/*
9062306a36Sopenharmony_ci * These ones are needed not to drag the PMU bandwagon, jevents generated
9162306a36Sopenharmony_ci * pmu_sys_event_tables, etc and evsel__find_pmu() is used so far just for
9262306a36Sopenharmony_ci * doing per PMU perf_event_attr.exclude_guest handling, not really needed, so
9362306a36Sopenharmony_ci * far, for the perf python binding known usecases, revisit if this become
9462306a36Sopenharmony_ci * necessary.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_cistruct perf_pmu *evsel__find_pmu(const struct evsel *evsel __maybe_unused)
9762306a36Sopenharmony_ci{
9862306a36Sopenharmony_ci	return NULL;
9962306a36Sopenharmony_ci}
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ciint perf_pmu__scan_file(struct perf_pmu *pmu, const char *name, const char *fmt, ...)
10262306a36Sopenharmony_ci{
10362306a36Sopenharmony_ci	return EOF;
10462306a36Sopenharmony_ci}
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ciint perf_pmus__num_core_pmus(void)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	return 1;
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cibool evsel__is_aux_event(const struct evsel *evsel __maybe_unused)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	return false;
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cibool perf_pmus__supports_extended_type(void)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	return false;
11962306a36Sopenharmony_ci}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci/*
12262306a36Sopenharmony_ci * Add this one here not to drag util/metricgroup.c
12362306a36Sopenharmony_ci */
12462306a36Sopenharmony_ciint metricgroup__copy_metric_events(struct evlist *evlist, struct cgroup *cgrp,
12562306a36Sopenharmony_ci				    struct rblist *new_metric_events,
12662306a36Sopenharmony_ci				    struct rblist *old_metric_events)
12762306a36Sopenharmony_ci{
12862306a36Sopenharmony_ci	return 0;
12962306a36Sopenharmony_ci}
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/*
13262306a36Sopenharmony_ci * Add this one here not to drag util/trace-event-info.c
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_cichar *tracepoint_id_to_name(u64 config)
13562306a36Sopenharmony_ci{
13662306a36Sopenharmony_ci	return NULL;
13762306a36Sopenharmony_ci}
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/*
14062306a36Sopenharmony_ci * XXX: All these evsel destructors need some better mechanism, like a linked
14162306a36Sopenharmony_ci * list of destructors registered when the relevant code indeed is used instead
14262306a36Sopenharmony_ci * of having more and more calls in perf_evsel__delete(). -- acme
14362306a36Sopenharmony_ci *
14462306a36Sopenharmony_ci * For now, add some more:
14562306a36Sopenharmony_ci *
14662306a36Sopenharmony_ci * Not to drag the BPF bandwagon...
14762306a36Sopenharmony_ci */
14862306a36Sopenharmony_civoid bpf_counter__destroy(struct evsel *evsel);
14962306a36Sopenharmony_ciint bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd);
15062306a36Sopenharmony_ciint bpf_counter__disable(struct evsel *evsel);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_civoid bpf_counter__destroy(struct evsel *evsel __maybe_unused)
15362306a36Sopenharmony_ci{
15462306a36Sopenharmony_ci}
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ciint bpf_counter__install_pe(struct evsel *evsel __maybe_unused, int cpu __maybe_unused, int fd __maybe_unused)
15762306a36Sopenharmony_ci{
15862306a36Sopenharmony_ci	return 0;
15962306a36Sopenharmony_ci}
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ciint bpf_counter__disable(struct evsel *evsel __maybe_unused)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	return 0;
16462306a36Sopenharmony_ci}
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci// not to drag util/bpf-filter.c
16762306a36Sopenharmony_ci#ifdef HAVE_BPF_SKEL
16862306a36Sopenharmony_ciint perf_bpf_filter__prepare(struct evsel *evsel __maybe_unused)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	return 0;
17162306a36Sopenharmony_ci}
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ciint perf_bpf_filter__destroy(struct evsel *evsel __maybe_unused)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	return 0;
17662306a36Sopenharmony_ci}
17762306a36Sopenharmony_ci#endif
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci/*
18062306a36Sopenharmony_ci * Support debug printing even though util/debug.c is not linked.  That means
18162306a36Sopenharmony_ci * implementing 'verbose' and 'eprintf'.
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_ciint verbose;
18462306a36Sopenharmony_ciint debug_peo_args;
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ciint eprintf(int level, int var, const char *fmt, ...);
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ciint eprintf(int level, int var, const char *fmt, ...)
18962306a36Sopenharmony_ci{
19062306a36Sopenharmony_ci	va_list args;
19162306a36Sopenharmony_ci	int ret = 0;
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci	if (var >= level) {
19462306a36Sopenharmony_ci		va_start(args, fmt);
19562306a36Sopenharmony_ci		ret = vfprintf(stderr, fmt, args);
19662306a36Sopenharmony_ci		va_end(args);
19762306a36Sopenharmony_ci	}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	return ret;
20062306a36Sopenharmony_ci}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/* Define PyVarObject_HEAD_INIT for python 2.5 */
20362306a36Sopenharmony_ci#ifndef PyVarObject_HEAD_INIT
20462306a36Sopenharmony_ci# define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
20562306a36Sopenharmony_ci#endif
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
20862306a36Sopenharmony_ciPyMODINIT_FUNC initperf(void);
20962306a36Sopenharmony_ci#else
21062306a36Sopenharmony_ciPyMODINIT_FUNC PyInit_perf(void);
21162306a36Sopenharmony_ci#endif
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci#define member_def(type, member, ptype, help) \
21462306a36Sopenharmony_ci	{ #member, ptype, \
21562306a36Sopenharmony_ci	  offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
21662306a36Sopenharmony_ci	  0, help }
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci#define sample_member_def(name, member, ptype, help) \
21962306a36Sopenharmony_ci	{ #name, ptype, \
22062306a36Sopenharmony_ci	  offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
22162306a36Sopenharmony_ci	  0, help }
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_cistruct pyrf_event {
22462306a36Sopenharmony_ci	PyObject_HEAD
22562306a36Sopenharmony_ci	struct evsel *evsel;
22662306a36Sopenharmony_ci	struct perf_sample sample;
22762306a36Sopenharmony_ci	union perf_event   event;
22862306a36Sopenharmony_ci};
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci#define sample_members \
23162306a36Sopenharmony_ci	sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"),			 \
23262306a36Sopenharmony_ci	sample_member_def(sample_pid, pid, T_INT, "event pid"),			 \
23362306a36Sopenharmony_ci	sample_member_def(sample_tid, tid, T_INT, "event tid"),			 \
23462306a36Sopenharmony_ci	sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"),		 \
23562306a36Sopenharmony_ci	sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"),		 \
23662306a36Sopenharmony_ci	sample_member_def(sample_id, id, T_ULONGLONG, "event id"),			 \
23762306a36Sopenharmony_ci	sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
23862306a36Sopenharmony_ci	sample_member_def(sample_period, period, T_ULONGLONG, "event period"),		 \
23962306a36Sopenharmony_ci	sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_cistatic char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic PyMemberDef pyrf_mmap_event__members[] = {
24462306a36Sopenharmony_ci	sample_members
24562306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
24662306a36Sopenharmony_ci	member_def(perf_event_header, misc, T_UINT, "event misc"),
24762306a36Sopenharmony_ci	member_def(perf_record_mmap, pid, T_UINT, "event pid"),
24862306a36Sopenharmony_ci	member_def(perf_record_mmap, tid, T_UINT, "event tid"),
24962306a36Sopenharmony_ci	member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"),
25062306a36Sopenharmony_ci	member_def(perf_record_mmap, len, T_ULONGLONG, "map length"),
25162306a36Sopenharmony_ci	member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"),
25262306a36Sopenharmony_ci	member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"),
25362306a36Sopenharmony_ci	{ .name = NULL, },
25462306a36Sopenharmony_ci};
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_cistatic PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
25762306a36Sopenharmony_ci{
25862306a36Sopenharmony_ci	PyObject *ret;
25962306a36Sopenharmony_ci	char *s;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", "
26262306a36Sopenharmony_ci			 "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", "
26362306a36Sopenharmony_ci			 "filename: %s }",
26462306a36Sopenharmony_ci		     pevent->event.mmap.pid, pevent->event.mmap.tid,
26562306a36Sopenharmony_ci		     pevent->event.mmap.start, pevent->event.mmap.len,
26662306a36Sopenharmony_ci		     pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
26762306a36Sopenharmony_ci		ret = PyErr_NoMemory();
26862306a36Sopenharmony_ci	} else {
26962306a36Sopenharmony_ci		ret = _PyUnicode_FromString(s);
27062306a36Sopenharmony_ci		free(s);
27162306a36Sopenharmony_ci	}
27262306a36Sopenharmony_ci	return ret;
27362306a36Sopenharmony_ci}
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_cistatic PyTypeObject pyrf_mmap_event__type = {
27662306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
27762306a36Sopenharmony_ci	.tp_name	= "perf.mmap_event",
27862306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
27962306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
28062306a36Sopenharmony_ci	.tp_doc		= pyrf_mmap_event__doc,
28162306a36Sopenharmony_ci	.tp_members	= pyrf_mmap_event__members,
28262306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_mmap_event__repr,
28362306a36Sopenharmony_ci};
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_cistatic PyMemberDef pyrf_task_event__members[] = {
28862306a36Sopenharmony_ci	sample_members
28962306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
29062306a36Sopenharmony_ci	member_def(perf_record_fork, pid, T_UINT, "event pid"),
29162306a36Sopenharmony_ci	member_def(perf_record_fork, ppid, T_UINT, "event ppid"),
29262306a36Sopenharmony_ci	member_def(perf_record_fork, tid, T_UINT, "event tid"),
29362306a36Sopenharmony_ci	member_def(perf_record_fork, ptid, T_UINT, "event ptid"),
29462306a36Sopenharmony_ci	member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"),
29562306a36Sopenharmony_ci	{ .name = NULL, },
29662306a36Sopenharmony_ci};
29762306a36Sopenharmony_ci
29862306a36Sopenharmony_cistatic PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
29962306a36Sopenharmony_ci{
30062306a36Sopenharmony_ci	return _PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
30162306a36Sopenharmony_ci				   "ptid: %u, time: %" PRI_lu64 "}",
30262306a36Sopenharmony_ci				   pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
30362306a36Sopenharmony_ci				   pevent->event.fork.pid,
30462306a36Sopenharmony_ci				   pevent->event.fork.ppid,
30562306a36Sopenharmony_ci				   pevent->event.fork.tid,
30662306a36Sopenharmony_ci				   pevent->event.fork.ptid,
30762306a36Sopenharmony_ci				   pevent->event.fork.time);
30862306a36Sopenharmony_ci}
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_cistatic PyTypeObject pyrf_task_event__type = {
31162306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
31262306a36Sopenharmony_ci	.tp_name	= "perf.task_event",
31362306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
31462306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
31562306a36Sopenharmony_ci	.tp_doc		= pyrf_task_event__doc,
31662306a36Sopenharmony_ci	.tp_members	= pyrf_task_event__members,
31762306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_task_event__repr,
31862306a36Sopenharmony_ci};
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_cistatic char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_cistatic PyMemberDef pyrf_comm_event__members[] = {
32362306a36Sopenharmony_ci	sample_members
32462306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
32562306a36Sopenharmony_ci	member_def(perf_record_comm, pid, T_UINT, "event pid"),
32662306a36Sopenharmony_ci	member_def(perf_record_comm, tid, T_UINT, "event tid"),
32762306a36Sopenharmony_ci	member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"),
32862306a36Sopenharmony_ci	{ .name = NULL, },
32962306a36Sopenharmony_ci};
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_cistatic PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
33262306a36Sopenharmony_ci{
33362306a36Sopenharmony_ci	return _PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
33462306a36Sopenharmony_ci				   pevent->event.comm.pid,
33562306a36Sopenharmony_ci				   pevent->event.comm.tid,
33662306a36Sopenharmony_ci				   pevent->event.comm.comm);
33762306a36Sopenharmony_ci}
33862306a36Sopenharmony_ci
33962306a36Sopenharmony_cistatic PyTypeObject pyrf_comm_event__type = {
34062306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
34162306a36Sopenharmony_ci	.tp_name	= "perf.comm_event",
34262306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
34362306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
34462306a36Sopenharmony_ci	.tp_doc		= pyrf_comm_event__doc,
34562306a36Sopenharmony_ci	.tp_members	= pyrf_comm_event__members,
34662306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_comm_event__repr,
34762306a36Sopenharmony_ci};
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_cistatic char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_cistatic PyMemberDef pyrf_throttle_event__members[] = {
35262306a36Sopenharmony_ci	sample_members
35362306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
35462306a36Sopenharmony_ci	member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"),
35562306a36Sopenharmony_ci	member_def(perf_record_throttle, id, T_ULONGLONG, "event id"),
35662306a36Sopenharmony_ci	member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"),
35762306a36Sopenharmony_ci	{ .name = NULL, },
35862306a36Sopenharmony_ci};
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_cistatic PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	struct perf_record_throttle *te = (struct perf_record_throttle *)(&pevent->event.header + 1);
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	return _PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64
36562306a36Sopenharmony_ci				   ", stream_id: %" PRI_lu64 " }",
36662306a36Sopenharmony_ci				   pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
36762306a36Sopenharmony_ci				   te->time, te->id, te->stream_id);
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic PyTypeObject pyrf_throttle_event__type = {
37162306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
37262306a36Sopenharmony_ci	.tp_name	= "perf.throttle_event",
37362306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
37462306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
37562306a36Sopenharmony_ci	.tp_doc		= pyrf_throttle_event__doc,
37662306a36Sopenharmony_ci	.tp_members	= pyrf_throttle_event__members,
37762306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_throttle_event__repr,
37862306a36Sopenharmony_ci};
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_cistatic char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistatic PyMemberDef pyrf_lost_event__members[] = {
38362306a36Sopenharmony_ci	sample_members
38462306a36Sopenharmony_ci	member_def(perf_record_lost, id, T_ULONGLONG, "event id"),
38562306a36Sopenharmony_ci	member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"),
38662306a36Sopenharmony_ci	{ .name = NULL, },
38762306a36Sopenharmony_ci};
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_cistatic PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
39062306a36Sopenharmony_ci{
39162306a36Sopenharmony_ci	PyObject *ret;
39262306a36Sopenharmony_ci	char *s;
39362306a36Sopenharmony_ci
39462306a36Sopenharmony_ci	if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", "
39562306a36Sopenharmony_ci			 "lost: %#" PRI_lx64 " }",
39662306a36Sopenharmony_ci		     pevent->event.lost.id, pevent->event.lost.lost) < 0) {
39762306a36Sopenharmony_ci		ret = PyErr_NoMemory();
39862306a36Sopenharmony_ci	} else {
39962306a36Sopenharmony_ci		ret = _PyUnicode_FromString(s);
40062306a36Sopenharmony_ci		free(s);
40162306a36Sopenharmony_ci	}
40262306a36Sopenharmony_ci	return ret;
40362306a36Sopenharmony_ci}
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_cistatic PyTypeObject pyrf_lost_event__type = {
40662306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
40762306a36Sopenharmony_ci	.tp_name	= "perf.lost_event",
40862306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
40962306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
41062306a36Sopenharmony_ci	.tp_doc		= pyrf_lost_event__doc,
41162306a36Sopenharmony_ci	.tp_members	= pyrf_lost_event__members,
41262306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_lost_event__repr,
41362306a36Sopenharmony_ci};
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_cistatic char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_cistatic PyMemberDef pyrf_read_event__members[] = {
41862306a36Sopenharmony_ci	sample_members
41962306a36Sopenharmony_ci	member_def(perf_record_read, pid, T_UINT, "event pid"),
42062306a36Sopenharmony_ci	member_def(perf_record_read, tid, T_UINT, "event tid"),
42162306a36Sopenharmony_ci	{ .name = NULL, },
42262306a36Sopenharmony_ci};
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_cistatic PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
42562306a36Sopenharmony_ci{
42662306a36Sopenharmony_ci	return _PyUnicode_FromFormat("{ type: read, pid: %u, tid: %u }",
42762306a36Sopenharmony_ci				   pevent->event.read.pid,
42862306a36Sopenharmony_ci				   pevent->event.read.tid);
42962306a36Sopenharmony_ci	/*
43062306a36Sopenharmony_ci 	 * FIXME: return the array of read values,
43162306a36Sopenharmony_ci 	 * making this method useful ;-)
43262306a36Sopenharmony_ci 	 */
43362306a36Sopenharmony_ci}
43462306a36Sopenharmony_ci
43562306a36Sopenharmony_cistatic PyTypeObject pyrf_read_event__type = {
43662306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
43762306a36Sopenharmony_ci	.tp_name	= "perf.read_event",
43862306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
43962306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
44062306a36Sopenharmony_ci	.tp_doc		= pyrf_read_event__doc,
44162306a36Sopenharmony_ci	.tp_members	= pyrf_read_event__members,
44262306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_read_event__repr,
44362306a36Sopenharmony_ci};
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_cistatic char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_cistatic PyMemberDef pyrf_sample_event__members[] = {
44862306a36Sopenharmony_ci	sample_members
44962306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
45062306a36Sopenharmony_ci	{ .name = NULL, },
45162306a36Sopenharmony_ci};
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_cistatic PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	PyObject *ret;
45662306a36Sopenharmony_ci	char *s;
45762306a36Sopenharmony_ci
45862306a36Sopenharmony_ci	if (asprintf(&s, "{ type: sample }") < 0) {
45962306a36Sopenharmony_ci		ret = PyErr_NoMemory();
46062306a36Sopenharmony_ci	} else {
46162306a36Sopenharmony_ci		ret = _PyUnicode_FromString(s);
46262306a36Sopenharmony_ci		free(s);
46362306a36Sopenharmony_ci	}
46462306a36Sopenharmony_ci	return ret;
46562306a36Sopenharmony_ci}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
46862306a36Sopenharmony_cistatic bool is_tracepoint(struct pyrf_event *pevent)
46962306a36Sopenharmony_ci{
47062306a36Sopenharmony_ci	return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
47162306a36Sopenharmony_ci}
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_cistatic PyObject*
47462306a36Sopenharmony_citracepoint_field(struct pyrf_event *pe, struct tep_format_field *field)
47562306a36Sopenharmony_ci{
47662306a36Sopenharmony_ci	struct tep_handle *pevent = field->event->tep;
47762306a36Sopenharmony_ci	void *data = pe->sample.raw_data;
47862306a36Sopenharmony_ci	PyObject *ret = NULL;
47962306a36Sopenharmony_ci	unsigned long long val;
48062306a36Sopenharmony_ci	unsigned int offset, len;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	if (field->flags & TEP_FIELD_IS_ARRAY) {
48362306a36Sopenharmony_ci		offset = field->offset;
48462306a36Sopenharmony_ci		len    = field->size;
48562306a36Sopenharmony_ci		if (field->flags & TEP_FIELD_IS_DYNAMIC) {
48662306a36Sopenharmony_ci			val     = tep_read_number(pevent, data + offset, len);
48762306a36Sopenharmony_ci			offset  = val;
48862306a36Sopenharmony_ci			len     = offset >> 16;
48962306a36Sopenharmony_ci			offset &= 0xffff;
49062306a36Sopenharmony_ci			if (tep_field_is_relative(field->flags))
49162306a36Sopenharmony_ci				offset += field->offset + field->size;
49262306a36Sopenharmony_ci		}
49362306a36Sopenharmony_ci		if (field->flags & TEP_FIELD_IS_STRING &&
49462306a36Sopenharmony_ci		    is_printable_array(data + offset, len)) {
49562306a36Sopenharmony_ci			ret = _PyUnicode_FromString((char *)data + offset);
49662306a36Sopenharmony_ci		} else {
49762306a36Sopenharmony_ci			ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
49862306a36Sopenharmony_ci			field->flags &= ~TEP_FIELD_IS_STRING;
49962306a36Sopenharmony_ci		}
50062306a36Sopenharmony_ci	} else {
50162306a36Sopenharmony_ci		val = tep_read_number(pevent, data + field->offset,
50262306a36Sopenharmony_ci				      field->size);
50362306a36Sopenharmony_ci		if (field->flags & TEP_FIELD_IS_POINTER)
50462306a36Sopenharmony_ci			ret = PyLong_FromUnsignedLong((unsigned long) val);
50562306a36Sopenharmony_ci		else if (field->flags & TEP_FIELD_IS_SIGNED)
50662306a36Sopenharmony_ci			ret = PyLong_FromLong((long) val);
50762306a36Sopenharmony_ci		else
50862306a36Sopenharmony_ci			ret = PyLong_FromUnsignedLong((unsigned long) val);
50962306a36Sopenharmony_ci	}
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	return ret;
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic PyObject*
51562306a36Sopenharmony_ciget_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	const char *str = _PyUnicode_AsString(PyObject_Str(attr_name));
51862306a36Sopenharmony_ci	struct evsel *evsel = pevent->evsel;
51962306a36Sopenharmony_ci	struct tep_format_field *field;
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	if (!evsel->tp_format) {
52262306a36Sopenharmony_ci		struct tep_event *tp_format;
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci		tp_format = trace_event__tp_format_id(evsel->core.attr.config);
52562306a36Sopenharmony_ci		if (IS_ERR_OR_NULL(tp_format))
52662306a36Sopenharmony_ci			return NULL;
52762306a36Sopenharmony_ci
52862306a36Sopenharmony_ci		evsel->tp_format = tp_format;
52962306a36Sopenharmony_ci	}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	field = tep_find_any_field(evsel->tp_format, str);
53262306a36Sopenharmony_ci	if (!field)
53362306a36Sopenharmony_ci		return NULL;
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	return tracepoint_field(pevent, field);
53662306a36Sopenharmony_ci}
53762306a36Sopenharmony_ci#endif /* HAVE_LIBTRACEEVENT */
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_cistatic PyObject*
54062306a36Sopenharmony_cipyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
54162306a36Sopenharmony_ci{
54262306a36Sopenharmony_ci	PyObject *obj = NULL;
54362306a36Sopenharmony_ci
54462306a36Sopenharmony_ci#ifdef HAVE_LIBTRACEEVENT
54562306a36Sopenharmony_ci	if (is_tracepoint(pevent))
54662306a36Sopenharmony_ci		obj = get_tracepoint_field(pevent, attr_name);
54762306a36Sopenharmony_ci#endif
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
55062306a36Sopenharmony_ci}
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_cistatic PyTypeObject pyrf_sample_event__type = {
55362306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
55462306a36Sopenharmony_ci	.tp_name	= "perf.sample_event",
55562306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
55662306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
55762306a36Sopenharmony_ci	.tp_doc		= pyrf_sample_event__doc,
55862306a36Sopenharmony_ci	.tp_members	= pyrf_sample_event__members,
55962306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_sample_event__repr,
56062306a36Sopenharmony_ci	.tp_getattro	= (getattrofunc) pyrf_sample_event__getattro,
56162306a36Sopenharmony_ci};
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_cistatic char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_cistatic PyMemberDef pyrf_context_switch_event__members[] = {
56662306a36Sopenharmony_ci	sample_members
56762306a36Sopenharmony_ci	member_def(perf_event_header, type, T_UINT, "event type"),
56862306a36Sopenharmony_ci	member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"),
56962306a36Sopenharmony_ci	member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"),
57062306a36Sopenharmony_ci	{ .name = NULL, },
57162306a36Sopenharmony_ci};
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_cistatic PyObject *pyrf_context_switch_event__repr(struct pyrf_event *pevent)
57462306a36Sopenharmony_ci{
57562306a36Sopenharmony_ci	PyObject *ret;
57662306a36Sopenharmony_ci	char *s;
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_ci	if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
57962306a36Sopenharmony_ci		     pevent->event.context_switch.next_prev_pid,
58062306a36Sopenharmony_ci		     pevent->event.context_switch.next_prev_tid,
58162306a36Sopenharmony_ci		     !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
58262306a36Sopenharmony_ci		ret = PyErr_NoMemory();
58362306a36Sopenharmony_ci	} else {
58462306a36Sopenharmony_ci		ret = _PyUnicode_FromString(s);
58562306a36Sopenharmony_ci		free(s);
58662306a36Sopenharmony_ci	}
58762306a36Sopenharmony_ci	return ret;
58862306a36Sopenharmony_ci}
58962306a36Sopenharmony_ci
59062306a36Sopenharmony_cistatic PyTypeObject pyrf_context_switch_event__type = {
59162306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
59262306a36Sopenharmony_ci	.tp_name	= "perf.context_switch_event",
59362306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_event),
59462306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
59562306a36Sopenharmony_ci	.tp_doc		= pyrf_context_switch_event__doc,
59662306a36Sopenharmony_ci	.tp_members	= pyrf_context_switch_event__members,
59762306a36Sopenharmony_ci	.tp_repr	= (reprfunc)pyrf_context_switch_event__repr,
59862306a36Sopenharmony_ci};
59962306a36Sopenharmony_ci
60062306a36Sopenharmony_cistatic int pyrf_event__setup_types(void)
60162306a36Sopenharmony_ci{
60262306a36Sopenharmony_ci	int err;
60362306a36Sopenharmony_ci	pyrf_mmap_event__type.tp_new =
60462306a36Sopenharmony_ci	pyrf_task_event__type.tp_new =
60562306a36Sopenharmony_ci	pyrf_comm_event__type.tp_new =
60662306a36Sopenharmony_ci	pyrf_lost_event__type.tp_new =
60762306a36Sopenharmony_ci	pyrf_read_event__type.tp_new =
60862306a36Sopenharmony_ci	pyrf_sample_event__type.tp_new =
60962306a36Sopenharmony_ci	pyrf_context_switch_event__type.tp_new =
61062306a36Sopenharmony_ci	pyrf_throttle_event__type.tp_new = PyType_GenericNew;
61162306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_mmap_event__type);
61262306a36Sopenharmony_ci	if (err < 0)
61362306a36Sopenharmony_ci		goto out;
61462306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_lost_event__type);
61562306a36Sopenharmony_ci	if (err < 0)
61662306a36Sopenharmony_ci		goto out;
61762306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_task_event__type);
61862306a36Sopenharmony_ci	if (err < 0)
61962306a36Sopenharmony_ci		goto out;
62062306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_comm_event__type);
62162306a36Sopenharmony_ci	if (err < 0)
62262306a36Sopenharmony_ci		goto out;
62362306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_throttle_event__type);
62462306a36Sopenharmony_ci	if (err < 0)
62562306a36Sopenharmony_ci		goto out;
62662306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_read_event__type);
62762306a36Sopenharmony_ci	if (err < 0)
62862306a36Sopenharmony_ci		goto out;
62962306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_sample_event__type);
63062306a36Sopenharmony_ci	if (err < 0)
63162306a36Sopenharmony_ci		goto out;
63262306a36Sopenharmony_ci	err = PyType_Ready(&pyrf_context_switch_event__type);
63362306a36Sopenharmony_ci	if (err < 0)
63462306a36Sopenharmony_ci		goto out;
63562306a36Sopenharmony_ciout:
63662306a36Sopenharmony_ci	return err;
63762306a36Sopenharmony_ci}
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_cistatic PyTypeObject *pyrf_event__type[] = {
64062306a36Sopenharmony_ci	[PERF_RECORD_MMAP]	 = &pyrf_mmap_event__type,
64162306a36Sopenharmony_ci	[PERF_RECORD_LOST]	 = &pyrf_lost_event__type,
64262306a36Sopenharmony_ci	[PERF_RECORD_COMM]	 = &pyrf_comm_event__type,
64362306a36Sopenharmony_ci	[PERF_RECORD_EXIT]	 = &pyrf_task_event__type,
64462306a36Sopenharmony_ci	[PERF_RECORD_THROTTLE]	 = &pyrf_throttle_event__type,
64562306a36Sopenharmony_ci	[PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
64662306a36Sopenharmony_ci	[PERF_RECORD_FORK]	 = &pyrf_task_event__type,
64762306a36Sopenharmony_ci	[PERF_RECORD_READ]	 = &pyrf_read_event__type,
64862306a36Sopenharmony_ci	[PERF_RECORD_SAMPLE]	 = &pyrf_sample_event__type,
64962306a36Sopenharmony_ci	[PERF_RECORD_SWITCH]	 = &pyrf_context_switch_event__type,
65062306a36Sopenharmony_ci	[PERF_RECORD_SWITCH_CPU_WIDE]  = &pyrf_context_switch_event__type,
65162306a36Sopenharmony_ci};
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_cistatic PyObject *pyrf_event__new(union perf_event *event)
65462306a36Sopenharmony_ci{
65562306a36Sopenharmony_ci	struct pyrf_event *pevent;
65662306a36Sopenharmony_ci	PyTypeObject *ptype;
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	if ((event->header.type < PERF_RECORD_MMAP ||
65962306a36Sopenharmony_ci	     event->header.type > PERF_RECORD_SAMPLE) &&
66062306a36Sopenharmony_ci	    !(event->header.type == PERF_RECORD_SWITCH ||
66162306a36Sopenharmony_ci	      event->header.type == PERF_RECORD_SWITCH_CPU_WIDE))
66262306a36Sopenharmony_ci		return NULL;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	ptype = pyrf_event__type[event->header.type];
66562306a36Sopenharmony_ci	pevent = PyObject_New(struct pyrf_event, ptype);
66662306a36Sopenharmony_ci	if (pevent != NULL)
66762306a36Sopenharmony_ci		memcpy(&pevent->event, event, event->header.size);
66862306a36Sopenharmony_ci	return (PyObject *)pevent;
66962306a36Sopenharmony_ci}
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_cistruct pyrf_cpu_map {
67262306a36Sopenharmony_ci	PyObject_HEAD
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	struct perf_cpu_map *cpus;
67562306a36Sopenharmony_ci};
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_cistatic int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
67862306a36Sopenharmony_ci			      PyObject *args, PyObject *kwargs)
67962306a36Sopenharmony_ci{
68062306a36Sopenharmony_ci	static char *kwlist[] = { "cpustr", NULL };
68162306a36Sopenharmony_ci	char *cpustr = NULL;
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
68462306a36Sopenharmony_ci					 kwlist, &cpustr))
68562306a36Sopenharmony_ci		return -1;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	pcpus->cpus = perf_cpu_map__new(cpustr);
68862306a36Sopenharmony_ci	if (pcpus->cpus == NULL)
68962306a36Sopenharmony_ci		return -1;
69062306a36Sopenharmony_ci	return 0;
69162306a36Sopenharmony_ci}
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_cistatic void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
69462306a36Sopenharmony_ci{
69562306a36Sopenharmony_ci	perf_cpu_map__put(pcpus->cpus);
69662306a36Sopenharmony_ci	Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
69762306a36Sopenharmony_ci}
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_cistatic Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
70062306a36Sopenharmony_ci{
70162306a36Sopenharmony_ci	struct pyrf_cpu_map *pcpus = (void *)obj;
70262306a36Sopenharmony_ci
70362306a36Sopenharmony_ci	return perf_cpu_map__nr(pcpus->cpus);
70462306a36Sopenharmony_ci}
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_cistatic PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
70762306a36Sopenharmony_ci{
70862306a36Sopenharmony_ci	struct pyrf_cpu_map *pcpus = (void *)obj;
70962306a36Sopenharmony_ci
71062306a36Sopenharmony_ci	if (i >= perf_cpu_map__nr(pcpus->cpus))
71162306a36Sopenharmony_ci		return NULL;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	return Py_BuildValue("i", perf_cpu_map__cpu(pcpus->cpus, i).cpu);
71462306a36Sopenharmony_ci}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_cistatic PySequenceMethods pyrf_cpu_map__sequence_methods = {
71762306a36Sopenharmony_ci	.sq_length = pyrf_cpu_map__length,
71862306a36Sopenharmony_ci	.sq_item   = pyrf_cpu_map__item,
71962306a36Sopenharmony_ci};
72062306a36Sopenharmony_ci
72162306a36Sopenharmony_cistatic char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
72262306a36Sopenharmony_ci
72362306a36Sopenharmony_cistatic PyTypeObject pyrf_cpu_map__type = {
72462306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
72562306a36Sopenharmony_ci	.tp_name	= "perf.cpu_map",
72662306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_cpu_map),
72762306a36Sopenharmony_ci	.tp_dealloc	= (destructor)pyrf_cpu_map__delete,
72862306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
72962306a36Sopenharmony_ci	.tp_doc		= pyrf_cpu_map__doc,
73062306a36Sopenharmony_ci	.tp_as_sequence	= &pyrf_cpu_map__sequence_methods,
73162306a36Sopenharmony_ci	.tp_init	= (initproc)pyrf_cpu_map__init,
73262306a36Sopenharmony_ci};
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_cistatic int pyrf_cpu_map__setup_types(void)
73562306a36Sopenharmony_ci{
73662306a36Sopenharmony_ci	pyrf_cpu_map__type.tp_new = PyType_GenericNew;
73762306a36Sopenharmony_ci	return PyType_Ready(&pyrf_cpu_map__type);
73862306a36Sopenharmony_ci}
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_cistruct pyrf_thread_map {
74162306a36Sopenharmony_ci	PyObject_HEAD
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_ci	struct perf_thread_map *threads;
74462306a36Sopenharmony_ci};
74562306a36Sopenharmony_ci
74662306a36Sopenharmony_cistatic int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
74762306a36Sopenharmony_ci				 PyObject *args, PyObject *kwargs)
74862306a36Sopenharmony_ci{
74962306a36Sopenharmony_ci	static char *kwlist[] = { "pid", "tid", "uid", NULL };
75062306a36Sopenharmony_ci	int pid = -1, tid = -1, uid = UINT_MAX;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iii",
75362306a36Sopenharmony_ci					 kwlist, &pid, &tid, &uid))
75462306a36Sopenharmony_ci		return -1;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	pthreads->threads = thread_map__new(pid, tid, uid);
75762306a36Sopenharmony_ci	if (pthreads->threads == NULL)
75862306a36Sopenharmony_ci		return -1;
75962306a36Sopenharmony_ci	return 0;
76062306a36Sopenharmony_ci}
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_cistatic void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
76362306a36Sopenharmony_ci{
76462306a36Sopenharmony_ci	perf_thread_map__put(pthreads->threads);
76562306a36Sopenharmony_ci	Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
76662306a36Sopenharmony_ci}
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_cistatic Py_ssize_t pyrf_thread_map__length(PyObject *obj)
76962306a36Sopenharmony_ci{
77062306a36Sopenharmony_ci	struct pyrf_thread_map *pthreads = (void *)obj;
77162306a36Sopenharmony_ci
77262306a36Sopenharmony_ci	return perf_thread_map__nr(pthreads->threads);
77362306a36Sopenharmony_ci}
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_cistatic PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
77662306a36Sopenharmony_ci{
77762306a36Sopenharmony_ci	struct pyrf_thread_map *pthreads = (void *)obj;
77862306a36Sopenharmony_ci
77962306a36Sopenharmony_ci	if (i >= perf_thread_map__nr(pthreads->threads))
78062306a36Sopenharmony_ci		return NULL;
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	return Py_BuildValue("i", perf_thread_map__pid(pthreads->threads, i));
78362306a36Sopenharmony_ci}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_cistatic PySequenceMethods pyrf_thread_map__sequence_methods = {
78662306a36Sopenharmony_ci	.sq_length = pyrf_thread_map__length,
78762306a36Sopenharmony_ci	.sq_item   = pyrf_thread_map__item,
78862306a36Sopenharmony_ci};
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_cistatic char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_cistatic PyTypeObject pyrf_thread_map__type = {
79362306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
79462306a36Sopenharmony_ci	.tp_name	= "perf.thread_map",
79562306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_thread_map),
79662306a36Sopenharmony_ci	.tp_dealloc	= (destructor)pyrf_thread_map__delete,
79762306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
79862306a36Sopenharmony_ci	.tp_doc		= pyrf_thread_map__doc,
79962306a36Sopenharmony_ci	.tp_as_sequence	= &pyrf_thread_map__sequence_methods,
80062306a36Sopenharmony_ci	.tp_init	= (initproc)pyrf_thread_map__init,
80162306a36Sopenharmony_ci};
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_cistatic int pyrf_thread_map__setup_types(void)
80462306a36Sopenharmony_ci{
80562306a36Sopenharmony_ci	pyrf_thread_map__type.tp_new = PyType_GenericNew;
80662306a36Sopenharmony_ci	return PyType_Ready(&pyrf_thread_map__type);
80762306a36Sopenharmony_ci}
80862306a36Sopenharmony_ci
80962306a36Sopenharmony_cistruct pyrf_evsel {
81062306a36Sopenharmony_ci	PyObject_HEAD
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	struct evsel evsel;
81362306a36Sopenharmony_ci};
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_cistatic int pyrf_evsel__init(struct pyrf_evsel *pevsel,
81662306a36Sopenharmony_ci			    PyObject *args, PyObject *kwargs)
81762306a36Sopenharmony_ci{
81862306a36Sopenharmony_ci	struct perf_event_attr attr = {
81962306a36Sopenharmony_ci		.type = PERF_TYPE_HARDWARE,
82062306a36Sopenharmony_ci		.config = PERF_COUNT_HW_CPU_CYCLES,
82162306a36Sopenharmony_ci		.sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
82262306a36Sopenharmony_ci	};
82362306a36Sopenharmony_ci	static char *kwlist[] = {
82462306a36Sopenharmony_ci		"type",
82562306a36Sopenharmony_ci		"config",
82662306a36Sopenharmony_ci		"sample_freq",
82762306a36Sopenharmony_ci		"sample_period",
82862306a36Sopenharmony_ci		"sample_type",
82962306a36Sopenharmony_ci		"read_format",
83062306a36Sopenharmony_ci		"disabled",
83162306a36Sopenharmony_ci		"inherit",
83262306a36Sopenharmony_ci		"pinned",
83362306a36Sopenharmony_ci		"exclusive",
83462306a36Sopenharmony_ci		"exclude_user",
83562306a36Sopenharmony_ci		"exclude_kernel",
83662306a36Sopenharmony_ci		"exclude_hv",
83762306a36Sopenharmony_ci		"exclude_idle",
83862306a36Sopenharmony_ci		"mmap",
83962306a36Sopenharmony_ci		"context_switch",
84062306a36Sopenharmony_ci		"comm",
84162306a36Sopenharmony_ci		"freq",
84262306a36Sopenharmony_ci		"inherit_stat",
84362306a36Sopenharmony_ci		"enable_on_exec",
84462306a36Sopenharmony_ci		"task",
84562306a36Sopenharmony_ci		"watermark",
84662306a36Sopenharmony_ci		"precise_ip",
84762306a36Sopenharmony_ci		"mmap_data",
84862306a36Sopenharmony_ci		"sample_id_all",
84962306a36Sopenharmony_ci		"wakeup_events",
85062306a36Sopenharmony_ci		"bp_type",
85162306a36Sopenharmony_ci		"bp_addr",
85262306a36Sopenharmony_ci		"bp_len",
85362306a36Sopenharmony_ci		 NULL
85462306a36Sopenharmony_ci	};
85562306a36Sopenharmony_ci	u64 sample_period = 0;
85662306a36Sopenharmony_ci	u32 disabled = 0,
85762306a36Sopenharmony_ci	    inherit = 0,
85862306a36Sopenharmony_ci	    pinned = 0,
85962306a36Sopenharmony_ci	    exclusive = 0,
86062306a36Sopenharmony_ci	    exclude_user = 0,
86162306a36Sopenharmony_ci	    exclude_kernel = 0,
86262306a36Sopenharmony_ci	    exclude_hv = 0,
86362306a36Sopenharmony_ci	    exclude_idle = 0,
86462306a36Sopenharmony_ci	    mmap = 0,
86562306a36Sopenharmony_ci	    context_switch = 0,
86662306a36Sopenharmony_ci	    comm = 0,
86762306a36Sopenharmony_ci	    freq = 1,
86862306a36Sopenharmony_ci	    inherit_stat = 0,
86962306a36Sopenharmony_ci	    enable_on_exec = 0,
87062306a36Sopenharmony_ci	    task = 0,
87162306a36Sopenharmony_ci	    watermark = 0,
87262306a36Sopenharmony_ci	    precise_ip = 0,
87362306a36Sopenharmony_ci	    mmap_data = 0,
87462306a36Sopenharmony_ci	    sample_id_all = 1;
87562306a36Sopenharmony_ci	int idx = 0;
87662306a36Sopenharmony_ci
87762306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs,
87862306a36Sopenharmony_ci					 "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
87962306a36Sopenharmony_ci					 &attr.type, &attr.config, &attr.sample_freq,
88062306a36Sopenharmony_ci					 &sample_period, &attr.sample_type,
88162306a36Sopenharmony_ci					 &attr.read_format, &disabled, &inherit,
88262306a36Sopenharmony_ci					 &pinned, &exclusive, &exclude_user,
88362306a36Sopenharmony_ci					 &exclude_kernel, &exclude_hv, &exclude_idle,
88462306a36Sopenharmony_ci					 &mmap, &context_switch, &comm, &freq, &inherit_stat,
88562306a36Sopenharmony_ci					 &enable_on_exec, &task, &watermark,
88662306a36Sopenharmony_ci					 &precise_ip, &mmap_data, &sample_id_all,
88762306a36Sopenharmony_ci					 &attr.wakeup_events, &attr.bp_type,
88862306a36Sopenharmony_ci					 &attr.bp_addr, &attr.bp_len, &idx))
88962306a36Sopenharmony_ci		return -1;
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_ci	/* union... */
89262306a36Sopenharmony_ci	if (sample_period != 0) {
89362306a36Sopenharmony_ci		if (attr.sample_freq != 0)
89462306a36Sopenharmony_ci			return -1; /* FIXME: throw right exception */
89562306a36Sopenharmony_ci		attr.sample_period = sample_period;
89662306a36Sopenharmony_ci	}
89762306a36Sopenharmony_ci
89862306a36Sopenharmony_ci	/* Bitfields */
89962306a36Sopenharmony_ci	attr.disabled	    = disabled;
90062306a36Sopenharmony_ci	attr.inherit	    = inherit;
90162306a36Sopenharmony_ci	attr.pinned	    = pinned;
90262306a36Sopenharmony_ci	attr.exclusive	    = exclusive;
90362306a36Sopenharmony_ci	attr.exclude_user   = exclude_user;
90462306a36Sopenharmony_ci	attr.exclude_kernel = exclude_kernel;
90562306a36Sopenharmony_ci	attr.exclude_hv	    = exclude_hv;
90662306a36Sopenharmony_ci	attr.exclude_idle   = exclude_idle;
90762306a36Sopenharmony_ci	attr.mmap	    = mmap;
90862306a36Sopenharmony_ci	attr.context_switch = context_switch;
90962306a36Sopenharmony_ci	attr.comm	    = comm;
91062306a36Sopenharmony_ci	attr.freq	    = freq;
91162306a36Sopenharmony_ci	attr.inherit_stat   = inherit_stat;
91262306a36Sopenharmony_ci	attr.enable_on_exec = enable_on_exec;
91362306a36Sopenharmony_ci	attr.task	    = task;
91462306a36Sopenharmony_ci	attr.watermark	    = watermark;
91562306a36Sopenharmony_ci	attr.precise_ip	    = precise_ip;
91662306a36Sopenharmony_ci	attr.mmap_data	    = mmap_data;
91762306a36Sopenharmony_ci	attr.sample_id_all  = sample_id_all;
91862306a36Sopenharmony_ci	attr.size	    = sizeof(attr);
91962306a36Sopenharmony_ci
92062306a36Sopenharmony_ci	evsel__init(&pevsel->evsel, &attr, idx);
92162306a36Sopenharmony_ci	return 0;
92262306a36Sopenharmony_ci}
92362306a36Sopenharmony_ci
92462306a36Sopenharmony_cistatic void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
92562306a36Sopenharmony_ci{
92662306a36Sopenharmony_ci	evsel__exit(&pevsel->evsel);
92762306a36Sopenharmony_ci	Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
92862306a36Sopenharmony_ci}
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_cistatic PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
93162306a36Sopenharmony_ci				  PyObject *args, PyObject *kwargs)
93262306a36Sopenharmony_ci{
93362306a36Sopenharmony_ci	struct evsel *evsel = &pevsel->evsel;
93462306a36Sopenharmony_ci	struct perf_cpu_map *cpus = NULL;
93562306a36Sopenharmony_ci	struct perf_thread_map *threads = NULL;
93662306a36Sopenharmony_ci	PyObject *pcpus = NULL, *pthreads = NULL;
93762306a36Sopenharmony_ci	int group = 0, inherit = 0;
93862306a36Sopenharmony_ci	static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
93962306a36Sopenharmony_ci
94062306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
94162306a36Sopenharmony_ci					 &pcpus, &pthreads, &group, &inherit))
94262306a36Sopenharmony_ci		return NULL;
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	if (pthreads != NULL)
94562306a36Sopenharmony_ci		threads = ((struct pyrf_thread_map *)pthreads)->threads;
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci	if (pcpus != NULL)
94862306a36Sopenharmony_ci		cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	evsel->core.attr.inherit = inherit;
95162306a36Sopenharmony_ci	/*
95262306a36Sopenharmony_ci	 * This will group just the fds for this single evsel, to group
95362306a36Sopenharmony_ci	 * multiple events, use evlist.open().
95462306a36Sopenharmony_ci	 */
95562306a36Sopenharmony_ci	if (evsel__open(evsel, cpus, threads) < 0) {
95662306a36Sopenharmony_ci		PyErr_SetFromErrno(PyExc_OSError);
95762306a36Sopenharmony_ci		return NULL;
95862306a36Sopenharmony_ci	}
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	Py_INCREF(Py_None);
96162306a36Sopenharmony_ci	return Py_None;
96262306a36Sopenharmony_ci}
96362306a36Sopenharmony_ci
96462306a36Sopenharmony_cistatic PyMethodDef pyrf_evsel__methods[] = {
96562306a36Sopenharmony_ci	{
96662306a36Sopenharmony_ci		.ml_name  = "open",
96762306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evsel__open,
96862306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
96962306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("open the event selector file descriptor table.")
97062306a36Sopenharmony_ci	},
97162306a36Sopenharmony_ci	{ .ml_name = NULL, }
97262306a36Sopenharmony_ci};
97362306a36Sopenharmony_ci
97462306a36Sopenharmony_cistatic char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
97562306a36Sopenharmony_ci
97662306a36Sopenharmony_cistatic PyTypeObject pyrf_evsel__type = {
97762306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
97862306a36Sopenharmony_ci	.tp_name	= "perf.evsel",
97962306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_evsel),
98062306a36Sopenharmony_ci	.tp_dealloc	= (destructor)pyrf_evsel__delete,
98162306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
98262306a36Sopenharmony_ci	.tp_doc		= pyrf_evsel__doc,
98362306a36Sopenharmony_ci	.tp_methods	= pyrf_evsel__methods,
98462306a36Sopenharmony_ci	.tp_init	= (initproc)pyrf_evsel__init,
98562306a36Sopenharmony_ci};
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_cistatic int pyrf_evsel__setup_types(void)
98862306a36Sopenharmony_ci{
98962306a36Sopenharmony_ci	pyrf_evsel__type.tp_new = PyType_GenericNew;
99062306a36Sopenharmony_ci	return PyType_Ready(&pyrf_evsel__type);
99162306a36Sopenharmony_ci}
99262306a36Sopenharmony_ci
99362306a36Sopenharmony_cistruct pyrf_evlist {
99462306a36Sopenharmony_ci	PyObject_HEAD
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ci	struct evlist evlist;
99762306a36Sopenharmony_ci};
99862306a36Sopenharmony_ci
99962306a36Sopenharmony_cistatic int pyrf_evlist__init(struct pyrf_evlist *pevlist,
100062306a36Sopenharmony_ci			     PyObject *args, PyObject *kwargs __maybe_unused)
100162306a36Sopenharmony_ci{
100262306a36Sopenharmony_ci	PyObject *pcpus = NULL, *pthreads = NULL;
100362306a36Sopenharmony_ci	struct perf_cpu_map *cpus;
100462306a36Sopenharmony_ci	struct perf_thread_map *threads;
100562306a36Sopenharmony_ci
100662306a36Sopenharmony_ci	if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
100762306a36Sopenharmony_ci		return -1;
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci	threads = ((struct pyrf_thread_map *)pthreads)->threads;
101062306a36Sopenharmony_ci	cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
101162306a36Sopenharmony_ci	evlist__init(&pevlist->evlist, cpus, threads);
101262306a36Sopenharmony_ci	return 0;
101362306a36Sopenharmony_ci}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_cistatic void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
101662306a36Sopenharmony_ci{
101762306a36Sopenharmony_ci	evlist__exit(&pevlist->evlist);
101862306a36Sopenharmony_ci	Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
101962306a36Sopenharmony_ci}
102062306a36Sopenharmony_ci
102162306a36Sopenharmony_cistatic PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
102262306a36Sopenharmony_ci				   PyObject *args, PyObject *kwargs)
102362306a36Sopenharmony_ci{
102462306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
102562306a36Sopenharmony_ci	static char *kwlist[] = { "pages", "overwrite", NULL };
102662306a36Sopenharmony_ci	int pages = 128, overwrite = false;
102762306a36Sopenharmony_ci
102862306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
102962306a36Sopenharmony_ci					 &pages, &overwrite))
103062306a36Sopenharmony_ci		return NULL;
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	if (evlist__mmap(evlist, pages) < 0) {
103362306a36Sopenharmony_ci		PyErr_SetFromErrno(PyExc_OSError);
103462306a36Sopenharmony_ci		return NULL;
103562306a36Sopenharmony_ci	}
103662306a36Sopenharmony_ci
103762306a36Sopenharmony_ci	Py_INCREF(Py_None);
103862306a36Sopenharmony_ci	return Py_None;
103962306a36Sopenharmony_ci}
104062306a36Sopenharmony_ci
104162306a36Sopenharmony_cistatic PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
104262306a36Sopenharmony_ci				   PyObject *args, PyObject *kwargs)
104362306a36Sopenharmony_ci{
104462306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
104562306a36Sopenharmony_ci	static char *kwlist[] = { "timeout", NULL };
104662306a36Sopenharmony_ci	int timeout = -1, n;
104762306a36Sopenharmony_ci
104862306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
104962306a36Sopenharmony_ci		return NULL;
105062306a36Sopenharmony_ci
105162306a36Sopenharmony_ci	n = evlist__poll(evlist, timeout);
105262306a36Sopenharmony_ci	if (n < 0) {
105362306a36Sopenharmony_ci		PyErr_SetFromErrno(PyExc_OSError);
105462306a36Sopenharmony_ci		return NULL;
105562306a36Sopenharmony_ci	}
105662306a36Sopenharmony_ci
105762306a36Sopenharmony_ci	return Py_BuildValue("i", n);
105862306a36Sopenharmony_ci}
105962306a36Sopenharmony_ci
106062306a36Sopenharmony_cistatic PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
106162306a36Sopenharmony_ci					 PyObject *args __maybe_unused,
106262306a36Sopenharmony_ci					 PyObject *kwargs __maybe_unused)
106362306a36Sopenharmony_ci{
106462306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
106562306a36Sopenharmony_ci        PyObject *list = PyList_New(0);
106662306a36Sopenharmony_ci	int i;
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci	for (i = 0; i < evlist->core.pollfd.nr; ++i) {
106962306a36Sopenharmony_ci		PyObject *file;
107062306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
107162306a36Sopenharmony_ci		FILE *fp = fdopen(evlist->core.pollfd.entries[i].fd, "r");
107262306a36Sopenharmony_ci
107362306a36Sopenharmony_ci		if (fp == NULL)
107462306a36Sopenharmony_ci			goto free_list;
107562306a36Sopenharmony_ci
107662306a36Sopenharmony_ci		file = PyFile_FromFile(fp, "perf", "r", NULL);
107762306a36Sopenharmony_ci#else
107862306a36Sopenharmony_ci		file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1,
107962306a36Sopenharmony_ci				     NULL, NULL, NULL, 0);
108062306a36Sopenharmony_ci#endif
108162306a36Sopenharmony_ci		if (file == NULL)
108262306a36Sopenharmony_ci			goto free_list;
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_ci		if (PyList_Append(list, file) != 0) {
108562306a36Sopenharmony_ci			Py_DECREF(file);
108662306a36Sopenharmony_ci			goto free_list;
108762306a36Sopenharmony_ci		}
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_ci		Py_DECREF(file);
109062306a36Sopenharmony_ci	}
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_ci	return list;
109362306a36Sopenharmony_cifree_list:
109462306a36Sopenharmony_ci	return PyErr_NoMemory();
109562306a36Sopenharmony_ci}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_ci
109862306a36Sopenharmony_cistatic PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
109962306a36Sopenharmony_ci				  PyObject *args,
110062306a36Sopenharmony_ci				  PyObject *kwargs __maybe_unused)
110162306a36Sopenharmony_ci{
110262306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
110362306a36Sopenharmony_ci	PyObject *pevsel;
110462306a36Sopenharmony_ci	struct evsel *evsel;
110562306a36Sopenharmony_ci
110662306a36Sopenharmony_ci	if (!PyArg_ParseTuple(args, "O", &pevsel))
110762306a36Sopenharmony_ci		return NULL;
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	Py_INCREF(pevsel);
111062306a36Sopenharmony_ci	evsel = &((struct pyrf_evsel *)pevsel)->evsel;
111162306a36Sopenharmony_ci	evsel->core.idx = evlist->core.nr_entries;
111262306a36Sopenharmony_ci	evlist__add(evlist, evsel);
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci	return Py_BuildValue("i", evlist->core.nr_entries);
111562306a36Sopenharmony_ci}
111662306a36Sopenharmony_ci
111762306a36Sopenharmony_cistatic struct mmap *get_md(struct evlist *evlist, int cpu)
111862306a36Sopenharmony_ci{
111962306a36Sopenharmony_ci	int i;
112062306a36Sopenharmony_ci
112162306a36Sopenharmony_ci	for (i = 0; i < evlist->core.nr_mmaps; i++) {
112262306a36Sopenharmony_ci		struct mmap *md = &evlist->mmap[i];
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci		if (md->core.cpu.cpu == cpu)
112562306a36Sopenharmony_ci			return md;
112662306a36Sopenharmony_ci	}
112762306a36Sopenharmony_ci
112862306a36Sopenharmony_ci	return NULL;
112962306a36Sopenharmony_ci}
113062306a36Sopenharmony_ci
113162306a36Sopenharmony_cistatic PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
113262306a36Sopenharmony_ci					  PyObject *args, PyObject *kwargs)
113362306a36Sopenharmony_ci{
113462306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
113562306a36Sopenharmony_ci	union perf_event *event;
113662306a36Sopenharmony_ci	int sample_id_all = 1, cpu;
113762306a36Sopenharmony_ci	static char *kwlist[] = { "cpu", "sample_id_all", NULL };
113862306a36Sopenharmony_ci	struct mmap *md;
113962306a36Sopenharmony_ci	int err;
114062306a36Sopenharmony_ci
114162306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
114262306a36Sopenharmony_ci					 &cpu, &sample_id_all))
114362306a36Sopenharmony_ci		return NULL;
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	md = get_md(evlist, cpu);
114662306a36Sopenharmony_ci	if (!md)
114762306a36Sopenharmony_ci		return NULL;
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	if (perf_mmap__read_init(&md->core) < 0)
115062306a36Sopenharmony_ci		goto end;
115162306a36Sopenharmony_ci
115262306a36Sopenharmony_ci	event = perf_mmap__read_event(&md->core);
115362306a36Sopenharmony_ci	if (event != NULL) {
115462306a36Sopenharmony_ci		PyObject *pyevent = pyrf_event__new(event);
115562306a36Sopenharmony_ci		struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
115662306a36Sopenharmony_ci		struct evsel *evsel;
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci		if (pyevent == NULL)
115962306a36Sopenharmony_ci			return PyErr_NoMemory();
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci		evsel = evlist__event2evsel(evlist, event);
116262306a36Sopenharmony_ci		if (!evsel) {
116362306a36Sopenharmony_ci			Py_INCREF(Py_None);
116462306a36Sopenharmony_ci			return Py_None;
116562306a36Sopenharmony_ci		}
116662306a36Sopenharmony_ci
116762306a36Sopenharmony_ci		pevent->evsel = evsel;
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci		err = evsel__parse_sample(evsel, event, &pevent->sample);
117062306a36Sopenharmony_ci
117162306a36Sopenharmony_ci		/* Consume the even only after we parsed it out. */
117262306a36Sopenharmony_ci		perf_mmap__consume(&md->core);
117362306a36Sopenharmony_ci
117462306a36Sopenharmony_ci		if (err)
117562306a36Sopenharmony_ci			return PyErr_Format(PyExc_OSError,
117662306a36Sopenharmony_ci					    "perf: can't parse sample, err=%d", err);
117762306a36Sopenharmony_ci		return pyevent;
117862306a36Sopenharmony_ci	}
117962306a36Sopenharmony_ciend:
118062306a36Sopenharmony_ci	Py_INCREF(Py_None);
118162306a36Sopenharmony_ci	return Py_None;
118262306a36Sopenharmony_ci}
118362306a36Sopenharmony_ci
118462306a36Sopenharmony_cistatic PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
118562306a36Sopenharmony_ci				   PyObject *args, PyObject *kwargs)
118662306a36Sopenharmony_ci{
118762306a36Sopenharmony_ci	struct evlist *evlist = &pevlist->evlist;
118862306a36Sopenharmony_ci
118962306a36Sopenharmony_ci	if (evlist__open(evlist) < 0) {
119062306a36Sopenharmony_ci		PyErr_SetFromErrno(PyExc_OSError);
119162306a36Sopenharmony_ci		return NULL;
119262306a36Sopenharmony_ci	}
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	Py_INCREF(Py_None);
119562306a36Sopenharmony_ci	return Py_None;
119662306a36Sopenharmony_ci}
119762306a36Sopenharmony_ci
119862306a36Sopenharmony_cistatic PyMethodDef pyrf_evlist__methods[] = {
119962306a36Sopenharmony_ci	{
120062306a36Sopenharmony_ci		.ml_name  = "mmap",
120162306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__mmap,
120262306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
120362306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("mmap the file descriptor table.")
120462306a36Sopenharmony_ci	},
120562306a36Sopenharmony_ci	{
120662306a36Sopenharmony_ci		.ml_name  = "open",
120762306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__open,
120862306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
120962306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("open the file descriptors.")
121062306a36Sopenharmony_ci	},
121162306a36Sopenharmony_ci	{
121262306a36Sopenharmony_ci		.ml_name  = "poll",
121362306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__poll,
121462306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
121562306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("poll the file descriptor table.")
121662306a36Sopenharmony_ci	},
121762306a36Sopenharmony_ci	{
121862306a36Sopenharmony_ci		.ml_name  = "get_pollfd",
121962306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__get_pollfd,
122062306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
122162306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("get the poll file descriptor table.")
122262306a36Sopenharmony_ci	},
122362306a36Sopenharmony_ci	{
122462306a36Sopenharmony_ci		.ml_name  = "add",
122562306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__add,
122662306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
122762306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("adds an event selector to the list.")
122862306a36Sopenharmony_ci	},
122962306a36Sopenharmony_ci	{
123062306a36Sopenharmony_ci		.ml_name  = "read_on_cpu",
123162306a36Sopenharmony_ci		.ml_meth  = (PyCFunction)pyrf_evlist__read_on_cpu,
123262306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
123362306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("reads an event.")
123462306a36Sopenharmony_ci	},
123562306a36Sopenharmony_ci	{ .ml_name = NULL, }
123662306a36Sopenharmony_ci};
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_cistatic Py_ssize_t pyrf_evlist__length(PyObject *obj)
123962306a36Sopenharmony_ci{
124062306a36Sopenharmony_ci	struct pyrf_evlist *pevlist = (void *)obj;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci	return pevlist->evlist.core.nr_entries;
124362306a36Sopenharmony_ci}
124462306a36Sopenharmony_ci
124562306a36Sopenharmony_cistatic PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
124662306a36Sopenharmony_ci{
124762306a36Sopenharmony_ci	struct pyrf_evlist *pevlist = (void *)obj;
124862306a36Sopenharmony_ci	struct evsel *pos;
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	if (i >= pevlist->evlist.core.nr_entries)
125162306a36Sopenharmony_ci		return NULL;
125262306a36Sopenharmony_ci
125362306a36Sopenharmony_ci	evlist__for_each_entry(&pevlist->evlist, pos) {
125462306a36Sopenharmony_ci		if (i-- == 0)
125562306a36Sopenharmony_ci			break;
125662306a36Sopenharmony_ci	}
125762306a36Sopenharmony_ci
125862306a36Sopenharmony_ci	return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
125962306a36Sopenharmony_ci}
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_cistatic PySequenceMethods pyrf_evlist__sequence_methods = {
126262306a36Sopenharmony_ci	.sq_length = pyrf_evlist__length,
126362306a36Sopenharmony_ci	.sq_item   = pyrf_evlist__item,
126462306a36Sopenharmony_ci};
126562306a36Sopenharmony_ci
126662306a36Sopenharmony_cistatic char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_cistatic PyTypeObject pyrf_evlist__type = {
126962306a36Sopenharmony_ci	PyVarObject_HEAD_INIT(NULL, 0)
127062306a36Sopenharmony_ci	.tp_name	= "perf.evlist",
127162306a36Sopenharmony_ci	.tp_basicsize	= sizeof(struct pyrf_evlist),
127262306a36Sopenharmony_ci	.tp_dealloc	= (destructor)pyrf_evlist__delete,
127362306a36Sopenharmony_ci	.tp_flags	= Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
127462306a36Sopenharmony_ci	.tp_as_sequence	= &pyrf_evlist__sequence_methods,
127562306a36Sopenharmony_ci	.tp_doc		= pyrf_evlist__doc,
127662306a36Sopenharmony_ci	.tp_methods	= pyrf_evlist__methods,
127762306a36Sopenharmony_ci	.tp_init	= (initproc)pyrf_evlist__init,
127862306a36Sopenharmony_ci};
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_cistatic int pyrf_evlist__setup_types(void)
128162306a36Sopenharmony_ci{
128262306a36Sopenharmony_ci	pyrf_evlist__type.tp_new = PyType_GenericNew;
128362306a36Sopenharmony_ci	return PyType_Ready(&pyrf_evlist__type);
128462306a36Sopenharmony_ci}
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci#define PERF_CONST(name) { #name, PERF_##name }
128762306a36Sopenharmony_ci
128862306a36Sopenharmony_cistatic struct {
128962306a36Sopenharmony_ci	const char *name;
129062306a36Sopenharmony_ci	int	    value;
129162306a36Sopenharmony_ci} perf__constants[] = {
129262306a36Sopenharmony_ci	PERF_CONST(TYPE_HARDWARE),
129362306a36Sopenharmony_ci	PERF_CONST(TYPE_SOFTWARE),
129462306a36Sopenharmony_ci	PERF_CONST(TYPE_TRACEPOINT),
129562306a36Sopenharmony_ci	PERF_CONST(TYPE_HW_CACHE),
129662306a36Sopenharmony_ci	PERF_CONST(TYPE_RAW),
129762306a36Sopenharmony_ci	PERF_CONST(TYPE_BREAKPOINT),
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CPU_CYCLES),
130062306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_INSTRUCTIONS),
130162306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_REFERENCES),
130262306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_MISSES),
130362306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
130462306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_BRANCH_MISSES),
130562306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_BUS_CYCLES),
130662306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_L1D),
130762306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_L1I),
130862306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_LL),
130962306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_DTLB),
131062306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_ITLB),
131162306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_BPU),
131262306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_OP_READ),
131362306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
131462306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
131562306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
131662306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
131762306a36Sopenharmony_ci
131862306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
131962306a36Sopenharmony_ci	PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_CPU_CLOCK),
132262306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_TASK_CLOCK),
132362306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_PAGE_FAULTS),
132462306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
132562306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
132662306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
132762306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
132862306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
132962306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_EMULATION_FAULTS),
133062306a36Sopenharmony_ci	PERF_CONST(COUNT_SW_DUMMY),
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci	PERF_CONST(SAMPLE_IP),
133362306a36Sopenharmony_ci	PERF_CONST(SAMPLE_TID),
133462306a36Sopenharmony_ci	PERF_CONST(SAMPLE_TIME),
133562306a36Sopenharmony_ci	PERF_CONST(SAMPLE_ADDR),
133662306a36Sopenharmony_ci	PERF_CONST(SAMPLE_READ),
133762306a36Sopenharmony_ci	PERF_CONST(SAMPLE_CALLCHAIN),
133862306a36Sopenharmony_ci	PERF_CONST(SAMPLE_ID),
133962306a36Sopenharmony_ci	PERF_CONST(SAMPLE_CPU),
134062306a36Sopenharmony_ci	PERF_CONST(SAMPLE_PERIOD),
134162306a36Sopenharmony_ci	PERF_CONST(SAMPLE_STREAM_ID),
134262306a36Sopenharmony_ci	PERF_CONST(SAMPLE_RAW),
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
134562306a36Sopenharmony_ci	PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
134662306a36Sopenharmony_ci	PERF_CONST(FORMAT_ID),
134762306a36Sopenharmony_ci	PERF_CONST(FORMAT_GROUP),
134862306a36Sopenharmony_ci
134962306a36Sopenharmony_ci	PERF_CONST(RECORD_MMAP),
135062306a36Sopenharmony_ci	PERF_CONST(RECORD_LOST),
135162306a36Sopenharmony_ci	PERF_CONST(RECORD_COMM),
135262306a36Sopenharmony_ci	PERF_CONST(RECORD_EXIT),
135362306a36Sopenharmony_ci	PERF_CONST(RECORD_THROTTLE),
135462306a36Sopenharmony_ci	PERF_CONST(RECORD_UNTHROTTLE),
135562306a36Sopenharmony_ci	PERF_CONST(RECORD_FORK),
135662306a36Sopenharmony_ci	PERF_CONST(RECORD_READ),
135762306a36Sopenharmony_ci	PERF_CONST(RECORD_SAMPLE),
135862306a36Sopenharmony_ci	PERF_CONST(RECORD_MMAP2),
135962306a36Sopenharmony_ci	PERF_CONST(RECORD_AUX),
136062306a36Sopenharmony_ci	PERF_CONST(RECORD_ITRACE_START),
136162306a36Sopenharmony_ci	PERF_CONST(RECORD_LOST_SAMPLES),
136262306a36Sopenharmony_ci	PERF_CONST(RECORD_SWITCH),
136362306a36Sopenharmony_ci	PERF_CONST(RECORD_SWITCH_CPU_WIDE),
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	PERF_CONST(RECORD_MISC_SWITCH_OUT),
136662306a36Sopenharmony_ci	{ .name = NULL, },
136762306a36Sopenharmony_ci};
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_cistatic PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
137062306a36Sopenharmony_ci				  PyObject *args, PyObject *kwargs)
137162306a36Sopenharmony_ci{
137262306a36Sopenharmony_ci#ifndef HAVE_LIBTRACEEVENT
137362306a36Sopenharmony_ci	return NULL;
137462306a36Sopenharmony_ci#else
137562306a36Sopenharmony_ci	struct tep_event *tp_format;
137662306a36Sopenharmony_ci	static char *kwlist[] = { "sys", "name", NULL };
137762306a36Sopenharmony_ci	char *sys  = NULL;
137862306a36Sopenharmony_ci	char *name = NULL;
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
138162306a36Sopenharmony_ci					 &sys, &name))
138262306a36Sopenharmony_ci		return NULL;
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	tp_format = trace_event__tp_format(sys, name);
138562306a36Sopenharmony_ci	if (IS_ERR(tp_format))
138662306a36Sopenharmony_ci		return _PyLong_FromLong(-1);
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci	return _PyLong_FromLong(tp_format->id);
138962306a36Sopenharmony_ci#endif // HAVE_LIBTRACEEVENT
139062306a36Sopenharmony_ci}
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_cistatic PyMethodDef perf__methods[] = {
139362306a36Sopenharmony_ci	{
139462306a36Sopenharmony_ci		.ml_name  = "tracepoint",
139562306a36Sopenharmony_ci		.ml_meth  = (PyCFunction) pyrf__tracepoint,
139662306a36Sopenharmony_ci		.ml_flags = METH_VARARGS | METH_KEYWORDS,
139762306a36Sopenharmony_ci		.ml_doc	  = PyDoc_STR("Get tracepoint config.")
139862306a36Sopenharmony_ci	},
139962306a36Sopenharmony_ci	{ .ml_name = NULL, }
140062306a36Sopenharmony_ci};
140162306a36Sopenharmony_ci
140262306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
140362306a36Sopenharmony_ciPyMODINIT_FUNC initperf(void)
140462306a36Sopenharmony_ci#else
140562306a36Sopenharmony_ciPyMODINIT_FUNC PyInit_perf(void)
140662306a36Sopenharmony_ci#endif
140762306a36Sopenharmony_ci{
140862306a36Sopenharmony_ci	PyObject *obj;
140962306a36Sopenharmony_ci	int i;
141062306a36Sopenharmony_ci	PyObject *dict;
141162306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
141262306a36Sopenharmony_ci	PyObject *module = Py_InitModule("perf", perf__methods);
141362306a36Sopenharmony_ci#else
141462306a36Sopenharmony_ci	static struct PyModuleDef moduledef = {
141562306a36Sopenharmony_ci		PyModuleDef_HEAD_INIT,
141662306a36Sopenharmony_ci		"perf",			/* m_name */
141762306a36Sopenharmony_ci		"",			/* m_doc */
141862306a36Sopenharmony_ci		-1,			/* m_size */
141962306a36Sopenharmony_ci		perf__methods,		/* m_methods */
142062306a36Sopenharmony_ci		NULL,			/* m_reload */
142162306a36Sopenharmony_ci		NULL,			/* m_traverse */
142262306a36Sopenharmony_ci		NULL,			/* m_clear */
142362306a36Sopenharmony_ci		NULL,			/* m_free */
142462306a36Sopenharmony_ci	};
142562306a36Sopenharmony_ci	PyObject *module = PyModule_Create(&moduledef);
142662306a36Sopenharmony_ci#endif
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	if (module == NULL ||
142962306a36Sopenharmony_ci	    pyrf_event__setup_types() < 0 ||
143062306a36Sopenharmony_ci	    pyrf_evlist__setup_types() < 0 ||
143162306a36Sopenharmony_ci	    pyrf_evsel__setup_types() < 0 ||
143262306a36Sopenharmony_ci	    pyrf_thread_map__setup_types() < 0 ||
143362306a36Sopenharmony_ci	    pyrf_cpu_map__setup_types() < 0)
143462306a36Sopenharmony_ci#if PY_MAJOR_VERSION < 3
143562306a36Sopenharmony_ci		return;
143662306a36Sopenharmony_ci#else
143762306a36Sopenharmony_ci		return module;
143862306a36Sopenharmony_ci#endif
143962306a36Sopenharmony_ci
144062306a36Sopenharmony_ci	/* The page_size is placed in util object. */
144162306a36Sopenharmony_ci	page_size = sysconf(_SC_PAGE_SIZE);
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci	Py_INCREF(&pyrf_evlist__type);
144462306a36Sopenharmony_ci	PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
144562306a36Sopenharmony_ci
144662306a36Sopenharmony_ci	Py_INCREF(&pyrf_evsel__type);
144762306a36Sopenharmony_ci	PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
144862306a36Sopenharmony_ci
144962306a36Sopenharmony_ci	Py_INCREF(&pyrf_mmap_event__type);
145062306a36Sopenharmony_ci	PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_ci	Py_INCREF(&pyrf_lost_event__type);
145362306a36Sopenharmony_ci	PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
145462306a36Sopenharmony_ci
145562306a36Sopenharmony_ci	Py_INCREF(&pyrf_comm_event__type);
145662306a36Sopenharmony_ci	PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
145762306a36Sopenharmony_ci
145862306a36Sopenharmony_ci	Py_INCREF(&pyrf_task_event__type);
145962306a36Sopenharmony_ci	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_ci	Py_INCREF(&pyrf_throttle_event__type);
146262306a36Sopenharmony_ci	PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
146362306a36Sopenharmony_ci
146462306a36Sopenharmony_ci	Py_INCREF(&pyrf_task_event__type);
146562306a36Sopenharmony_ci	PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
146662306a36Sopenharmony_ci
146762306a36Sopenharmony_ci	Py_INCREF(&pyrf_read_event__type);
146862306a36Sopenharmony_ci	PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
146962306a36Sopenharmony_ci
147062306a36Sopenharmony_ci	Py_INCREF(&pyrf_sample_event__type);
147162306a36Sopenharmony_ci	PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
147262306a36Sopenharmony_ci
147362306a36Sopenharmony_ci	Py_INCREF(&pyrf_context_switch_event__type);
147462306a36Sopenharmony_ci	PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_ci	Py_INCREF(&pyrf_thread_map__type);
147762306a36Sopenharmony_ci	PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
147862306a36Sopenharmony_ci
147962306a36Sopenharmony_ci	Py_INCREF(&pyrf_cpu_map__type);
148062306a36Sopenharmony_ci	PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
148162306a36Sopenharmony_ci
148262306a36Sopenharmony_ci	dict = PyModule_GetDict(module);
148362306a36Sopenharmony_ci	if (dict == NULL)
148462306a36Sopenharmony_ci		goto error;
148562306a36Sopenharmony_ci
148662306a36Sopenharmony_ci	for (i = 0; perf__constants[i].name != NULL; i++) {
148762306a36Sopenharmony_ci		obj = _PyLong_FromLong(perf__constants[i].value);
148862306a36Sopenharmony_ci		if (obj == NULL)
148962306a36Sopenharmony_ci			goto error;
149062306a36Sopenharmony_ci		PyDict_SetItemString(dict, perf__constants[i].name, obj);
149162306a36Sopenharmony_ci		Py_DECREF(obj);
149262306a36Sopenharmony_ci	}
149362306a36Sopenharmony_ci
149462306a36Sopenharmony_cierror:
149562306a36Sopenharmony_ci	if (PyErr_Occurred())
149662306a36Sopenharmony_ci		PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
149762306a36Sopenharmony_ci#if PY_MAJOR_VERSION >= 3
149862306a36Sopenharmony_ci	return module;
149962306a36Sopenharmony_ci#endif
150062306a36Sopenharmony_ci}
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci/*
150362306a36Sopenharmony_ci * Dummy, to avoid dragging all the test_attr infrastructure in the python
150462306a36Sopenharmony_ci * binding.
150562306a36Sopenharmony_ci */
150662306a36Sopenharmony_civoid test_attr__open(struct perf_event_attr *attr, pid_t pid, struct perf_cpu cpu,
150762306a36Sopenharmony_ci                     int fd, int group_fd, unsigned long flags)
150862306a36Sopenharmony_ci{
150962306a36Sopenharmony_ci}
151062306a36Sopenharmony_ci
151162306a36Sopenharmony_civoid evlist__free_stats(struct evlist *evlist)
151262306a36Sopenharmony_ci{
151362306a36Sopenharmony_ci}
1514