python.c 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <Python.h>
  3. #include <structmember.h>
  4. #include <inttypes.h>
  5. #include <poll.h>
  6. #include <linux/err.h>
  7. #include <perf/cpumap.h>
  8. #ifdef HAVE_LIBTRACEEVENT
  9. #include <event-parse.h>
  10. #endif
  11. #include <perf/mmap.h>
  12. #include "callchain.h"
  13. #include "counts.h"
  14. #include "evlist.h"
  15. #include "evsel.h"
  16. #include "event.h"
  17. #include "expr.h"
  18. #include "print_binary.h"
  19. #include "record.h"
  20. #include "strbuf.h"
  21. #include "thread_map.h"
  22. #include "tp_pmu.h"
  23. #include "trace-event.h"
  24. #include "metricgroup.h"
  25. #include "mmap.h"
  26. #include "util/sample.h"
  27. #include <internal/lib.h>
  28. PyMODINIT_FUNC PyInit_perf(void);
  29. #define member_def(type, member, ptype, help) \
  30. { #member, ptype, \
  31. offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
  32. 0, help }
  33. #define sample_member_def(name, member, ptype, help) \
  34. { #name, ptype, \
  35. offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
  36. 0, help }
  37. struct pyrf_event {
  38. PyObject_HEAD
  39. struct evsel *evsel;
  40. struct perf_sample sample;
  41. union perf_event event;
  42. };
  43. #define sample_members \
  44. sample_member_def(sample_ip, ip, T_ULONGLONG, "event ip"), \
  45. sample_member_def(sample_pid, pid, T_INT, "event pid"), \
  46. sample_member_def(sample_tid, tid, T_INT, "event tid"), \
  47. sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
  48. sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
  49. sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
  50. sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
  51. sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
  52. sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
  53. static const char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
  54. static PyMemberDef pyrf_mmap_event__members[] = {
  55. sample_members
  56. member_def(perf_event_header, type, T_UINT, "event type"),
  57. member_def(perf_event_header, misc, T_UINT, "event misc"),
  58. member_def(perf_record_mmap, pid, T_UINT, "event pid"),
  59. member_def(perf_record_mmap, tid, T_UINT, "event tid"),
  60. member_def(perf_record_mmap, start, T_ULONGLONG, "start of the map"),
  61. member_def(perf_record_mmap, len, T_ULONGLONG, "map length"),
  62. member_def(perf_record_mmap, pgoff, T_ULONGLONG, "page offset"),
  63. member_def(perf_record_mmap, filename, T_STRING_INPLACE, "backing store"),
  64. { .name = NULL, },
  65. };
  66. static PyObject *pyrf_mmap_event__repr(const struct pyrf_event *pevent)
  67. {
  68. PyObject *ret;
  69. char *s;
  70. if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRI_lx64 ", "
  71. "length: %#" PRI_lx64 ", offset: %#" PRI_lx64 ", "
  72. "filename: %s }",
  73. pevent->event.mmap.pid, pevent->event.mmap.tid,
  74. pevent->event.mmap.start, pevent->event.mmap.len,
  75. pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
  76. ret = PyErr_NoMemory();
  77. } else {
  78. ret = PyUnicode_FromString(s);
  79. free(s);
  80. }
  81. return ret;
  82. }
  83. static PyTypeObject pyrf_mmap_event__type = {
  84. PyVarObject_HEAD_INIT(NULL, 0)
  85. .tp_name = "perf.mmap_event",
  86. .tp_basicsize = sizeof(struct pyrf_event),
  87. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  88. .tp_doc = pyrf_mmap_event__doc,
  89. .tp_members = pyrf_mmap_event__members,
  90. .tp_repr = (reprfunc)pyrf_mmap_event__repr,
  91. };
  92. static const char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
  93. static PyMemberDef pyrf_task_event__members[] = {
  94. sample_members
  95. member_def(perf_event_header, type, T_UINT, "event type"),
  96. member_def(perf_record_fork, pid, T_UINT, "event pid"),
  97. member_def(perf_record_fork, ppid, T_UINT, "event ppid"),
  98. member_def(perf_record_fork, tid, T_UINT, "event tid"),
  99. member_def(perf_record_fork, ptid, T_UINT, "event ptid"),
  100. member_def(perf_record_fork, time, T_ULONGLONG, "timestamp"),
  101. { .name = NULL, },
  102. };
  103. static PyObject *pyrf_task_event__repr(const struct pyrf_event *pevent)
  104. {
  105. return PyUnicode_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
  106. "ptid: %u, time: %" PRI_lu64 "}",
  107. pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
  108. pevent->event.fork.pid,
  109. pevent->event.fork.ppid,
  110. pevent->event.fork.tid,
  111. pevent->event.fork.ptid,
  112. pevent->event.fork.time);
  113. }
  114. static PyTypeObject pyrf_task_event__type = {
  115. PyVarObject_HEAD_INIT(NULL, 0)
  116. .tp_name = "perf.task_event",
  117. .tp_basicsize = sizeof(struct pyrf_event),
  118. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  119. .tp_doc = pyrf_task_event__doc,
  120. .tp_members = pyrf_task_event__members,
  121. .tp_repr = (reprfunc)pyrf_task_event__repr,
  122. };
  123. static const char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
  124. static PyMemberDef pyrf_comm_event__members[] = {
  125. sample_members
  126. member_def(perf_event_header, type, T_UINT, "event type"),
  127. member_def(perf_record_comm, pid, T_UINT, "event pid"),
  128. member_def(perf_record_comm, tid, T_UINT, "event tid"),
  129. member_def(perf_record_comm, comm, T_STRING_INPLACE, "process name"),
  130. { .name = NULL, },
  131. };
  132. static PyObject *pyrf_comm_event__repr(const struct pyrf_event *pevent)
  133. {
  134. return PyUnicode_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
  135. pevent->event.comm.pid,
  136. pevent->event.comm.tid,
  137. pevent->event.comm.comm);
  138. }
  139. static PyTypeObject pyrf_comm_event__type = {
  140. PyVarObject_HEAD_INIT(NULL, 0)
  141. .tp_name = "perf.comm_event",
  142. .tp_basicsize = sizeof(struct pyrf_event),
  143. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  144. .tp_doc = pyrf_comm_event__doc,
  145. .tp_members = pyrf_comm_event__members,
  146. .tp_repr = (reprfunc)pyrf_comm_event__repr,
  147. };
  148. static const char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
  149. static PyMemberDef pyrf_throttle_event__members[] = {
  150. sample_members
  151. member_def(perf_event_header, type, T_UINT, "event type"),
  152. member_def(perf_record_throttle, time, T_ULONGLONG, "timestamp"),
  153. member_def(perf_record_throttle, id, T_ULONGLONG, "event id"),
  154. member_def(perf_record_throttle, stream_id, T_ULONGLONG, "event stream id"),
  155. { .name = NULL, },
  156. };
  157. static PyObject *pyrf_throttle_event__repr(const struct pyrf_event *pevent)
  158. {
  159. const struct perf_record_throttle *te = (const struct perf_record_throttle *)
  160. (&pevent->event.header + 1);
  161. return PyUnicode_FromFormat("{ type: %sthrottle, time: %" PRI_lu64 ", id: %" PRI_lu64
  162. ", stream_id: %" PRI_lu64 " }",
  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 const char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
  176. static PyMemberDef pyrf_lost_event__members[] = {
  177. sample_members
  178. member_def(perf_record_lost, id, T_ULONGLONG, "event id"),
  179. member_def(perf_record_lost, lost, T_ULONGLONG, "number of lost events"),
  180. { .name = NULL, },
  181. };
  182. static PyObject *pyrf_lost_event__repr(const struct pyrf_event *pevent)
  183. {
  184. PyObject *ret;
  185. char *s;
  186. if (asprintf(&s, "{ type: lost, id: %#" PRI_lx64 ", "
  187. "lost: %#" PRI_lx64 " }",
  188. pevent->event.lost.id, pevent->event.lost.lost) < 0) {
  189. ret = PyErr_NoMemory();
  190. } else {
  191. ret = PyUnicode_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 const char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
  206. static PyMemberDef pyrf_read_event__members[] = {
  207. sample_members
  208. member_def(perf_record_read, pid, T_UINT, "event pid"),
  209. member_def(perf_record_read, tid, T_UINT, "event tid"),
  210. { .name = NULL, },
  211. };
  212. static PyObject *pyrf_read_event__repr(const struct pyrf_event *pevent)
  213. {
  214. return PyUnicode_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 const 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 void pyrf_sample_event__delete(struct pyrf_event *pevent)
  238. {
  239. perf_sample__exit(&pevent->sample);
  240. Py_TYPE(pevent)->tp_free((PyObject*)pevent);
  241. }
  242. static PyObject *pyrf_sample_event__repr(const struct pyrf_event *pevent)
  243. {
  244. PyObject *ret;
  245. char *s;
  246. if (asprintf(&s, "{ type: sample }") < 0) {
  247. ret = PyErr_NoMemory();
  248. } else {
  249. ret = PyUnicode_FromString(s);
  250. free(s);
  251. }
  252. return ret;
  253. }
  254. #ifdef HAVE_LIBTRACEEVENT
  255. static bool is_tracepoint(const struct pyrf_event *pevent)
  256. {
  257. return pevent->evsel->core.attr.type == PERF_TYPE_TRACEPOINT;
  258. }
  259. static PyObject*
  260. tracepoint_field(const struct pyrf_event *pe, struct tep_format_field *field)
  261. {
  262. struct tep_handle *pevent = field->event->tep;
  263. void *data = pe->sample.raw_data;
  264. PyObject *ret = NULL;
  265. unsigned long long val;
  266. unsigned int offset, len;
  267. if (field->flags & TEP_FIELD_IS_ARRAY) {
  268. offset = field->offset;
  269. len = field->size;
  270. if (field->flags & TEP_FIELD_IS_DYNAMIC) {
  271. val = tep_read_number(pevent, data + offset, len);
  272. offset = val;
  273. len = offset >> 16;
  274. offset &= 0xffff;
  275. if (tep_field_is_relative(field->flags))
  276. offset += field->offset + field->size;
  277. }
  278. if (field->flags & TEP_FIELD_IS_STRING &&
  279. is_printable_array(data + offset, len)) {
  280. ret = PyUnicode_FromString((char *)data + offset);
  281. } else {
  282. ret = PyByteArray_FromStringAndSize((const char *) data + offset, len);
  283. field->flags &= ~TEP_FIELD_IS_STRING;
  284. }
  285. } else {
  286. val = tep_read_number(pevent, data + field->offset,
  287. field->size);
  288. if (field->flags & TEP_FIELD_IS_POINTER)
  289. ret = PyLong_FromUnsignedLong((unsigned long) val);
  290. else if (field->flags & TEP_FIELD_IS_SIGNED)
  291. ret = PyLong_FromLong((long) val);
  292. else
  293. ret = PyLong_FromUnsignedLong((unsigned long) val);
  294. }
  295. return ret;
  296. }
  297. static PyObject*
  298. get_tracepoint_field(struct pyrf_event *pevent, PyObject *attr_name)
  299. {
  300. struct evsel *evsel = pevent->evsel;
  301. struct tep_event *tp_format = evsel__tp_format(evsel);
  302. struct tep_format_field *field;
  303. if (IS_ERR_OR_NULL(tp_format))
  304. return NULL;
  305. PyObject *obj = PyObject_Str(attr_name);
  306. if (obj == NULL)
  307. return NULL;
  308. const char *str = PyUnicode_AsUTF8(obj);
  309. if (str == NULL) {
  310. Py_DECREF(obj);
  311. return NULL;
  312. }
  313. field = tep_find_any_field(tp_format, str);
  314. Py_DECREF(obj);
  315. return field ? tracepoint_field(pevent, field) : NULL;
  316. }
  317. #endif /* HAVE_LIBTRACEEVENT */
  318. static PyObject*
  319. pyrf_sample_event__getattro(struct pyrf_event *pevent, PyObject *attr_name)
  320. {
  321. PyObject *obj = NULL;
  322. #ifdef HAVE_LIBTRACEEVENT
  323. if (is_tracepoint(pevent))
  324. obj = get_tracepoint_field(pevent, attr_name);
  325. #endif
  326. return obj ?: PyObject_GenericGetAttr((PyObject *) pevent, attr_name);
  327. }
  328. static PyTypeObject pyrf_sample_event__type = {
  329. PyVarObject_HEAD_INIT(NULL, 0)
  330. .tp_name = "perf.sample_event",
  331. .tp_basicsize = sizeof(struct pyrf_event),
  332. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  333. .tp_doc = pyrf_sample_event__doc,
  334. .tp_members = pyrf_sample_event__members,
  335. .tp_repr = (reprfunc)pyrf_sample_event__repr,
  336. .tp_getattro = (getattrofunc) pyrf_sample_event__getattro,
  337. };
  338. static const char pyrf_context_switch_event__doc[] = PyDoc_STR("perf context_switch event object.");
  339. static PyMemberDef pyrf_context_switch_event__members[] = {
  340. sample_members
  341. member_def(perf_event_header, type, T_UINT, "event type"),
  342. member_def(perf_record_switch, next_prev_pid, T_UINT, "next/prev pid"),
  343. member_def(perf_record_switch, next_prev_tid, T_UINT, "next/prev tid"),
  344. { .name = NULL, },
  345. };
  346. static PyObject *pyrf_context_switch_event__repr(const struct pyrf_event *pevent)
  347. {
  348. PyObject *ret;
  349. char *s;
  350. if (asprintf(&s, "{ type: context_switch, next_prev_pid: %u, next_prev_tid: %u, switch_out: %u }",
  351. pevent->event.context_switch.next_prev_pid,
  352. pevent->event.context_switch.next_prev_tid,
  353. !!(pevent->event.header.misc & PERF_RECORD_MISC_SWITCH_OUT)) < 0) {
  354. ret = PyErr_NoMemory();
  355. } else {
  356. ret = PyUnicode_FromString(s);
  357. free(s);
  358. }
  359. return ret;
  360. }
  361. static PyTypeObject pyrf_context_switch_event__type = {
  362. PyVarObject_HEAD_INIT(NULL, 0)
  363. .tp_name = "perf.context_switch_event",
  364. .tp_basicsize = sizeof(struct pyrf_event),
  365. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  366. .tp_doc = pyrf_context_switch_event__doc,
  367. .tp_members = pyrf_context_switch_event__members,
  368. .tp_repr = (reprfunc)pyrf_context_switch_event__repr,
  369. };
  370. static int pyrf_event__setup_types(void)
  371. {
  372. int err;
  373. pyrf_mmap_event__type.tp_new =
  374. pyrf_task_event__type.tp_new =
  375. pyrf_comm_event__type.tp_new =
  376. pyrf_lost_event__type.tp_new =
  377. pyrf_read_event__type.tp_new =
  378. pyrf_sample_event__type.tp_new =
  379. pyrf_context_switch_event__type.tp_new =
  380. pyrf_throttle_event__type.tp_new = PyType_GenericNew;
  381. pyrf_sample_event__type.tp_dealloc = (destructor)pyrf_sample_event__delete,
  382. err = PyType_Ready(&pyrf_mmap_event__type);
  383. if (err < 0)
  384. goto out;
  385. err = PyType_Ready(&pyrf_lost_event__type);
  386. if (err < 0)
  387. goto out;
  388. err = PyType_Ready(&pyrf_task_event__type);
  389. if (err < 0)
  390. goto out;
  391. err = PyType_Ready(&pyrf_comm_event__type);
  392. if (err < 0)
  393. goto out;
  394. err = PyType_Ready(&pyrf_throttle_event__type);
  395. if (err < 0)
  396. goto out;
  397. err = PyType_Ready(&pyrf_read_event__type);
  398. if (err < 0)
  399. goto out;
  400. err = PyType_Ready(&pyrf_sample_event__type);
  401. if (err < 0)
  402. goto out;
  403. err = PyType_Ready(&pyrf_context_switch_event__type);
  404. if (err < 0)
  405. goto out;
  406. out:
  407. return err;
  408. }
  409. static PyTypeObject *pyrf_event__type[] = {
  410. [PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
  411. [PERF_RECORD_LOST] = &pyrf_lost_event__type,
  412. [PERF_RECORD_COMM] = &pyrf_comm_event__type,
  413. [PERF_RECORD_EXIT] = &pyrf_task_event__type,
  414. [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
  415. [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
  416. [PERF_RECORD_FORK] = &pyrf_task_event__type,
  417. [PERF_RECORD_READ] = &pyrf_read_event__type,
  418. [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
  419. [PERF_RECORD_SWITCH] = &pyrf_context_switch_event__type,
  420. [PERF_RECORD_SWITCH_CPU_WIDE] = &pyrf_context_switch_event__type,
  421. };
  422. static PyObject *pyrf_event__new(const union perf_event *event)
  423. {
  424. struct pyrf_event *pevent;
  425. PyTypeObject *ptype;
  426. if ((event->header.type < PERF_RECORD_MMAP ||
  427. event->header.type > PERF_RECORD_SAMPLE) &&
  428. !(event->header.type == PERF_RECORD_SWITCH ||
  429. event->header.type == PERF_RECORD_SWITCH_CPU_WIDE)) {
  430. PyErr_Format(PyExc_TypeError, "Unexpected header type %u",
  431. event->header.type);
  432. return NULL;
  433. }
  434. // FIXME this better be dynamic or we need to parse everything
  435. // before calling perf_mmap__consume(), including tracepoint fields.
  436. if (sizeof(pevent->event) < event->header.size) {
  437. PyErr_Format(PyExc_TypeError, "Unexpected event size: %zd < %u",
  438. sizeof(pevent->event), event->header.size);
  439. return NULL;
  440. }
  441. ptype = pyrf_event__type[event->header.type];
  442. pevent = PyObject_New(struct pyrf_event, ptype);
  443. if (pevent != NULL)
  444. memcpy(&pevent->event, event, event->header.size);
  445. return (PyObject *)pevent;
  446. }
  447. struct pyrf_cpu_map {
  448. PyObject_HEAD
  449. struct perf_cpu_map *cpus;
  450. };
  451. static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
  452. PyObject *args, PyObject *kwargs)
  453. {
  454. static char *kwlist[] = { "cpustr", NULL };
  455. char *cpustr = NULL;
  456. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
  457. kwlist, &cpustr))
  458. return -1;
  459. pcpus->cpus = perf_cpu_map__new(cpustr);
  460. if (pcpus->cpus == NULL)
  461. return -1;
  462. return 0;
  463. }
  464. static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
  465. {
  466. perf_cpu_map__put(pcpus->cpus);
  467. Py_TYPE(pcpus)->tp_free((PyObject*)pcpus);
  468. }
  469. static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
  470. {
  471. struct pyrf_cpu_map *pcpus = (void *)obj;
  472. return perf_cpu_map__nr(pcpus->cpus);
  473. }
  474. static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
  475. {
  476. struct pyrf_cpu_map *pcpus = (void *)obj;
  477. if (i >= perf_cpu_map__nr(pcpus->cpus)) {
  478. PyErr_SetString(PyExc_IndexError, "Index out of range");
  479. return NULL;
  480. }
  481. return Py_BuildValue("i", perf_cpu_map__cpu(pcpus->cpus, i).cpu);
  482. }
  483. static PySequenceMethods pyrf_cpu_map__sequence_methods = {
  484. .sq_length = pyrf_cpu_map__length,
  485. .sq_item = pyrf_cpu_map__item,
  486. };
  487. static const char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
  488. static PyTypeObject pyrf_cpu_map__type = {
  489. PyVarObject_HEAD_INIT(NULL, 0)
  490. .tp_name = "perf.cpu_map",
  491. .tp_basicsize = sizeof(struct pyrf_cpu_map),
  492. .tp_dealloc = (destructor)pyrf_cpu_map__delete,
  493. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  494. .tp_doc = pyrf_cpu_map__doc,
  495. .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
  496. .tp_init = (initproc)pyrf_cpu_map__init,
  497. };
  498. static int pyrf_cpu_map__setup_types(void)
  499. {
  500. pyrf_cpu_map__type.tp_new = PyType_GenericNew;
  501. return PyType_Ready(&pyrf_cpu_map__type);
  502. }
  503. struct pyrf_thread_map {
  504. PyObject_HEAD
  505. struct perf_thread_map *threads;
  506. };
  507. static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
  508. PyObject *args, PyObject *kwargs)
  509. {
  510. static char *kwlist[] = { "pid", "tid", NULL };
  511. int pid = -1, tid = -1;
  512. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
  513. kwlist, &pid, &tid))
  514. return -1;
  515. pthreads->threads = thread_map__new(pid, tid);
  516. if (pthreads->threads == NULL)
  517. return -1;
  518. return 0;
  519. }
  520. static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
  521. {
  522. perf_thread_map__put(pthreads->threads);
  523. Py_TYPE(pthreads)->tp_free((PyObject*)pthreads);
  524. }
  525. static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
  526. {
  527. struct pyrf_thread_map *pthreads = (void *)obj;
  528. return perf_thread_map__nr(pthreads->threads);
  529. }
  530. static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
  531. {
  532. struct pyrf_thread_map *pthreads = (void *)obj;
  533. if (i >= perf_thread_map__nr(pthreads->threads)) {
  534. PyErr_SetString(PyExc_IndexError, "Index out of range");
  535. return NULL;
  536. }
  537. return Py_BuildValue("i", perf_thread_map__pid(pthreads->threads, i));
  538. }
  539. static PySequenceMethods pyrf_thread_map__sequence_methods = {
  540. .sq_length = pyrf_thread_map__length,
  541. .sq_item = pyrf_thread_map__item,
  542. };
  543. static const char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
  544. static PyTypeObject pyrf_thread_map__type = {
  545. PyVarObject_HEAD_INIT(NULL, 0)
  546. .tp_name = "perf.thread_map",
  547. .tp_basicsize = sizeof(struct pyrf_thread_map),
  548. .tp_dealloc = (destructor)pyrf_thread_map__delete,
  549. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  550. .tp_doc = pyrf_thread_map__doc,
  551. .tp_as_sequence = &pyrf_thread_map__sequence_methods,
  552. .tp_init = (initproc)pyrf_thread_map__init,
  553. };
  554. static int pyrf_thread_map__setup_types(void)
  555. {
  556. pyrf_thread_map__type.tp_new = PyType_GenericNew;
  557. return PyType_Ready(&pyrf_thread_map__type);
  558. }
  559. /**
  560. * A python wrapper for perf_pmus that are globally owned by the pmus.c code.
  561. */
  562. struct pyrf_pmu {
  563. PyObject_HEAD
  564. struct perf_pmu *pmu;
  565. };
  566. static void pyrf_pmu__delete(struct pyrf_pmu *ppmu)
  567. {
  568. Py_TYPE(ppmu)->tp_free((PyObject *)ppmu);
  569. }
  570. static PyObject *pyrf_pmu__name(PyObject *self)
  571. {
  572. struct pyrf_pmu *ppmu = (void *)self;
  573. return PyUnicode_FromString(ppmu->pmu->name);
  574. }
  575. static bool add_to_dict(PyObject *dict, const char *key, const char *value)
  576. {
  577. PyObject *pkey, *pvalue;
  578. bool ret;
  579. if (value == NULL)
  580. return true;
  581. pkey = PyUnicode_FromString(key);
  582. pvalue = PyUnicode_FromString(value);
  583. ret = pkey && pvalue && PyDict_SetItem(dict, pkey, pvalue) == 0;
  584. Py_XDECREF(pkey);
  585. Py_XDECREF(pvalue);
  586. return ret;
  587. }
  588. static int pyrf_pmu__events_cb(void *state, struct pmu_event_info *info)
  589. {
  590. PyObject *py_list = state;
  591. PyObject *dict = PyDict_New();
  592. if (!dict)
  593. return -ENOMEM;
  594. if (!add_to_dict(dict, "name", info->name) ||
  595. !add_to_dict(dict, "alias", info->alias) ||
  596. !add_to_dict(dict, "scale_unit", info->scale_unit) ||
  597. !add_to_dict(dict, "desc", info->desc) ||
  598. !add_to_dict(dict, "long_desc", info->long_desc) ||
  599. !add_to_dict(dict, "encoding_desc", info->encoding_desc) ||
  600. !add_to_dict(dict, "topic", info->topic) ||
  601. !add_to_dict(dict, "event_type_desc", info->event_type_desc) ||
  602. !add_to_dict(dict, "str", info->str) ||
  603. !add_to_dict(dict, "deprecated", info->deprecated ? "deprecated" : NULL) ||
  604. PyList_Append(py_list, dict) != 0) {
  605. Py_DECREF(dict);
  606. return -ENOMEM;
  607. }
  608. Py_DECREF(dict);
  609. return 0;
  610. }
  611. static PyObject *pyrf_pmu__events(PyObject *self)
  612. {
  613. struct pyrf_pmu *ppmu = (void *)self;
  614. PyObject *py_list = PyList_New(0);
  615. int ret;
  616. if (!py_list)
  617. return NULL;
  618. ret = perf_pmu__for_each_event(ppmu->pmu,
  619. /*skip_duplicate_pmus=*/false,
  620. py_list,
  621. pyrf_pmu__events_cb);
  622. if (ret) {
  623. Py_DECREF(py_list);
  624. errno = -ret;
  625. PyErr_SetFromErrno(PyExc_OSError);
  626. return NULL;
  627. }
  628. return py_list;
  629. }
  630. static PyObject *pyrf_pmu__repr(PyObject *self)
  631. {
  632. struct pyrf_pmu *ppmu = (void *)self;
  633. return PyUnicode_FromFormat("pmu(%s)", ppmu->pmu->name);
  634. }
  635. static const char pyrf_pmu__doc[] = PyDoc_STR("perf Performance Monitoring Unit (PMU) object.");
  636. static PyMethodDef pyrf_pmu__methods[] = {
  637. {
  638. .ml_name = "events",
  639. .ml_meth = (PyCFunction)pyrf_pmu__events,
  640. .ml_flags = METH_NOARGS,
  641. .ml_doc = PyDoc_STR("Returns a sequence of events encoded as a dictionaries.")
  642. },
  643. {
  644. .ml_name = "name",
  645. .ml_meth = (PyCFunction)pyrf_pmu__name,
  646. .ml_flags = METH_NOARGS,
  647. .ml_doc = PyDoc_STR("Name of the PMU including suffixes.")
  648. },
  649. { .ml_name = NULL, }
  650. };
  651. /** The python type for a perf.pmu. */
  652. static PyTypeObject pyrf_pmu__type = {
  653. PyVarObject_HEAD_INIT(NULL, 0)
  654. .tp_name = "perf.pmu",
  655. .tp_basicsize = sizeof(struct pyrf_pmu),
  656. .tp_dealloc = (destructor)pyrf_pmu__delete,
  657. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  658. .tp_doc = pyrf_pmu__doc,
  659. .tp_methods = pyrf_pmu__methods,
  660. .tp_str = pyrf_pmu__name,
  661. .tp_repr = pyrf_pmu__repr,
  662. };
  663. static int pyrf_pmu__setup_types(void)
  664. {
  665. pyrf_pmu__type.tp_new = PyType_GenericNew;
  666. return PyType_Ready(&pyrf_pmu__type);
  667. }
  668. /** A python iterator for pmus that has no equivalent in the C code. */
  669. struct pyrf_pmu_iterator {
  670. PyObject_HEAD
  671. struct perf_pmu *pmu;
  672. };
  673. static void pyrf_pmu_iterator__dealloc(struct pyrf_pmu_iterator *self)
  674. {
  675. Py_TYPE(self)->tp_free((PyObject *) self);
  676. }
  677. static PyObject *pyrf_pmu_iterator__new(PyTypeObject *type, PyObject *args __maybe_unused,
  678. PyObject *kwds __maybe_unused)
  679. {
  680. struct pyrf_pmu_iterator *itr = (void *)type->tp_alloc(type, 0);
  681. if (itr != NULL)
  682. itr->pmu = perf_pmus__scan(/*pmu=*/NULL);
  683. return (PyObject *) itr;
  684. }
  685. static PyObject *pyrf_pmu_iterator__iter(PyObject *self)
  686. {
  687. Py_INCREF(self);
  688. return self;
  689. }
  690. static PyObject *pyrf_pmu_iterator__iternext(PyObject *self)
  691. {
  692. struct pyrf_pmu_iterator *itr = (void *)self;
  693. struct pyrf_pmu *ppmu;
  694. if (itr->pmu == NULL) {
  695. PyErr_SetNone(PyExc_StopIteration);
  696. return NULL;
  697. }
  698. // Create object to return.
  699. ppmu = PyObject_New(struct pyrf_pmu, &pyrf_pmu__type);
  700. if (ppmu) {
  701. ppmu->pmu = itr->pmu;
  702. // Advance iterator.
  703. itr->pmu = perf_pmus__scan(itr->pmu);
  704. }
  705. return (PyObject *)ppmu;
  706. }
  707. /** The python type for the PMU iterator. */
  708. static PyTypeObject pyrf_pmu_iterator__type = {
  709. PyVarObject_HEAD_INIT(NULL, 0)
  710. .tp_name = "pmus.iterator",
  711. .tp_doc = "Iterator for the pmus string sequence.",
  712. .tp_basicsize = sizeof(struct pyrf_pmu_iterator),
  713. .tp_itemsize = 0,
  714. .tp_flags = Py_TPFLAGS_DEFAULT,
  715. .tp_new = pyrf_pmu_iterator__new,
  716. .tp_dealloc = (destructor) pyrf_pmu_iterator__dealloc,
  717. .tp_iter = pyrf_pmu_iterator__iter,
  718. .tp_iternext = pyrf_pmu_iterator__iternext,
  719. };
  720. static int pyrf_pmu_iterator__setup_types(void)
  721. {
  722. return PyType_Ready(&pyrf_pmu_iterator__type);
  723. }
  724. static PyObject *pyrf__pmus(PyObject *self, PyObject *args)
  725. {
  726. // Calling the class creates an instance of the iterator.
  727. return PyObject_CallObject((PyObject *) &pyrf_pmu_iterator__type, /*args=*/NULL);
  728. }
  729. struct pyrf_counts_values {
  730. PyObject_HEAD
  731. struct perf_counts_values values;
  732. };
  733. static const char pyrf_counts_values__doc[] = PyDoc_STR("perf counts values object.");
  734. static void pyrf_counts_values__delete(struct pyrf_counts_values *pcounts_values)
  735. {
  736. Py_TYPE(pcounts_values)->tp_free((PyObject *)pcounts_values);
  737. }
  738. #define counts_values_member_def(member, ptype, help) \
  739. { #member, ptype, \
  740. offsetof(struct pyrf_counts_values, values.member), \
  741. 0, help }
  742. static PyMemberDef pyrf_counts_values_members[] = {
  743. counts_values_member_def(val, T_ULONG, "Value of event"),
  744. counts_values_member_def(ena, T_ULONG, "Time for which enabled"),
  745. counts_values_member_def(run, T_ULONG, "Time for which running"),
  746. counts_values_member_def(id, T_ULONG, "Unique ID for an event"),
  747. counts_values_member_def(lost, T_ULONG, "Num of lost samples"),
  748. { .name = NULL, },
  749. };
  750. static PyObject *pyrf_counts_values_get_values(struct pyrf_counts_values *self, void *closure)
  751. {
  752. PyObject *vals = PyList_New(5);
  753. if (!vals)
  754. return NULL;
  755. for (int i = 0; i < 5; i++)
  756. PyList_SetItem(vals, i, PyLong_FromLong(self->values.values[i]));
  757. return vals;
  758. }
  759. static int pyrf_counts_values_set_values(struct pyrf_counts_values *self, PyObject *list,
  760. void *closure)
  761. {
  762. Py_ssize_t size;
  763. PyObject *item = NULL;
  764. if (!PyList_Check(list)) {
  765. PyErr_SetString(PyExc_TypeError, "Value assigned must be a list");
  766. return -1;
  767. }
  768. size = PyList_Size(list);
  769. for (Py_ssize_t i = 0; i < size; i++) {
  770. item = PyList_GetItem(list, i);
  771. if (!PyLong_Check(item)) {
  772. PyErr_SetString(PyExc_TypeError, "List members should be numbers");
  773. return -1;
  774. }
  775. self->values.values[i] = PyLong_AsLong(item);
  776. }
  777. return 0;
  778. }
  779. static PyGetSetDef pyrf_counts_values_getset[] = {
  780. {"values", (getter)pyrf_counts_values_get_values, (setter)pyrf_counts_values_set_values,
  781. "Name field", NULL},
  782. { .name = NULL, },
  783. };
  784. static PyTypeObject pyrf_counts_values__type = {
  785. PyVarObject_HEAD_INIT(NULL, 0)
  786. .tp_name = "perf.counts_values",
  787. .tp_basicsize = sizeof(struct pyrf_counts_values),
  788. .tp_dealloc = (destructor)pyrf_counts_values__delete,
  789. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  790. .tp_doc = pyrf_counts_values__doc,
  791. .tp_members = pyrf_counts_values_members,
  792. .tp_getset = pyrf_counts_values_getset,
  793. };
  794. static int pyrf_counts_values__setup_types(void)
  795. {
  796. pyrf_counts_values__type.tp_new = PyType_GenericNew;
  797. return PyType_Ready(&pyrf_counts_values__type);
  798. }
  799. struct pyrf_evsel {
  800. PyObject_HEAD
  801. struct evsel evsel;
  802. };
  803. static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
  804. PyObject *args, PyObject *kwargs)
  805. {
  806. struct perf_event_attr attr = {
  807. .type = PERF_TYPE_HARDWARE,
  808. .config = PERF_COUNT_HW_CPU_CYCLES,
  809. .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
  810. };
  811. static char *kwlist[] = {
  812. "type",
  813. "config",
  814. "sample_freq",
  815. "sample_period",
  816. "sample_type",
  817. "read_format",
  818. "disabled",
  819. "inherit",
  820. "pinned",
  821. "exclusive",
  822. "exclude_user",
  823. "exclude_kernel",
  824. "exclude_hv",
  825. "exclude_idle",
  826. "mmap",
  827. "context_switch",
  828. "comm",
  829. "freq",
  830. "inherit_stat",
  831. "enable_on_exec",
  832. "task",
  833. "watermark",
  834. "precise_ip",
  835. "mmap_data",
  836. "sample_id_all",
  837. "wakeup_events",
  838. "bp_type",
  839. "bp_addr",
  840. "bp_len",
  841. NULL
  842. };
  843. u64 sample_period = 0;
  844. u32 disabled = 0,
  845. inherit = 0,
  846. pinned = 0,
  847. exclusive = 0,
  848. exclude_user = 0,
  849. exclude_kernel = 0,
  850. exclude_hv = 0,
  851. exclude_idle = 0,
  852. mmap = 0,
  853. context_switch = 0,
  854. comm = 0,
  855. freq = 1,
  856. inherit_stat = 0,
  857. enable_on_exec = 0,
  858. task = 0,
  859. watermark = 0,
  860. precise_ip = 0,
  861. mmap_data = 0,
  862. sample_id_all = 1;
  863. int idx = 0;
  864. if (!PyArg_ParseTupleAndKeywords(args, kwargs,
  865. "|iKiKKiiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
  866. &attr.type, &attr.config, &attr.sample_freq,
  867. &sample_period, &attr.sample_type,
  868. &attr.read_format, &disabled, &inherit,
  869. &pinned, &exclusive, &exclude_user,
  870. &exclude_kernel, &exclude_hv, &exclude_idle,
  871. &mmap, &context_switch, &comm, &freq, &inherit_stat,
  872. &enable_on_exec, &task, &watermark,
  873. &precise_ip, &mmap_data, &sample_id_all,
  874. &attr.wakeup_events, &attr.bp_type,
  875. &attr.bp_addr, &attr.bp_len, &idx))
  876. return -1;
  877. /* union... */
  878. if (sample_period != 0) {
  879. if (attr.sample_freq != 0)
  880. return -1; /* FIXME: throw right exception */
  881. attr.sample_period = sample_period;
  882. }
  883. /* Bitfields */
  884. attr.disabled = disabled;
  885. attr.inherit = inherit;
  886. attr.pinned = pinned;
  887. attr.exclusive = exclusive;
  888. attr.exclude_user = exclude_user;
  889. attr.exclude_kernel = exclude_kernel;
  890. attr.exclude_hv = exclude_hv;
  891. attr.exclude_idle = exclude_idle;
  892. attr.mmap = mmap;
  893. attr.context_switch = context_switch;
  894. attr.comm = comm;
  895. attr.freq = freq;
  896. attr.inherit_stat = inherit_stat;
  897. attr.enable_on_exec = enable_on_exec;
  898. attr.task = task;
  899. attr.watermark = watermark;
  900. attr.precise_ip = precise_ip;
  901. attr.mmap_data = mmap_data;
  902. attr.sample_id_all = sample_id_all;
  903. attr.size = sizeof(attr);
  904. evsel__init(&pevsel->evsel, &attr, idx);
  905. return 0;
  906. }
  907. static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
  908. {
  909. evsel__exit(&pevsel->evsel);
  910. Py_TYPE(pevsel)->tp_free((PyObject*)pevsel);
  911. }
  912. static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
  913. PyObject *args, PyObject *kwargs)
  914. {
  915. struct evsel *evsel = &pevsel->evsel;
  916. struct perf_cpu_map *cpus = NULL;
  917. struct perf_thread_map *threads = NULL;
  918. PyObject *pcpus = NULL, *pthreads = NULL;
  919. int group = 0, inherit = 0;
  920. static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
  921. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
  922. &pcpus, &pthreads, &group, &inherit))
  923. return NULL;
  924. if (pthreads != NULL)
  925. threads = ((struct pyrf_thread_map *)pthreads)->threads;
  926. if (pcpus != NULL)
  927. cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
  928. evsel->core.attr.inherit = inherit;
  929. /*
  930. * This will group just the fds for this single evsel, to group
  931. * multiple events, use evlist.open().
  932. */
  933. if (evsel__open(evsel, cpus, threads) < 0) {
  934. PyErr_SetFromErrno(PyExc_OSError);
  935. return NULL;
  936. }
  937. Py_INCREF(Py_None);
  938. return Py_None;
  939. }
  940. static PyObject *pyrf_evsel__cpus(struct pyrf_evsel *pevsel)
  941. {
  942. struct pyrf_cpu_map *pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
  943. if (pcpu_map)
  944. pcpu_map->cpus = perf_cpu_map__get(pevsel->evsel.core.cpus);
  945. return (PyObject *)pcpu_map;
  946. }
  947. static PyObject *pyrf_evsel__threads(struct pyrf_evsel *pevsel)
  948. {
  949. struct pyrf_thread_map *pthread_map =
  950. PyObject_New(struct pyrf_thread_map, &pyrf_thread_map__type);
  951. if (pthread_map)
  952. pthread_map->threads = perf_thread_map__get(pevsel->evsel.core.threads);
  953. return (PyObject *)pthread_map;
  954. }
  955. /*
  956. * Ensure evsel's counts and prev_raw_counts are allocated, the latter
  957. * used by tool PMUs to compute the cumulative count as expected by
  958. * stat's process_counter_values.
  959. */
  960. static int evsel__ensure_counts(struct evsel *evsel)
  961. {
  962. int nthreads, ncpus;
  963. if (evsel->counts != NULL)
  964. return 0;
  965. nthreads = perf_thread_map__nr(evsel->core.threads);
  966. ncpus = perf_cpu_map__nr(evsel->core.cpus);
  967. evsel->counts = perf_counts__new(ncpus, nthreads);
  968. if (evsel->counts == NULL)
  969. return -ENOMEM;
  970. evsel->prev_raw_counts = perf_counts__new(ncpus, nthreads);
  971. if (evsel->prev_raw_counts == NULL)
  972. return -ENOMEM;
  973. return 0;
  974. }
  975. static PyObject *pyrf_evsel__read(struct pyrf_evsel *pevsel,
  976. PyObject *args, PyObject *kwargs)
  977. {
  978. struct evsel *evsel = &pevsel->evsel;
  979. int cpu = 0, cpu_idx, thread = 0, thread_idx;
  980. struct perf_counts_values *old_count, *new_count;
  981. struct pyrf_counts_values *count_values = PyObject_New(struct pyrf_counts_values,
  982. &pyrf_counts_values__type);
  983. if (!count_values)
  984. return NULL;
  985. if (!PyArg_ParseTuple(args, "ii", &cpu, &thread))
  986. return NULL;
  987. cpu_idx = perf_cpu_map__idx(evsel->core.cpus, (struct perf_cpu){.cpu = cpu});
  988. if (cpu_idx < 0) {
  989. PyErr_Format(PyExc_TypeError, "CPU %d is not part of evsel's CPUs", cpu);
  990. return NULL;
  991. }
  992. thread_idx = perf_thread_map__idx(evsel->core.threads, thread);
  993. if (thread_idx < 0) {
  994. PyErr_Format(PyExc_TypeError, "Thread %d is not part of evsel's threads",
  995. thread);
  996. return NULL;
  997. }
  998. if (evsel__ensure_counts(evsel))
  999. return PyErr_NoMemory();
  1000. /* Set up pointers to the old and newly read counter values. */
  1001. old_count = perf_counts(evsel->prev_raw_counts, cpu_idx, thread_idx);
  1002. new_count = perf_counts(evsel->counts, cpu_idx, thread_idx);
  1003. /* Update the value in evsel->counts. */
  1004. evsel__read_counter(evsel, cpu_idx, thread_idx);
  1005. /* Copy the value and turn it into the delta from old_count. */
  1006. count_values->values = *new_count;
  1007. count_values->values.val -= old_count->val;
  1008. count_values->values.ena -= old_count->ena;
  1009. count_values->values.run -= old_count->run;
  1010. /* Save the new count over the old_count for the next read. */
  1011. *old_count = *new_count;
  1012. return (PyObject *)count_values;
  1013. }
  1014. static PyObject *pyrf_evsel__str(PyObject *self)
  1015. {
  1016. struct pyrf_evsel *pevsel = (void *)self;
  1017. struct evsel *evsel = &pevsel->evsel;
  1018. return PyUnicode_FromFormat("evsel(%s/%s/)", evsel__pmu_name(evsel), evsel__name(evsel));
  1019. }
  1020. static PyMethodDef pyrf_evsel__methods[] = {
  1021. {
  1022. .ml_name = "open",
  1023. .ml_meth = (PyCFunction)pyrf_evsel__open,
  1024. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1025. .ml_doc = PyDoc_STR("open the event selector file descriptor table.")
  1026. },
  1027. {
  1028. .ml_name = "cpus",
  1029. .ml_meth = (PyCFunction)pyrf_evsel__cpus,
  1030. .ml_flags = METH_NOARGS,
  1031. .ml_doc = PyDoc_STR("CPUs the event is to be used with.")
  1032. },
  1033. {
  1034. .ml_name = "threads",
  1035. .ml_meth = (PyCFunction)pyrf_evsel__threads,
  1036. .ml_flags = METH_NOARGS,
  1037. .ml_doc = PyDoc_STR("threads the event is to be used with.")
  1038. },
  1039. {
  1040. .ml_name = "read",
  1041. .ml_meth = (PyCFunction)pyrf_evsel__read,
  1042. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1043. .ml_doc = PyDoc_STR("read counters")
  1044. },
  1045. { .ml_name = NULL, }
  1046. };
  1047. #define evsel_member_def(member, ptype, help) \
  1048. { #member, ptype, \
  1049. offsetof(struct pyrf_evsel, evsel.member), \
  1050. 0, help }
  1051. #define evsel_attr_member_def(member, ptype, help) \
  1052. { #member, ptype, \
  1053. offsetof(struct pyrf_evsel, evsel.core.attr.member), \
  1054. 0, help }
  1055. static PyMemberDef pyrf_evsel__members[] = {
  1056. evsel_member_def(tracking, T_BOOL, "tracking event."),
  1057. evsel_attr_member_def(type, T_UINT, "attribute type."),
  1058. evsel_attr_member_def(size, T_UINT, "attribute size."),
  1059. evsel_attr_member_def(config, T_ULONGLONG, "attribute config."),
  1060. evsel_attr_member_def(sample_period, T_ULONGLONG, "attribute sample_period."),
  1061. evsel_attr_member_def(sample_type, T_ULONGLONG, "attribute sample_type."),
  1062. evsel_attr_member_def(read_format, T_ULONGLONG, "attribute read_format."),
  1063. evsel_attr_member_def(wakeup_events, T_UINT, "attribute wakeup_events."),
  1064. { .name = NULL, },
  1065. };
  1066. static const char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
  1067. static PyTypeObject pyrf_evsel__type = {
  1068. PyVarObject_HEAD_INIT(NULL, 0)
  1069. .tp_name = "perf.evsel",
  1070. .tp_basicsize = sizeof(struct pyrf_evsel),
  1071. .tp_dealloc = (destructor)pyrf_evsel__delete,
  1072. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  1073. .tp_doc = pyrf_evsel__doc,
  1074. .tp_members = pyrf_evsel__members,
  1075. .tp_methods = pyrf_evsel__methods,
  1076. .tp_init = (initproc)pyrf_evsel__init,
  1077. .tp_str = pyrf_evsel__str,
  1078. .tp_repr = pyrf_evsel__str,
  1079. };
  1080. static int pyrf_evsel__setup_types(void)
  1081. {
  1082. pyrf_evsel__type.tp_new = PyType_GenericNew;
  1083. return PyType_Ready(&pyrf_evsel__type);
  1084. }
  1085. struct pyrf_evlist {
  1086. PyObject_HEAD
  1087. struct evlist evlist;
  1088. };
  1089. static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
  1090. PyObject *args, PyObject *kwargs __maybe_unused)
  1091. {
  1092. PyObject *pcpus = NULL, *pthreads = NULL;
  1093. struct perf_cpu_map *cpus;
  1094. struct perf_thread_map *threads;
  1095. if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
  1096. return -1;
  1097. threads = ((struct pyrf_thread_map *)pthreads)->threads;
  1098. cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
  1099. evlist__init(&pevlist->evlist, cpus, threads);
  1100. return 0;
  1101. }
  1102. static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
  1103. {
  1104. evlist__exit(&pevlist->evlist);
  1105. Py_TYPE(pevlist)->tp_free((PyObject*)pevlist);
  1106. }
  1107. static PyObject *pyrf_evlist__all_cpus(struct pyrf_evlist *pevlist)
  1108. {
  1109. struct pyrf_cpu_map *pcpu_map = PyObject_New(struct pyrf_cpu_map, &pyrf_cpu_map__type);
  1110. if (pcpu_map)
  1111. pcpu_map->cpus = perf_cpu_map__get(pevlist->evlist.core.all_cpus);
  1112. return (PyObject *)pcpu_map;
  1113. }
  1114. static PyObject *pyrf_evlist__metrics(struct pyrf_evlist *pevlist)
  1115. {
  1116. PyObject *list = PyList_New(/*len=*/0);
  1117. struct rb_node *node;
  1118. if (!list)
  1119. return NULL;
  1120. for (node = rb_first_cached(&pevlist->evlist.metric_events.entries); node;
  1121. node = rb_next(node)) {
  1122. struct metric_event *me = container_of(node, struct metric_event, nd);
  1123. struct list_head *pos;
  1124. list_for_each(pos, &me->head) {
  1125. struct metric_expr *expr = container_of(pos, struct metric_expr, nd);
  1126. PyObject *str = PyUnicode_FromString(expr->metric_name);
  1127. if (!str || PyList_Append(list, str) != 0) {
  1128. Py_DECREF(list);
  1129. return NULL;
  1130. }
  1131. Py_DECREF(str);
  1132. }
  1133. }
  1134. return list;
  1135. }
  1136. static int prepare_metric(const struct metric_expr *mexp,
  1137. const struct evsel *evsel,
  1138. struct expr_parse_ctx *pctx,
  1139. int cpu_idx, int thread_idx)
  1140. {
  1141. struct evsel * const *metric_events = mexp->metric_events;
  1142. struct metric_ref *metric_refs = mexp->metric_refs;
  1143. for (int i = 0; metric_events[i]; i++) {
  1144. struct evsel *cur = metric_events[i];
  1145. double val, ena, run;
  1146. int ret, source_count = 0;
  1147. struct perf_counts_values *old_count, *new_count;
  1148. char *n = strdup(evsel__metric_id(cur));
  1149. if (!n)
  1150. return -ENOMEM;
  1151. /*
  1152. * If there are multiple uncore PMUs and we're not reading the
  1153. * leader's stats, determine the stats for the appropriate
  1154. * uncore PMU.
  1155. */
  1156. if (evsel && evsel->metric_leader &&
  1157. evsel->pmu != evsel->metric_leader->pmu &&
  1158. cur->pmu == evsel->metric_leader->pmu) {
  1159. struct evsel *pos;
  1160. evlist__for_each_entry(evsel->evlist, pos) {
  1161. if (pos->pmu != evsel->pmu)
  1162. continue;
  1163. if (pos->metric_leader != cur)
  1164. continue;
  1165. cur = pos;
  1166. source_count = 1;
  1167. break;
  1168. }
  1169. }
  1170. if (source_count == 0)
  1171. source_count = evsel__source_count(cur);
  1172. ret = evsel__ensure_counts(cur);
  1173. if (ret)
  1174. return ret;
  1175. /* Set up pointers to the old and newly read counter values. */
  1176. old_count = perf_counts(cur->prev_raw_counts, cpu_idx, thread_idx);
  1177. new_count = perf_counts(cur->counts, cpu_idx, thread_idx);
  1178. /* Update the value in cur->counts. */
  1179. evsel__read_counter(cur, cpu_idx, thread_idx);
  1180. val = new_count->val - old_count->val;
  1181. ena = new_count->ena - old_count->ena;
  1182. run = new_count->run - old_count->run;
  1183. if (ena != run && run != 0)
  1184. val = val * ena / run;
  1185. ret = expr__add_id_val_source_count(pctx, n, val, source_count);
  1186. if (ret)
  1187. return ret;
  1188. }
  1189. for (int i = 0; metric_refs && metric_refs[i].metric_name; i++) {
  1190. int ret = expr__add_ref(pctx, &metric_refs[i]);
  1191. if (ret)
  1192. return ret;
  1193. }
  1194. return 0;
  1195. }
  1196. static PyObject *pyrf_evlist__compute_metric(struct pyrf_evlist *pevlist,
  1197. PyObject *args, PyObject *kwargs)
  1198. {
  1199. int ret, cpu = 0, cpu_idx = 0, thread = 0, thread_idx = 0;
  1200. const char *metric;
  1201. struct rb_node *node;
  1202. struct metric_expr *mexp = NULL;
  1203. struct expr_parse_ctx *pctx;
  1204. double result = 0;
  1205. struct evsel *metric_evsel = NULL;
  1206. if (!PyArg_ParseTuple(args, "sii", &metric, &cpu, &thread))
  1207. return NULL;
  1208. for (node = rb_first_cached(&pevlist->evlist.metric_events.entries);
  1209. mexp == NULL && node;
  1210. node = rb_next(node)) {
  1211. struct metric_event *me = container_of(node, struct metric_event, nd);
  1212. struct list_head *pos;
  1213. list_for_each(pos, &me->head) {
  1214. struct metric_expr *e = container_of(pos, struct metric_expr, nd);
  1215. struct evsel *pos2;
  1216. if (strcmp(e->metric_name, metric))
  1217. continue;
  1218. if (e->metric_events[0] == NULL)
  1219. continue;
  1220. evlist__for_each_entry(&pevlist->evlist, pos2) {
  1221. if (pos2->metric_leader != e->metric_events[0])
  1222. continue;
  1223. cpu_idx = perf_cpu_map__idx(pos2->core.cpus,
  1224. (struct perf_cpu){.cpu = cpu});
  1225. if (cpu_idx < 0)
  1226. continue;
  1227. thread_idx = perf_thread_map__idx(pos2->core.threads, thread);
  1228. if (thread_idx < 0)
  1229. continue;
  1230. metric_evsel = pos2;
  1231. mexp = e;
  1232. goto done;
  1233. }
  1234. }
  1235. }
  1236. done:
  1237. if (!mexp) {
  1238. PyErr_Format(PyExc_TypeError, "Unknown metric '%s' for CPU '%d' and thread '%d'",
  1239. metric, cpu, thread);
  1240. return NULL;
  1241. }
  1242. pctx = expr__ctx_new();
  1243. if (!pctx)
  1244. return PyErr_NoMemory();
  1245. ret = prepare_metric(mexp, metric_evsel, pctx, cpu_idx, thread_idx);
  1246. if (ret) {
  1247. expr__ctx_free(pctx);
  1248. errno = -ret;
  1249. PyErr_SetFromErrno(PyExc_OSError);
  1250. return NULL;
  1251. }
  1252. if (expr__parse(&result, pctx, mexp->metric_expr))
  1253. result = 0.0;
  1254. expr__ctx_free(pctx);
  1255. return PyFloat_FromDouble(result);
  1256. }
  1257. static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
  1258. PyObject *args, PyObject *kwargs)
  1259. {
  1260. struct evlist *evlist = &pevlist->evlist;
  1261. static char *kwlist[] = { "pages", "overwrite", NULL };
  1262. int pages = 128, overwrite = false;
  1263. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
  1264. &pages, &overwrite))
  1265. return NULL;
  1266. if (evlist__mmap(evlist, pages) < 0) {
  1267. PyErr_SetFromErrno(PyExc_OSError);
  1268. return NULL;
  1269. }
  1270. Py_INCREF(Py_None);
  1271. return Py_None;
  1272. }
  1273. static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
  1274. PyObject *args, PyObject *kwargs)
  1275. {
  1276. struct evlist *evlist = &pevlist->evlist;
  1277. static char *kwlist[] = { "timeout", NULL };
  1278. int timeout = -1, n;
  1279. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
  1280. return NULL;
  1281. n = evlist__poll(evlist, timeout);
  1282. if (n < 0) {
  1283. PyErr_SetFromErrno(PyExc_OSError);
  1284. return NULL;
  1285. }
  1286. return Py_BuildValue("i", n);
  1287. }
  1288. static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
  1289. PyObject *args __maybe_unused,
  1290. PyObject *kwargs __maybe_unused)
  1291. {
  1292. struct evlist *evlist = &pevlist->evlist;
  1293. PyObject *list = PyList_New(0);
  1294. int i;
  1295. for (i = 0; i < evlist->core.pollfd.nr; ++i) {
  1296. PyObject *file;
  1297. file = PyFile_FromFd(evlist->core.pollfd.entries[i].fd, "perf", "r", -1,
  1298. NULL, NULL, NULL, 0);
  1299. if (file == NULL)
  1300. goto free_list;
  1301. if (PyList_Append(list, file) != 0) {
  1302. Py_DECREF(file);
  1303. goto free_list;
  1304. }
  1305. Py_DECREF(file);
  1306. }
  1307. return list;
  1308. free_list:
  1309. return PyErr_NoMemory();
  1310. }
  1311. static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
  1312. PyObject *args,
  1313. PyObject *kwargs __maybe_unused)
  1314. {
  1315. struct evlist *evlist = &pevlist->evlist;
  1316. PyObject *pevsel;
  1317. struct evsel *evsel;
  1318. if (!PyArg_ParseTuple(args, "O", &pevsel))
  1319. return NULL;
  1320. Py_INCREF(pevsel);
  1321. evsel = &((struct pyrf_evsel *)pevsel)->evsel;
  1322. evsel->core.idx = evlist->core.nr_entries;
  1323. evlist__add(evlist, evsel);
  1324. return Py_BuildValue("i", evlist->core.nr_entries);
  1325. }
  1326. static struct mmap *get_md(struct evlist *evlist, int cpu)
  1327. {
  1328. int i;
  1329. for (i = 0; i < evlist->core.nr_mmaps; i++) {
  1330. struct mmap *md = &evlist->mmap[i];
  1331. if (md->core.cpu.cpu == cpu)
  1332. return md;
  1333. }
  1334. return NULL;
  1335. }
  1336. static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
  1337. PyObject *args, PyObject *kwargs)
  1338. {
  1339. struct evlist *evlist = &pevlist->evlist;
  1340. union perf_event *event;
  1341. int sample_id_all = 1, cpu;
  1342. static char *kwlist[] = { "cpu", "sample_id_all", NULL };
  1343. struct mmap *md;
  1344. int err;
  1345. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
  1346. &cpu, &sample_id_all))
  1347. return NULL;
  1348. md = get_md(evlist, cpu);
  1349. if (!md) {
  1350. PyErr_Format(PyExc_TypeError, "Unknown CPU '%d'", cpu);
  1351. return NULL;
  1352. }
  1353. if (perf_mmap__read_init(&md->core) < 0)
  1354. goto end;
  1355. event = perf_mmap__read_event(&md->core);
  1356. if (event != NULL) {
  1357. PyObject *pyevent = pyrf_event__new(event);
  1358. struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
  1359. struct evsel *evsel;
  1360. if (pyevent == NULL)
  1361. return PyErr_NoMemory();
  1362. evsel = evlist__event2evsel(evlist, event);
  1363. if (!evsel) {
  1364. Py_DECREF(pyevent);
  1365. Py_INCREF(Py_None);
  1366. return Py_None;
  1367. }
  1368. pevent->evsel = evsel;
  1369. perf_mmap__consume(&md->core);
  1370. err = evsel__parse_sample(evsel, &pevent->event, &pevent->sample);
  1371. if (err) {
  1372. Py_DECREF(pyevent);
  1373. return PyErr_Format(PyExc_OSError,
  1374. "perf: can't parse sample, err=%d", err);
  1375. }
  1376. return pyevent;
  1377. }
  1378. end:
  1379. Py_INCREF(Py_None);
  1380. return Py_None;
  1381. }
  1382. static PyObject *pyrf_evlist__open(struct pyrf_evlist *pevlist,
  1383. PyObject *args, PyObject *kwargs)
  1384. {
  1385. struct evlist *evlist = &pevlist->evlist;
  1386. if (evlist__open(evlist) < 0) {
  1387. PyErr_SetFromErrno(PyExc_OSError);
  1388. return NULL;
  1389. }
  1390. Py_INCREF(Py_None);
  1391. return Py_None;
  1392. }
  1393. static PyObject *pyrf_evlist__close(struct pyrf_evlist *pevlist)
  1394. {
  1395. struct evlist *evlist = &pevlist->evlist;
  1396. evlist__close(evlist);
  1397. Py_INCREF(Py_None);
  1398. return Py_None;
  1399. }
  1400. static PyObject *pyrf_evlist__config(struct pyrf_evlist *pevlist)
  1401. {
  1402. struct record_opts opts = {
  1403. .sample_time = true,
  1404. .mmap_pages = UINT_MAX,
  1405. .user_freq = UINT_MAX,
  1406. .user_interval = ULLONG_MAX,
  1407. .freq = 4000,
  1408. .target = {
  1409. .uses_mmap = true,
  1410. .default_per_cpu = true,
  1411. },
  1412. .nr_threads_synthesize = 1,
  1413. .ctl_fd = -1,
  1414. .ctl_fd_ack = -1,
  1415. .no_buffering = true,
  1416. .no_inherit = true,
  1417. };
  1418. struct evlist *evlist = &pevlist->evlist;
  1419. evlist__config(evlist, &opts, &callchain_param);
  1420. Py_INCREF(Py_None);
  1421. return Py_None;
  1422. }
  1423. static PyObject *pyrf_evlist__disable(struct pyrf_evlist *pevlist)
  1424. {
  1425. evlist__disable(&pevlist->evlist);
  1426. Py_INCREF(Py_None);
  1427. return Py_None;
  1428. }
  1429. static PyObject *pyrf_evlist__enable(struct pyrf_evlist *pevlist)
  1430. {
  1431. evlist__enable(&pevlist->evlist);
  1432. Py_INCREF(Py_None);
  1433. return Py_None;
  1434. }
  1435. static PyMethodDef pyrf_evlist__methods[] = {
  1436. {
  1437. .ml_name = "all_cpus",
  1438. .ml_meth = (PyCFunction)pyrf_evlist__all_cpus,
  1439. .ml_flags = METH_NOARGS,
  1440. .ml_doc = PyDoc_STR("CPU map union of all evsel CPU maps.")
  1441. },
  1442. {
  1443. .ml_name = "metrics",
  1444. .ml_meth = (PyCFunction)pyrf_evlist__metrics,
  1445. .ml_flags = METH_NOARGS,
  1446. .ml_doc = PyDoc_STR("List of metric names within the evlist.")
  1447. },
  1448. {
  1449. .ml_name = "compute_metric",
  1450. .ml_meth = (PyCFunction)pyrf_evlist__compute_metric,
  1451. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1452. .ml_doc = PyDoc_STR("compute metric for given name, cpu and thread")
  1453. },
  1454. {
  1455. .ml_name = "mmap",
  1456. .ml_meth = (PyCFunction)pyrf_evlist__mmap,
  1457. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1458. .ml_doc = PyDoc_STR("mmap the file descriptor table.")
  1459. },
  1460. {
  1461. .ml_name = "open",
  1462. .ml_meth = (PyCFunction)pyrf_evlist__open,
  1463. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1464. .ml_doc = PyDoc_STR("open the file descriptors.")
  1465. },
  1466. {
  1467. .ml_name = "close",
  1468. .ml_meth = (PyCFunction)pyrf_evlist__close,
  1469. .ml_flags = METH_NOARGS,
  1470. .ml_doc = PyDoc_STR("close the file descriptors.")
  1471. },
  1472. {
  1473. .ml_name = "poll",
  1474. .ml_meth = (PyCFunction)pyrf_evlist__poll,
  1475. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1476. .ml_doc = PyDoc_STR("poll the file descriptor table.")
  1477. },
  1478. {
  1479. .ml_name = "get_pollfd",
  1480. .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
  1481. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1482. .ml_doc = PyDoc_STR("get the poll file descriptor table.")
  1483. },
  1484. {
  1485. .ml_name = "add",
  1486. .ml_meth = (PyCFunction)pyrf_evlist__add,
  1487. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1488. .ml_doc = PyDoc_STR("adds an event selector to the list.")
  1489. },
  1490. {
  1491. .ml_name = "read_on_cpu",
  1492. .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
  1493. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1494. .ml_doc = PyDoc_STR("reads an event.")
  1495. },
  1496. {
  1497. .ml_name = "config",
  1498. .ml_meth = (PyCFunction)pyrf_evlist__config,
  1499. .ml_flags = METH_NOARGS,
  1500. .ml_doc = PyDoc_STR("Apply default record options to the evlist.")
  1501. },
  1502. {
  1503. .ml_name = "disable",
  1504. .ml_meth = (PyCFunction)pyrf_evlist__disable,
  1505. .ml_flags = METH_NOARGS,
  1506. .ml_doc = PyDoc_STR("Disable the evsels in the evlist.")
  1507. },
  1508. {
  1509. .ml_name = "enable",
  1510. .ml_meth = (PyCFunction)pyrf_evlist__enable,
  1511. .ml_flags = METH_NOARGS,
  1512. .ml_doc = PyDoc_STR("Enable the evsels in the evlist.")
  1513. },
  1514. { .ml_name = NULL, }
  1515. };
  1516. static Py_ssize_t pyrf_evlist__length(PyObject *obj)
  1517. {
  1518. struct pyrf_evlist *pevlist = (void *)obj;
  1519. return pevlist->evlist.core.nr_entries;
  1520. }
  1521. static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
  1522. {
  1523. struct pyrf_evlist *pevlist = (void *)obj;
  1524. struct evsel *pos;
  1525. if (i >= pevlist->evlist.core.nr_entries) {
  1526. PyErr_SetString(PyExc_IndexError, "Index out of range");
  1527. return NULL;
  1528. }
  1529. evlist__for_each_entry(&pevlist->evlist, pos) {
  1530. if (i-- == 0)
  1531. break;
  1532. }
  1533. return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
  1534. }
  1535. static PyObject *pyrf_evlist__str(PyObject *self)
  1536. {
  1537. struct pyrf_evlist *pevlist = (void *)self;
  1538. struct evsel *pos;
  1539. struct strbuf sb = STRBUF_INIT;
  1540. bool first = true;
  1541. PyObject *result;
  1542. strbuf_addstr(&sb, "evlist([");
  1543. evlist__for_each_entry(&pevlist->evlist, pos) {
  1544. if (!first)
  1545. strbuf_addch(&sb, ',');
  1546. if (!pos->pmu)
  1547. strbuf_addstr(&sb, evsel__name(pos));
  1548. else
  1549. strbuf_addf(&sb, "%s/%s/", pos->pmu->name, evsel__name(pos));
  1550. first = false;
  1551. }
  1552. strbuf_addstr(&sb, "])");
  1553. result = PyUnicode_FromString(sb.buf);
  1554. strbuf_release(&sb);
  1555. return result;
  1556. }
  1557. static PySequenceMethods pyrf_evlist__sequence_methods = {
  1558. .sq_length = pyrf_evlist__length,
  1559. .sq_item = pyrf_evlist__item,
  1560. };
  1561. static const char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
  1562. static PyTypeObject pyrf_evlist__type = {
  1563. PyVarObject_HEAD_INIT(NULL, 0)
  1564. .tp_name = "perf.evlist",
  1565. .tp_basicsize = sizeof(struct pyrf_evlist),
  1566. .tp_dealloc = (destructor)pyrf_evlist__delete,
  1567. .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
  1568. .tp_as_sequence = &pyrf_evlist__sequence_methods,
  1569. .tp_doc = pyrf_evlist__doc,
  1570. .tp_methods = pyrf_evlist__methods,
  1571. .tp_init = (initproc)pyrf_evlist__init,
  1572. .tp_repr = pyrf_evlist__str,
  1573. .tp_str = pyrf_evlist__str,
  1574. };
  1575. static int pyrf_evlist__setup_types(void)
  1576. {
  1577. pyrf_evlist__type.tp_new = PyType_GenericNew;
  1578. return PyType_Ready(&pyrf_evlist__type);
  1579. }
  1580. #define PERF_CONST(name) { #name, PERF_##name }
  1581. struct perf_constant {
  1582. const char *name;
  1583. int value;
  1584. };
  1585. static const struct perf_constant perf__constants[] = {
  1586. PERF_CONST(TYPE_HARDWARE),
  1587. PERF_CONST(TYPE_SOFTWARE),
  1588. PERF_CONST(TYPE_TRACEPOINT),
  1589. PERF_CONST(TYPE_HW_CACHE),
  1590. PERF_CONST(TYPE_RAW),
  1591. PERF_CONST(TYPE_BREAKPOINT),
  1592. PERF_CONST(COUNT_HW_CPU_CYCLES),
  1593. PERF_CONST(COUNT_HW_INSTRUCTIONS),
  1594. PERF_CONST(COUNT_HW_CACHE_REFERENCES),
  1595. PERF_CONST(COUNT_HW_CACHE_MISSES),
  1596. PERF_CONST(COUNT_HW_BRANCH_INSTRUCTIONS),
  1597. PERF_CONST(COUNT_HW_BRANCH_MISSES),
  1598. PERF_CONST(COUNT_HW_BUS_CYCLES),
  1599. PERF_CONST(COUNT_HW_CACHE_L1D),
  1600. PERF_CONST(COUNT_HW_CACHE_L1I),
  1601. PERF_CONST(COUNT_HW_CACHE_LL),
  1602. PERF_CONST(COUNT_HW_CACHE_DTLB),
  1603. PERF_CONST(COUNT_HW_CACHE_ITLB),
  1604. PERF_CONST(COUNT_HW_CACHE_BPU),
  1605. PERF_CONST(COUNT_HW_CACHE_OP_READ),
  1606. PERF_CONST(COUNT_HW_CACHE_OP_WRITE),
  1607. PERF_CONST(COUNT_HW_CACHE_OP_PREFETCH),
  1608. PERF_CONST(COUNT_HW_CACHE_RESULT_ACCESS),
  1609. PERF_CONST(COUNT_HW_CACHE_RESULT_MISS),
  1610. PERF_CONST(COUNT_HW_STALLED_CYCLES_FRONTEND),
  1611. PERF_CONST(COUNT_HW_STALLED_CYCLES_BACKEND),
  1612. PERF_CONST(COUNT_SW_CPU_CLOCK),
  1613. PERF_CONST(COUNT_SW_TASK_CLOCK),
  1614. PERF_CONST(COUNT_SW_PAGE_FAULTS),
  1615. PERF_CONST(COUNT_SW_CONTEXT_SWITCHES),
  1616. PERF_CONST(COUNT_SW_CPU_MIGRATIONS),
  1617. PERF_CONST(COUNT_SW_PAGE_FAULTS_MIN),
  1618. PERF_CONST(COUNT_SW_PAGE_FAULTS_MAJ),
  1619. PERF_CONST(COUNT_SW_ALIGNMENT_FAULTS),
  1620. PERF_CONST(COUNT_SW_EMULATION_FAULTS),
  1621. PERF_CONST(COUNT_SW_DUMMY),
  1622. PERF_CONST(SAMPLE_IP),
  1623. PERF_CONST(SAMPLE_TID),
  1624. PERF_CONST(SAMPLE_TIME),
  1625. PERF_CONST(SAMPLE_ADDR),
  1626. PERF_CONST(SAMPLE_READ),
  1627. PERF_CONST(SAMPLE_CALLCHAIN),
  1628. PERF_CONST(SAMPLE_ID),
  1629. PERF_CONST(SAMPLE_CPU),
  1630. PERF_CONST(SAMPLE_PERIOD),
  1631. PERF_CONST(SAMPLE_STREAM_ID),
  1632. PERF_CONST(SAMPLE_RAW),
  1633. PERF_CONST(FORMAT_TOTAL_TIME_ENABLED),
  1634. PERF_CONST(FORMAT_TOTAL_TIME_RUNNING),
  1635. PERF_CONST(FORMAT_ID),
  1636. PERF_CONST(FORMAT_GROUP),
  1637. PERF_CONST(RECORD_MMAP),
  1638. PERF_CONST(RECORD_LOST),
  1639. PERF_CONST(RECORD_COMM),
  1640. PERF_CONST(RECORD_EXIT),
  1641. PERF_CONST(RECORD_THROTTLE),
  1642. PERF_CONST(RECORD_UNTHROTTLE),
  1643. PERF_CONST(RECORD_FORK),
  1644. PERF_CONST(RECORD_READ),
  1645. PERF_CONST(RECORD_SAMPLE),
  1646. PERF_CONST(RECORD_MMAP2),
  1647. PERF_CONST(RECORD_AUX),
  1648. PERF_CONST(RECORD_ITRACE_START),
  1649. PERF_CONST(RECORD_LOST_SAMPLES),
  1650. PERF_CONST(RECORD_SWITCH),
  1651. PERF_CONST(RECORD_SWITCH_CPU_WIDE),
  1652. PERF_CONST(RECORD_MISC_SWITCH_OUT),
  1653. { .name = NULL, },
  1654. };
  1655. static PyObject *pyrf__tracepoint(struct pyrf_evsel *pevsel,
  1656. PyObject *args, PyObject *kwargs)
  1657. {
  1658. static char *kwlist[] = { "sys", "name", NULL };
  1659. char *sys = NULL;
  1660. char *name = NULL;
  1661. if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ss", kwlist,
  1662. &sys, &name))
  1663. return NULL;
  1664. return PyLong_FromLong(tp_pmu__id(sys, name));
  1665. }
  1666. static PyObject *pyrf_evsel__from_evsel(struct evsel *evsel)
  1667. {
  1668. struct pyrf_evsel *pevsel = PyObject_New(struct pyrf_evsel, &pyrf_evsel__type);
  1669. if (!pevsel)
  1670. return NULL;
  1671. memset(&pevsel->evsel, 0, sizeof(pevsel->evsel));
  1672. evsel__init(&pevsel->evsel, &evsel->core.attr, evsel->core.idx);
  1673. evsel__clone(&pevsel->evsel, evsel);
  1674. if (evsel__is_group_leader(evsel))
  1675. evsel__set_leader(&pevsel->evsel, &pevsel->evsel);
  1676. return (PyObject *)pevsel;
  1677. }
  1678. static int evlist__pos(struct evlist *evlist, struct evsel *evsel)
  1679. {
  1680. struct evsel *pos;
  1681. int idx = 0;
  1682. evlist__for_each_entry(evlist, pos) {
  1683. if (evsel == pos)
  1684. return idx;
  1685. idx++;
  1686. }
  1687. return -1;
  1688. }
  1689. static struct evsel *evlist__at(struct evlist *evlist, int idx)
  1690. {
  1691. struct evsel *pos;
  1692. int idx2 = 0;
  1693. evlist__for_each_entry(evlist, pos) {
  1694. if (idx == idx2)
  1695. return pos;
  1696. idx2++;
  1697. }
  1698. return NULL;
  1699. }
  1700. static PyObject *pyrf_evlist__from_evlist(struct evlist *evlist)
  1701. {
  1702. struct pyrf_evlist *pevlist = PyObject_New(struct pyrf_evlist, &pyrf_evlist__type);
  1703. struct evsel *pos;
  1704. struct rb_node *node;
  1705. if (!pevlist)
  1706. return NULL;
  1707. memset(&pevlist->evlist, 0, sizeof(pevlist->evlist));
  1708. evlist__init(&pevlist->evlist, evlist->core.all_cpus, evlist->core.threads);
  1709. evlist__for_each_entry(evlist, pos) {
  1710. struct pyrf_evsel *pevsel = (void *)pyrf_evsel__from_evsel(pos);
  1711. evlist__add(&pevlist->evlist, &pevsel->evsel);
  1712. }
  1713. evlist__for_each_entry(&pevlist->evlist, pos) {
  1714. struct evsel *leader = evsel__leader(pos);
  1715. if (pos != leader) {
  1716. int idx = evlist__pos(evlist, leader);
  1717. if (idx >= 0)
  1718. evsel__set_leader(pos, evlist__at(&pevlist->evlist, idx));
  1719. else if (leader == NULL)
  1720. evsel__set_leader(pos, pos);
  1721. }
  1722. leader = pos->metric_leader;
  1723. if (pos != leader) {
  1724. int idx = evlist__pos(evlist, leader);
  1725. if (idx >= 0)
  1726. pos->metric_leader = evlist__at(&pevlist->evlist, idx);
  1727. else if (leader == NULL)
  1728. pos->metric_leader = pos;
  1729. }
  1730. }
  1731. metricgroup__copy_metric_events(&pevlist->evlist, /*cgrp=*/NULL,
  1732. &pevlist->evlist.metric_events,
  1733. &evlist->metric_events);
  1734. for (node = rb_first_cached(&pevlist->evlist.metric_events.entries); node;
  1735. node = rb_next(node)) {
  1736. struct metric_event *me = container_of(node, struct metric_event, nd);
  1737. struct list_head *mpos;
  1738. int idx = evlist__pos(evlist, me->evsel);
  1739. if (idx >= 0)
  1740. me->evsel = evlist__at(&pevlist->evlist, idx);
  1741. list_for_each(mpos, &me->head) {
  1742. struct metric_expr *e = container_of(mpos, struct metric_expr, nd);
  1743. for (int j = 0; e->metric_events[j]; j++) {
  1744. idx = evlist__pos(evlist, e->metric_events[j]);
  1745. if (idx >= 0)
  1746. e->metric_events[j] = evlist__at(&pevlist->evlist, idx);
  1747. }
  1748. }
  1749. }
  1750. return (PyObject *)pevlist;
  1751. }
  1752. static PyObject *pyrf__parse_events(PyObject *self, PyObject *args)
  1753. {
  1754. const char *input;
  1755. struct evlist evlist = {};
  1756. struct parse_events_error err;
  1757. PyObject *result;
  1758. PyObject *pcpus = NULL, *pthreads = NULL;
  1759. struct perf_cpu_map *cpus;
  1760. struct perf_thread_map *threads;
  1761. if (!PyArg_ParseTuple(args, "s|OO", &input, &pcpus, &pthreads))
  1762. return NULL;
  1763. threads = pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NULL;
  1764. cpus = pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
  1765. parse_events_error__init(&err);
  1766. evlist__init(&evlist, cpus, threads);
  1767. if (parse_events(&evlist, input, &err)) {
  1768. parse_events_error__print(&err, input);
  1769. PyErr_SetFromErrno(PyExc_OSError);
  1770. return NULL;
  1771. }
  1772. result = pyrf_evlist__from_evlist(&evlist);
  1773. evlist__exit(&evlist);
  1774. return result;
  1775. }
  1776. static PyObject *pyrf__parse_metrics(PyObject *self, PyObject *args)
  1777. {
  1778. const char *input, *pmu = NULL;
  1779. struct evlist evlist = {};
  1780. PyObject *result;
  1781. PyObject *pcpus = NULL, *pthreads = NULL;
  1782. struct perf_cpu_map *cpus;
  1783. struct perf_thread_map *threads;
  1784. int ret;
  1785. if (!PyArg_ParseTuple(args, "s|sOO", &input, &pmu, &pcpus, &pthreads))
  1786. return NULL;
  1787. threads = pthreads ? ((struct pyrf_thread_map *)pthreads)->threads : NULL;
  1788. cpus = pcpus ? ((struct pyrf_cpu_map *)pcpus)->cpus : NULL;
  1789. evlist__init(&evlist, cpus, threads);
  1790. ret = metricgroup__parse_groups(&evlist, pmu ?: "all", input,
  1791. /*metric_no_group=*/ false,
  1792. /*metric_no_merge=*/ false,
  1793. /*metric_no_threshold=*/ true,
  1794. /*user_requested_cpu_list=*/ NULL,
  1795. /*system_wide=*/true,
  1796. /*hardware_aware_grouping=*/ false);
  1797. if (ret) {
  1798. errno = -ret;
  1799. PyErr_SetFromErrno(PyExc_OSError);
  1800. return NULL;
  1801. }
  1802. result = pyrf_evlist__from_evlist(&evlist);
  1803. evlist__exit(&evlist);
  1804. return result;
  1805. }
  1806. static PyObject *pyrf__metrics_groups(const struct pmu_metric *pm)
  1807. {
  1808. PyObject *groups = PyList_New(/*len=*/0);
  1809. const char *mg = pm->metric_group;
  1810. if (!groups)
  1811. return NULL;
  1812. while (mg) {
  1813. PyObject *val = NULL;
  1814. const char *sep = strchr(mg, ';');
  1815. size_t len = sep ? (size_t)(sep - mg) : strlen(mg);
  1816. if (len > 0) {
  1817. val = PyUnicode_FromStringAndSize(mg, len);
  1818. if (val)
  1819. PyList_Append(groups, val);
  1820. Py_XDECREF(val);
  1821. }
  1822. mg = sep ? sep + 1 : NULL;
  1823. }
  1824. return groups;
  1825. }
  1826. static int pyrf__metrics_cb(const struct pmu_metric *pm,
  1827. const struct pmu_metrics_table *table __maybe_unused,
  1828. void *vdata)
  1829. {
  1830. PyObject *py_list = vdata;
  1831. PyObject *dict = PyDict_New();
  1832. PyObject *key = dict ? PyUnicode_FromString("MetricGroup") : NULL;
  1833. PyObject *value = key ? pyrf__metrics_groups(pm) : NULL;
  1834. if (!value || PyDict_SetItem(dict, key, value) != 0) {
  1835. Py_XDECREF(key);
  1836. Py_XDECREF(value);
  1837. Py_XDECREF(dict);
  1838. return -ENOMEM;
  1839. }
  1840. if (!add_to_dict(dict, "MetricName", pm->metric_name) ||
  1841. !add_to_dict(dict, "PMU", pm->pmu) ||
  1842. !add_to_dict(dict, "MetricExpr", pm->metric_expr) ||
  1843. !add_to_dict(dict, "MetricThreshold", pm->metric_threshold) ||
  1844. !add_to_dict(dict, "ScaleUnit", pm->unit) ||
  1845. !add_to_dict(dict, "Compat", pm->compat) ||
  1846. !add_to_dict(dict, "BriefDescription", pm->desc) ||
  1847. !add_to_dict(dict, "PublicDescription", pm->long_desc) ||
  1848. PyList_Append(py_list, dict) != 0) {
  1849. Py_DECREF(dict);
  1850. return -ENOMEM;
  1851. }
  1852. Py_DECREF(dict);
  1853. return 0;
  1854. }
  1855. static PyObject *pyrf__metrics(PyObject *self, PyObject *args)
  1856. {
  1857. const struct pmu_metrics_table *table = pmu_metrics_table__find();
  1858. PyObject *list = PyList_New(/*len=*/0);
  1859. int ret;
  1860. if (!list)
  1861. return NULL;
  1862. ret = pmu_metrics_table__for_each_metric(table, pyrf__metrics_cb, list);
  1863. if (!ret)
  1864. ret = pmu_for_each_sys_metric(pyrf__metrics_cb, list);
  1865. if (ret) {
  1866. Py_DECREF(list);
  1867. errno = -ret;
  1868. PyErr_SetFromErrno(PyExc_OSError);
  1869. return NULL;
  1870. }
  1871. return list;
  1872. }
  1873. static PyMethodDef perf__methods[] = {
  1874. {
  1875. .ml_name = "metrics",
  1876. .ml_meth = (PyCFunction) pyrf__metrics,
  1877. .ml_flags = METH_NOARGS,
  1878. .ml_doc = PyDoc_STR(
  1879. "Returns a list of metrics represented as string values in dictionaries.")
  1880. },
  1881. {
  1882. .ml_name = "tracepoint",
  1883. .ml_meth = (PyCFunction) pyrf__tracepoint,
  1884. .ml_flags = METH_VARARGS | METH_KEYWORDS,
  1885. .ml_doc = PyDoc_STR("Get tracepoint config.")
  1886. },
  1887. {
  1888. .ml_name = "parse_events",
  1889. .ml_meth = (PyCFunction) pyrf__parse_events,
  1890. .ml_flags = METH_VARARGS,
  1891. .ml_doc = PyDoc_STR("Parse a string of events and return an evlist.")
  1892. },
  1893. {
  1894. .ml_name = "parse_metrics",
  1895. .ml_meth = (PyCFunction) pyrf__parse_metrics,
  1896. .ml_flags = METH_VARARGS,
  1897. .ml_doc = PyDoc_STR(
  1898. "Parse a string of metrics or metric groups and return an evlist.")
  1899. },
  1900. {
  1901. .ml_name = "pmus",
  1902. .ml_meth = (PyCFunction) pyrf__pmus,
  1903. .ml_flags = METH_NOARGS,
  1904. .ml_doc = PyDoc_STR("Returns a sequence of pmus.")
  1905. },
  1906. { .ml_name = NULL, }
  1907. };
  1908. PyMODINIT_FUNC PyInit_perf(void)
  1909. {
  1910. PyObject *obj;
  1911. int i;
  1912. PyObject *dict;
  1913. static struct PyModuleDef moduledef = {
  1914. PyModuleDef_HEAD_INIT,
  1915. "perf", /* m_name */
  1916. "", /* m_doc */
  1917. -1, /* m_size */
  1918. perf__methods, /* m_methods */
  1919. NULL, /* m_reload */
  1920. NULL, /* m_traverse */
  1921. NULL, /* m_clear */
  1922. NULL, /* m_free */
  1923. };
  1924. PyObject *module = PyModule_Create(&moduledef);
  1925. if (module == NULL ||
  1926. pyrf_event__setup_types() < 0 ||
  1927. pyrf_evlist__setup_types() < 0 ||
  1928. pyrf_evsel__setup_types() < 0 ||
  1929. pyrf_thread_map__setup_types() < 0 ||
  1930. pyrf_cpu_map__setup_types() < 0 ||
  1931. pyrf_pmu_iterator__setup_types() < 0 ||
  1932. pyrf_pmu__setup_types() < 0 ||
  1933. pyrf_counts_values__setup_types() < 0)
  1934. return module;
  1935. /* The page_size is placed in util object. */
  1936. page_size = sysconf(_SC_PAGE_SIZE);
  1937. Py_INCREF(&pyrf_evlist__type);
  1938. PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
  1939. Py_INCREF(&pyrf_evsel__type);
  1940. PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
  1941. Py_INCREF(&pyrf_mmap_event__type);
  1942. PyModule_AddObject(module, "mmap_event", (PyObject *)&pyrf_mmap_event__type);
  1943. Py_INCREF(&pyrf_lost_event__type);
  1944. PyModule_AddObject(module, "lost_event", (PyObject *)&pyrf_lost_event__type);
  1945. Py_INCREF(&pyrf_comm_event__type);
  1946. PyModule_AddObject(module, "comm_event", (PyObject *)&pyrf_comm_event__type);
  1947. Py_INCREF(&pyrf_task_event__type);
  1948. PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
  1949. Py_INCREF(&pyrf_throttle_event__type);
  1950. PyModule_AddObject(module, "throttle_event", (PyObject *)&pyrf_throttle_event__type);
  1951. Py_INCREF(&pyrf_task_event__type);
  1952. PyModule_AddObject(module, "task_event", (PyObject *)&pyrf_task_event__type);
  1953. Py_INCREF(&pyrf_read_event__type);
  1954. PyModule_AddObject(module, "read_event", (PyObject *)&pyrf_read_event__type);
  1955. Py_INCREF(&pyrf_sample_event__type);
  1956. PyModule_AddObject(module, "sample_event", (PyObject *)&pyrf_sample_event__type);
  1957. Py_INCREF(&pyrf_context_switch_event__type);
  1958. PyModule_AddObject(module, "switch_event", (PyObject *)&pyrf_context_switch_event__type);
  1959. Py_INCREF(&pyrf_thread_map__type);
  1960. PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
  1961. Py_INCREF(&pyrf_cpu_map__type);
  1962. PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
  1963. Py_INCREF(&pyrf_counts_values__type);
  1964. PyModule_AddObject(module, "counts_values", (PyObject *)&pyrf_counts_values__type);
  1965. dict = PyModule_GetDict(module);
  1966. if (dict == NULL)
  1967. goto error;
  1968. for (i = 0; perf__constants[i].name != NULL; i++) {
  1969. obj = PyLong_FromLong(perf__constants[i].value);
  1970. if (obj == NULL)
  1971. goto error;
  1972. PyDict_SetItemString(dict, perf__constants[i].name, obj);
  1973. Py_DECREF(obj);
  1974. }
  1975. error:
  1976. if (PyErr_Occurred())
  1977. PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
  1978. return module;
  1979. }