python.c 31 KB

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