python.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906
  1. #include <Python.h>
  2. #include <structmember.h>
  3. #include <inttypes.h>
  4. #include <poll.h>
  5. #include "evlist.h"
  6. #include "evsel.h"
  7. #include "event.h"
  8. #include "cpumap.h"
  9. #include "thread_map.h"
  10. /* Define PyVarObject_HEAD_INIT for python 2.5 */
  11. #ifndef PyVarObject_HEAD_INIT
  12. # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
  13. #endif
  14. struct throttle_event {
  15. struct perf_event_header header;
  16. u64 time;
  17. u64 id;
  18. u64 stream_id;
  19. };
  20. PyMODINIT_FUNC initperf(void);
  21. #define member_def(type, member, ptype, help) \
  22. { #member, ptype, \
  23. offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
  24. 0, help }
  25. #define sample_member_def(name, member, ptype, help) \
  26. { #name, ptype, \
  27. offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
  28. 0, help }
  29. struct pyrf_event {
  30. PyObject_HEAD
  31. struct perf_sample sample;
  32. union perf_event event;
  33. };
  34. #define sample_members \
  35. sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
  36. sample_member_def(sample_pid, pid, T_INT, "event pid"), \
  37. sample_member_def(sample_tid, tid, T_INT, "event tid"), \
  38. sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
  39. sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
  40. sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
  41. sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
  42. sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
  43. sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
  44. static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
  45. static PyMemberDef pyrf_mmap_event__members[] = {
  46. sample_members
  47. member_def(perf_event_header, type, T_UINT, "event type"),
  48. member_def(mmap_event, pid, T_UINT, "event pid"),
  49. member_def(mmap_event, tid, T_UINT, "event tid"),
  50. member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
  51. member_def(mmap_event, len, T_ULONGLONG, "map length"),
  52. member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
  53. member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
  54. { .name = NULL, },
  55. };
  56. static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
  57. {
  58. PyObject *ret;
  59. char *s;
  60. if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
  61. "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
  62. "filename: %s }",
  63. pevent->event.mmap.pid, pevent->event.mmap.tid,
  64. pevent->event.mmap.start, pevent->event.mmap.len,
  65. pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
  66. ret = PyErr_NoMemory();
  67. } else {
  68. ret = PyString_FromString(s);
  69. free(s);
  70. }
  71. return ret;
  72. }
  73. static PyTypeObject pyrf_mmap_event__type = {
  74. PyVarObject_HEAD_INIT(NULL, 0)
  75. .tp_name = "perf.mmap_event",
  76. .tp_basicsize = sizeof(struct pyrf_event),
  77. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  78. .tp_doc = pyrf_mmap_event__doc,
  79. .tp_members = pyrf_mmap_event__members,
  80. .tp_repr = (reprfunc)pyrf_mmap_event__repr,
  81. };
  82. static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
  83. static PyMemberDef pyrf_task_event__members[] = {
  84. sample_members
  85. member_def(perf_event_header, type, T_UINT, "event type"),
  86. member_def(fork_event, pid, T_UINT, "event pid"),
  87. member_def(fork_event, ppid, T_UINT, "event ppid"),
  88. member_def(fork_event, tid, T_UINT, "event tid"),
  89. member_def(fork_event, ptid, T_UINT, "event ptid"),
  90. member_def(fork_event, time, T_ULONGLONG, "timestamp"),
  91. { .name = NULL, },
  92. };
  93. static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
  94. {
  95. return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
  96. "ptid: %u, time: %" PRIu64 "}",
  97. pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
  98. pevent->event.fork.pid,
  99. pevent->event.fork.ppid,
  100. pevent->event.fork.tid,
  101. pevent->event.fork.ptid,
  102. pevent->event.fork.time);
  103. }
  104. static PyTypeObject pyrf_task_event__type = {
  105. PyVarObject_HEAD_INIT(NULL, 0)
  106. .tp_name = "perf.task_event",
  107. .tp_basicsize = sizeof(struct pyrf_event),
  108. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  109. .tp_doc = pyrf_task_event__doc,
  110. .tp_members = pyrf_task_event__members,
  111. .tp_repr = (reprfunc)pyrf_task_event__repr,
  112. };
  113. static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
  114. static PyMemberDef pyrf_comm_event__members[] = {
  115. sample_members
  116. member_def(perf_event_header, type, T_UINT, "event type"),
  117. member_def(comm_event, pid, T_UINT, "event pid"),
  118. member_def(comm_event, tid, T_UINT, "event tid"),
  119. member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
  120. { .name = NULL, },
  121. };
  122. static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
  123. {
  124. return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
  125. pevent->event.comm.pid,
  126. pevent->event.comm.tid,
  127. pevent->event.comm.comm);
  128. }
  129. static PyTypeObject pyrf_comm_event__type = {
  130. PyVarObject_HEAD_INIT(NULL, 0)
  131. .tp_name = "perf.comm_event",
  132. .tp_basicsize = sizeof(struct pyrf_event),
  133. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  134. .tp_doc = pyrf_comm_event__doc,
  135. .tp_members = pyrf_comm_event__members,
  136. .tp_repr = (reprfunc)pyrf_comm_event__repr,
  137. };
  138. static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
  139. static PyMemberDef pyrf_throttle_event__members[] = {
  140. sample_members
  141. member_def(perf_event_header, type, T_UINT, "event type"),
  142. member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
  143. member_def(throttle_event, id, T_ULONGLONG, "event id"),
  144. member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
  145. { .name = NULL, },
  146. };
  147. static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
  148. {
  149. struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
  150. return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
  151. ", stream_id: %" PRIu64 " }",
  152. pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
  153. te->time, te->id, te->stream_id);
  154. }
  155. static PyTypeObject pyrf_throttle_event__type = {
  156. PyVarObject_HEAD_INIT(NULL, 0)
  157. .tp_name = "perf.throttle_event",
  158. .tp_basicsize = sizeof(struct pyrf_event),
  159. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  160. .tp_doc = pyrf_throttle_event__doc,
  161. .tp_members = pyrf_throttle_event__members,
  162. .tp_repr = (reprfunc)pyrf_throttle_event__repr,
  163. };
  164. static int pyrf_event__setup_types(void)
  165. {
  166. int err;
  167. pyrf_mmap_event__type.tp_new =
  168. pyrf_task_event__type.tp_new =
  169. pyrf_comm_event__type.tp_new =
  170. pyrf_throttle_event__type.tp_new = PyType_GenericNew;
  171. err = PyType_Ready(&pyrf_mmap_event__type);
  172. if (err < 0)
  173. goto out;
  174. err = PyType_Ready(&pyrf_task_event__type);
  175. if (err < 0)
  176. goto out;
  177. err = PyType_Ready(&pyrf_comm_event__type);
  178. if (err < 0)
  179. goto out;
  180. err = PyType_Ready(&pyrf_throttle_event__type);
  181. if (err < 0)
  182. goto out;
  183. out:
  184. return err;
  185. }
  186. static PyTypeObject *pyrf_event__type[] = {
  187. [PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
  188. [PERF_RECORD_LOST] = &pyrf_mmap_event__type,
  189. [PERF_RECORD_COMM] = &pyrf_comm_event__type,
  190. [PERF_RECORD_EXIT] = &pyrf_task_event__type,
  191. [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
  192. [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
  193. [PERF_RECORD_FORK] = &pyrf_task_event__type,
  194. [PERF_RECORD_READ] = &pyrf_mmap_event__type,
  195. [PERF_RECORD_SAMPLE] = &pyrf_mmap_event__type,
  196. };
  197. static PyObject *pyrf_event__new(union perf_event *event)
  198. {
  199. struct pyrf_event *pevent;
  200. PyTypeObject *ptype;
  201. if (event->header.type < PERF_RECORD_MMAP ||
  202. event->header.type > PERF_RECORD_SAMPLE)
  203. return NULL;
  204. ptype = pyrf_event__type[event->header.type];
  205. pevent = PyObject_New(struct pyrf_event, ptype);
  206. if (pevent != NULL)
  207. memcpy(&pevent->event, event, event->header.size);
  208. return (PyObject *)pevent;
  209. }
  210. struct pyrf_cpu_map {
  211. PyObject_HEAD
  212. struct cpu_map *cpus;
  213. };
  214. static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
  215. PyObject *args, PyObject *kwargs)
  216. {
  217. static char *kwlist[] = { "cpustr", NULL, NULL, };
  218. char *cpustr = NULL;
  219. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
  220. kwlist, &cpustr))
  221. return -1;
  222. pcpus->cpus = cpu_map__new(cpustr);
  223. if (pcpus->cpus == NULL)
  224. return -1;
  225. return 0;
  226. }
  227. static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
  228. {
  229. cpu_map__delete(pcpus->cpus);
  230. pcpus->ob_type->tp_free((PyObject*)pcpus);
  231. }
  232. static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
  233. {
  234. struct pyrf_cpu_map *pcpus = (void *)obj;
  235. return pcpus->cpus->nr;
  236. }
  237. static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
  238. {
  239. struct pyrf_cpu_map *pcpus = (void *)obj;
  240. if (i >= pcpus->cpus->nr)
  241. return NULL;
  242. return Py_BuildValue("i", pcpus->cpus->map[i]);
  243. }
  244. static PySequenceMethods pyrf_cpu_map__sequence_methods = {
  245. .sq_length = pyrf_cpu_map__length,
  246. .sq_item = pyrf_cpu_map__item,
  247. };
  248. static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
  249. static PyTypeObject pyrf_cpu_map__type = {
  250. PyVarObject_HEAD_INIT(NULL, 0)
  251. .tp_name = "perf.cpu_map",
  252. .tp_basicsize = sizeof(struct pyrf_cpu_map),
  253. .tp_dealloc = (destructor)pyrf_cpu_map__delete,
  254. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  255. .tp_doc = pyrf_cpu_map__doc,
  256. .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
  257. .tp_init = (initproc)pyrf_cpu_map__init,
  258. };
  259. static int pyrf_cpu_map__setup_types(void)
  260. {
  261. pyrf_cpu_map__type.tp_new = PyType_GenericNew;
  262. return PyType_Ready(&pyrf_cpu_map__type);
  263. }
  264. struct pyrf_thread_map {
  265. PyObject_HEAD
  266. struct thread_map *threads;
  267. };
  268. static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
  269. PyObject *args, PyObject *kwargs)
  270. {
  271. static char *kwlist[] = { "pid", "tid", NULL, NULL, };
  272. int pid = -1, tid = -1;
  273. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
  274. kwlist, &pid, &tid))
  275. return -1;
  276. pthreads->threads = thread_map__new(pid, tid);
  277. if (pthreads->threads == NULL)
  278. return -1;
  279. return 0;
  280. }
  281. static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
  282. {
  283. thread_map__delete(pthreads->threads);
  284. pthreads->ob_type->tp_free((PyObject*)pthreads);
  285. }
  286. static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
  287. {
  288. struct pyrf_thread_map *pthreads = (void *)obj;
  289. return pthreads->threads->nr;
  290. }
  291. static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
  292. {
  293. struct pyrf_thread_map *pthreads = (void *)obj;
  294. if (i >= pthreads->threads->nr)
  295. return NULL;
  296. return Py_BuildValue("i", pthreads->threads->map[i]);
  297. }
  298. static PySequenceMethods pyrf_thread_map__sequence_methods = {
  299. .sq_length = pyrf_thread_map__length,
  300. .sq_item = pyrf_thread_map__item,
  301. };
  302. static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
  303. static PyTypeObject pyrf_thread_map__type = {
  304. PyVarObject_HEAD_INIT(NULL, 0)
  305. .tp_name = "perf.thread_map",
  306. .tp_basicsize = sizeof(struct pyrf_thread_map),
  307. .tp_dealloc = (destructor)pyrf_thread_map__delete,
  308. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  309. .tp_doc = pyrf_thread_map__doc,
  310. .tp_as_sequence = &pyrf_thread_map__sequence_methods,
  311. .tp_init = (initproc)pyrf_thread_map__init,
  312. };
  313. static int pyrf_thread_map__setup_types(void)
  314. {
  315. pyrf_thread_map__type.tp_new = PyType_GenericNew;
  316. return PyType_Ready(&pyrf_thread_map__type);
  317. }
  318. struct pyrf_evsel {
  319. PyObject_HEAD
  320. struct perf_evsel evsel;
  321. };
  322. static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
  323. PyObject *args, PyObject *kwargs)
  324. {
  325. struct perf_event_attr attr = {
  326. .type = PERF_TYPE_HARDWARE,
  327. .config = PERF_COUNT_HW_CPU_CYCLES,
  328. .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
  329. };
  330. static char *kwlist[] = {
  331. "type",
  332. "config",
  333. "sample_freq",
  334. "sample_period",
  335. "sample_type",
  336. "read_format",
  337. "disabled",
  338. "inherit",
  339. "pinned",
  340. "exclusive",
  341. "exclude_user",
  342. "exclude_kernel",
  343. "exclude_hv",
  344. "exclude_idle",
  345. "mmap",
  346. "comm",
  347. "freq",
  348. "inherit_stat",
  349. "enable_on_exec",
  350. "task",
  351. "watermark",
  352. "precise_ip",
  353. "mmap_data",
  354. "sample_id_all",
  355. "wakeup_events",
  356. "bp_type",
  357. "bp_addr",
  358. "bp_len", NULL, NULL, };
  359. u64 sample_period = 0;
  360. u32 disabled = 0,
  361. inherit = 0,
  362. pinned = 0,
  363. exclusive = 0,
  364. exclude_user = 0,
  365. exclude_kernel = 0,
  366. exclude_hv = 0,
  367. exclude_idle = 0,
  368. mmap = 0,
  369. comm = 0,
  370. freq = 1,
  371. inherit_stat = 0,
  372. enable_on_exec = 0,
  373. task = 0,
  374. watermark = 0,
  375. precise_ip = 0,
  376. mmap_data = 0,
  377. sample_id_all = 1;
  378. int idx = 0;
  379. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  380. "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
  381. &attr.type, &attr.config, &attr.sample_freq,
  382. &sample_period, &attr.sample_type,
  383. &attr.read_format, &disabled, &inherit,
  384. &pinned, &exclusive, &exclude_user,
  385. &exclude_kernel, &exclude_hv, &exclude_idle,
  386. &mmap, &comm, &freq, &inherit_stat,
  387. &enable_on_exec, &task, &watermark,
  388. &precise_ip, &mmap_data, &sample_id_all,
  389. &attr.wakeup_events, &attr.bp_type,
  390. &attr.bp_addr, &attr.bp_len, &idx))
  391. return -1;
  392. /* union... */
  393. if (sample_period != 0) {
  394. if (attr.sample_freq != 0)
  395. return -1; /* FIXME: throw right exception */
  396. attr.sample_period = sample_period;
  397. }
  398. /* Bitfields */
  399. attr.disabled = disabled;
  400. attr.inherit = inherit;
  401. attr.pinned = pinned;
  402. attr.exclusive = exclusive;
  403. attr.exclude_user = exclude_user;
  404. attr.exclude_kernel = exclude_kernel;
  405. attr.exclude_hv = exclude_hv;
  406. attr.exclude_idle = exclude_idle;
  407. attr.mmap = mmap;
  408. attr.comm = comm;
  409. attr.freq = freq;
  410. attr.inherit_stat = inherit_stat;
  411. attr.enable_on_exec = enable_on_exec;
  412. attr.task = task;
  413. attr.watermark = watermark;
  414. attr.precise_ip = precise_ip;
  415. attr.mmap_data = mmap_data;
  416. attr.sample_id_all = sample_id_all;
  417. perf_evsel__init(&pevsel->evsel, &attr, idx);
  418. return 0;
  419. }
  420. static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
  421. {
  422. perf_evsel__exit(&pevsel->evsel);
  423. pevsel->ob_type->tp_free((PyObject*)pevsel);
  424. }
  425. static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
  426. PyObject *args, PyObject *kwargs)
  427. {
  428. struct perf_evsel *evsel = &pevsel->evsel;
  429. struct cpu_map *cpus = NULL;
  430. struct thread_map *threads = NULL;
  431. PyObject *pcpus = NULL, *pthreads = NULL;
  432. int group = 0, inherit = 0;
  433. static char *kwlist[] = {"cpus", "threads", "group", "inherit", NULL, NULL};
  434. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
  435. &pcpus, &pthreads, &group, &inherit))
  436. return NULL;
  437. if (pthreads != NULL)
  438. threads = ((struct pyrf_thread_map *)pthreads)->threads;
  439. if (pcpus != NULL)
  440. cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
  441. evsel->attr.inherit = inherit;
  442. if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
  443. PyErr_SetFromErrno(PyExc_OSError);
  444. return NULL;
  445. }
  446. Py_INCREF(Py_None);
  447. return Py_None;
  448. }
  449. static PyMethodDef pyrf_evsel__methods[] = {
  450. {
  451. .ml_name = "open",
  452. .ml_meth = (PyCFunction)pyrf_evsel__open,
  453. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  454. .ml_doc = PyDoc_STR("open the event selector file descriptor table.")
  455. },
  456. { .ml_name = NULL, }
  457. };
  458. static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
  459. static PyTypeObject pyrf_evsel__type = {
  460. PyVarObject_HEAD_INIT(NULL, 0)
  461. .tp_name = "perf.evsel",
  462. .tp_basicsize = sizeof(struct pyrf_evsel),
  463. .tp_dealloc = (destructor)pyrf_evsel__delete,
  464. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  465. .tp_doc = pyrf_evsel__doc,
  466. .tp_methods = pyrf_evsel__methods,
  467. .tp_init = (initproc)pyrf_evsel__init,
  468. };
  469. static int pyrf_evsel__setup_types(void)
  470. {
  471. pyrf_evsel__type.tp_new = PyType_GenericNew;
  472. return PyType_Ready(&pyrf_evsel__type);
  473. }
  474. struct pyrf_evlist {
  475. PyObject_HEAD
  476. struct perf_evlist evlist;
  477. };
  478. static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
  479. PyObject *args, PyObject *kwargs __used)
  480. {
  481. PyObject *pcpus = NULL, *pthreads = NULL;
  482. struct cpu_map *cpus;
  483. struct thread_map *threads;
  484. if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
  485. return -1;
  486. threads = ((struct pyrf_thread_map *)pthreads)->threads;
  487. cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
  488. perf_evlist__init(&pevlist->evlist, cpus, threads);
  489. return 0;
  490. }
  491. static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
  492. {
  493. perf_evlist__exit(&pevlist->evlist);
  494. pevlist->ob_type->tp_free((PyObject*)pevlist);
  495. }
  496. static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
  497. PyObject *args, PyObject *kwargs)
  498. {
  499. struct perf_evlist *evlist = &pevlist->evlist;
  500. static char *kwlist[] = {"pages", "overwrite",
  501. NULL, NULL};
  502. int pages = 128, overwrite = false;
  503. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
  504. &pages, &overwrite))
  505. return NULL;
  506. if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
  507. PyErr_SetFromErrno(PyExc_OSError);
  508. return NULL;
  509. }
  510. Py_INCREF(Py_None);
  511. return Py_None;
  512. }
  513. static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
  514. PyObject *args, PyObject *kwargs)
  515. {
  516. struct perf_evlist *evlist = &pevlist->evlist;
  517. static char *kwlist[] = {"timeout", NULL, NULL};
  518. int timeout = -1, n;
  519. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
  520. return NULL;
  521. n = poll(evlist->pollfd, evlist->nr_fds, timeout);
  522. if (n < 0) {
  523. PyErr_SetFromErrno(PyExc_OSError);
  524. return NULL;
  525. }
  526. return Py_BuildValue("i", n);
  527. }
  528. static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
  529. PyObject *args __used, PyObject *kwargs __used)
  530. {
  531. struct perf_evlist *evlist = &pevlist->evlist;
  532. PyObject *list = PyList_New(0);
  533. int i;
  534. for (i = 0; i < evlist->nr_fds; ++i) {
  535. PyObject *file;
  536. FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
  537. if (fp == NULL)
  538. goto free_list;
  539. file = PyFile_FromFile(fp, "perf", "r", NULL);
  540. if (file == NULL)
  541. goto free_list;
  542. if (PyList_Append(list, file) != 0) {
  543. Py_DECREF(file);
  544. goto free_list;
  545. }
  546. Py_DECREF(file);
  547. }
  548. return list;
  549. free_list:
  550. return PyErr_NoMemory();
  551. }
  552. static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
  553. PyObject *args, PyObject *kwargs __used)
  554. {
  555. struct perf_evlist *evlist = &pevlist->evlist;
  556. PyObject *pevsel;
  557. struct perf_evsel *evsel;
  558. if (!PyArg_ParseTuple(args, "O", &pevsel))
  559. return NULL;
  560. Py_INCREF(pevsel);
  561. evsel = &((struct pyrf_evsel *)pevsel)->evsel;
  562. evsel->idx = evlist->nr_entries;
  563. perf_evlist__add(evlist, evsel);
  564. return Py_BuildValue("i", evlist->nr_entries);
  565. }
  566. static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
  567. PyObject *args, PyObject *kwargs)
  568. {
  569. struct perf_evlist *evlist = &pevlist->evlist;
  570. union perf_event *event;
  571. int sample_id_all = 1, cpu;
  572. static char *kwlist[] = {"cpu", "sample_id_all", NULL, NULL};
  573. int err;
  574. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
  575. &cpu, &sample_id_all))
  576. return NULL;
  577. event = perf_evlist__mmap_read(evlist, cpu);
  578. if (event != NULL) {
  579. struct perf_evsel *first;
  580. PyObject *pyevent = pyrf_event__new(event);
  581. struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
  582. if (pyevent == NULL)
  583. return PyErr_NoMemory();
  584. first = list_entry(evlist->entries.next, struct perf_evsel, node);
  585. err = perf_event__parse_sample(event, first->attr.sample_type,
  586. perf_evsel__sample_size(first),
  587. sample_id_all, &pevent->sample);
  588. if (err)
  589. return PyErr_Format(PyExc_OSError,
  590. "perf: can't parse sample, err=%d", err);
  591. return pyevent;
  592. }
  593. Py_INCREF(Py_None);
  594. return Py_None;
  595. }
  596. static PyMethodDef pyrf_evlist__methods[] = {
  597. {
  598. .ml_name = "mmap",
  599. .ml_meth = (PyCFunction)pyrf_evlist__mmap,
  600. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  601. .ml_doc = PyDoc_STR("mmap the file descriptor table.")
  602. },
  603. {
  604. .ml_name = "poll",
  605. .ml_meth = (PyCFunction)pyrf_evlist__poll,
  606. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  607. .ml_doc = PyDoc_STR("poll the file descriptor table.")
  608. },
  609. {
  610. .ml_name = "get_pollfd",
  611. .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
  612. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  613. .ml_doc = PyDoc_STR("get the poll file descriptor table.")
  614. },
  615. {
  616. .ml_name = "add",
  617. .ml_meth = (PyCFunction)pyrf_evlist__add,
  618. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  619. .ml_doc = PyDoc_STR("adds an event selector to the list.")
  620. },
  621. {
  622. .ml_name = "read_on_cpu",
  623. .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
  624. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  625. .ml_doc = PyDoc_STR("reads an event.")
  626. },
  627. { .ml_name = NULL, }
  628. };
  629. static Py_ssize_t pyrf_evlist__length(PyObject *obj)
  630. {
  631. struct pyrf_evlist *pevlist = (void *)obj;
  632. return pevlist->evlist.nr_entries;
  633. }
  634. static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
  635. {
  636. struct pyrf_evlist *pevlist = (void *)obj;
  637. struct perf_evsel *pos;
  638. if (i >= pevlist->evlist.nr_entries)
  639. return NULL;
  640. list_for_each_entry(pos, &pevlist->evlist.entries, node)
  641. if (i-- == 0)
  642. break;
  643. return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
  644. }
  645. static PySequenceMethods pyrf_evlist__sequence_methods = {
  646. .sq_length = pyrf_evlist__length,
  647. .sq_item = pyrf_evlist__item,
  648. };
  649. static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
  650. static PyTypeObject pyrf_evlist__type = {
  651. PyVarObject_HEAD_INIT(NULL, 0)
  652. .tp_name = "perf.evlist",
  653. .tp_basicsize = sizeof(struct pyrf_evlist),
  654. .tp_dealloc = (destructor)pyrf_evlist__delete,
  655. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  656. .tp_as_sequence = &pyrf_evlist__sequence_methods,
  657. .tp_doc = pyrf_evlist__doc,
  658. .tp_methods = pyrf_evlist__methods,
  659. .tp_init = (initproc)pyrf_evlist__init,
  660. };
  661. static int pyrf_evlist__setup_types(void)
  662. {
  663. pyrf_evlist__type.tp_new = PyType_GenericNew;
  664. return PyType_Ready(&pyrf_evlist__type);
  665. }
  666. static struct {
  667. const char *name;
  668. int value;
  669. } perf__constants[] = {
  670. { "TYPE_HARDWARE", PERF_TYPE_HARDWARE },
  671. { "TYPE_SOFTWARE", PERF_TYPE_SOFTWARE },
  672. { "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
  673. { "TYPE_HW_CACHE", PERF_TYPE_HW_CACHE },
  674. { "TYPE_RAW", PERF_TYPE_RAW },
  675. { "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
  676. { "COUNT_HW_CPU_CYCLES", PERF_COUNT_HW_CPU_CYCLES },
  677. { "COUNT_HW_INSTRUCTIONS", PERF_COUNT_HW_INSTRUCTIONS },
  678. { "COUNT_HW_CACHE_REFERENCES", PERF_COUNT_HW_CACHE_REFERENCES },
  679. { "COUNT_HW_CACHE_MISSES", PERF_COUNT_HW_CACHE_MISSES },
  680. { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
  681. { "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES },
  682. { "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES },
  683. { "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D },
  684. { "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I },
  685. { "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL },
  686. { "COUNT_HW_CACHE_DTLB", PERF_COUNT_HW_CACHE_DTLB },
  687. { "COUNT_HW_CACHE_ITLB", PERF_COUNT_HW_CACHE_ITLB },
  688. { "COUNT_HW_CACHE_BPU", PERF_COUNT_HW_CACHE_BPU },
  689. { "COUNT_HW_CACHE_OP_READ", PERF_COUNT_HW_CACHE_OP_READ },
  690. { "COUNT_HW_CACHE_OP_WRITE", PERF_COUNT_HW_CACHE_OP_WRITE },
  691. { "COUNT_HW_CACHE_OP_PREFETCH", PERF_COUNT_HW_CACHE_OP_PREFETCH },
  692. { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
  693. { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS },
  694. { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
  695. { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
  696. { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK },
  697. { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK },
  698. { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS },
  699. { "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
  700. { "COUNT_SW_CPU_MIGRATIONS", PERF_COUNT_SW_CPU_MIGRATIONS },
  701. { "COUNT_SW_PAGE_FAULTS_MIN", PERF_COUNT_SW_PAGE_FAULTS_MIN },
  702. { "COUNT_SW_PAGE_FAULTS_MAJ", PERF_COUNT_SW_PAGE_FAULTS_MAJ },
  703. { "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
  704. { "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
  705. { "SAMPLE_IP", PERF_SAMPLE_IP },
  706. { "SAMPLE_TID", PERF_SAMPLE_TID },
  707. { "SAMPLE_TIME", PERF_SAMPLE_TIME },
  708. { "SAMPLE_ADDR", PERF_SAMPLE_ADDR },
  709. { "SAMPLE_READ", PERF_SAMPLE_READ },
  710. { "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
  711. { "SAMPLE_ID", PERF_SAMPLE_ID },
  712. { "SAMPLE_CPU", PERF_SAMPLE_CPU },
  713. { "SAMPLE_PERIOD", PERF_SAMPLE_PERIOD },
  714. { "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
  715. { "SAMPLE_RAW", PERF_SAMPLE_RAW },
  716. { "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
  717. { "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
  718. { "FORMAT_ID", PERF_FORMAT_ID },
  719. { "FORMAT_GROUP", PERF_FORMAT_GROUP },
  720. { "RECORD_MMAP", PERF_RECORD_MMAP },
  721. { "RECORD_LOST", PERF_RECORD_LOST },
  722. { "RECORD_COMM", PERF_RECORD_COMM },
  723. { "RECORD_EXIT", PERF_RECORD_EXIT },
  724. { "RECORD_THROTTLE", PERF_RECORD_THROTTLE },
  725. { "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
  726. { "RECORD_FORK", PERF_RECORD_FORK },
  727. { "RECORD_READ", PERF_RECORD_READ },
  728. { "RECORD_SAMPLE", PERF_RECORD_SAMPLE },
  729. { .name = NULL, },
  730. };
  731. static PyMethodDef perf__methods[] = {
  732. { .ml_name = NULL, }
  733. };
  734. PyMODINIT_FUNC initperf(void)
  735. {
  736. PyObject *obj;
  737. int i;
  738. PyObject *dict, *module = Py_InitModule("perf", perf__methods);
  739. if (module == NULL ||
  740. pyrf_event__setup_types() < 0 ||
  741. pyrf_evlist__setup_types() < 0 ||
  742. pyrf_evsel__setup_types() < 0 ||
  743. pyrf_thread_map__setup_types() < 0 ||
  744. pyrf_cpu_map__setup_types() < 0)
  745. return;
  746. Py_INCREF(&pyrf_evlist__type);
  747. PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
  748. Py_INCREF(&pyrf_evsel__type);
  749. PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
  750. Py_INCREF(&pyrf_thread_map__type);
  751. PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
  752. Py_INCREF(&pyrf_cpu_map__type);
  753. PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
  754. dict = PyModule_GetDict(module);
  755. if (dict == NULL)
  756. goto error;
  757. for (i = 0; perf__constants[i].name != NULL; i++) {
  758. obj = PyInt_FromLong(perf__constants[i].value);
  759. if (obj == NULL)
  760. goto error;
  761. PyDict_SetItemString(dict, perf__constants[i].name, obj);
  762. Py_DECREF(obj);
  763. }
  764. error:
  765. if (PyErr_Occurred())
  766. PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
  767. }