18c2ecf20Sopenharmony_ci#! /usr/bin/env python 28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only 38c2ecf20Sopenharmony_ci# -*- python -*- 48c2ecf20Sopenharmony_ci# -*- coding: utf-8 -*- 58c2ecf20Sopenharmony_ci# twatch - Experimental use of the perf python interface 68c2ecf20Sopenharmony_ci# Copyright (C) 2011 Arnaldo Carvalho de Melo <acme@redhat.com> 78c2ecf20Sopenharmony_ci# 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ciimport perf 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cidef main(context_switch = 0, thread = -1): 128c2ecf20Sopenharmony_ci cpus = perf.cpu_map() 138c2ecf20Sopenharmony_ci threads = perf.thread_map(thread) 148c2ecf20Sopenharmony_ci evsel = perf.evsel(type = perf.TYPE_SOFTWARE, 158c2ecf20Sopenharmony_ci config = perf.COUNT_SW_DUMMY, 168c2ecf20Sopenharmony_ci task = 1, comm = 1, mmap = 0, freq = 0, 178c2ecf20Sopenharmony_ci wakeup_events = 1, watermark = 1, 188c2ecf20Sopenharmony_ci sample_id_all = 1, context_switch = context_switch, 198c2ecf20Sopenharmony_ci sample_type = perf.SAMPLE_PERIOD | perf.SAMPLE_TID | perf.SAMPLE_CPU) 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci """What we want are just the PERF_RECORD_ lifetime events for threads, 228c2ecf20Sopenharmony_ci using the default, PERF_TYPE_HARDWARE + PERF_COUNT_HW_CYCLES & freq=1 238c2ecf20Sopenharmony_ci (the default), makes perf reenable irq_vectors:local_timer_entry, when 248c2ecf20Sopenharmony_ci disabling nohz, not good for some use cases where all we want is to get 258c2ecf20Sopenharmony_ci threads comes and goes... So use (perf.TYPE_SOFTWARE, perf_COUNT_SW_DUMMY, 268c2ecf20Sopenharmony_ci freq=0) instead.""" 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci evsel.open(cpus = cpus, threads = threads); 298c2ecf20Sopenharmony_ci evlist = perf.evlist(cpus, threads) 308c2ecf20Sopenharmony_ci evlist.add(evsel) 318c2ecf20Sopenharmony_ci evlist.mmap() 328c2ecf20Sopenharmony_ci while True: 338c2ecf20Sopenharmony_ci evlist.poll(timeout = -1) 348c2ecf20Sopenharmony_ci for cpu in cpus: 358c2ecf20Sopenharmony_ci event = evlist.read_on_cpu(cpu) 368c2ecf20Sopenharmony_ci if not event: 378c2ecf20Sopenharmony_ci continue 388c2ecf20Sopenharmony_ci print("cpu: {0}, pid: {1}, tid: {2} {3}".format(event.sample_cpu, 398c2ecf20Sopenharmony_ci event.sample_pid, 408c2ecf20Sopenharmony_ci event.sample_tid, 418c2ecf20Sopenharmony_ci event)) 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ciif __name__ == '__main__': 448c2ecf20Sopenharmony_ci """ 458c2ecf20Sopenharmony_ci To test the PERF_RECORD_SWITCH record, pick a pid and replace 468c2ecf20Sopenharmony_ci in the following line. 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci Example output: 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_cicpu: 3, pid: 31463, tid: 31593 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31593, switch_out: 1 } 518c2ecf20Sopenharmony_cicpu: 1, pid: 31463, tid: 31489 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31489, switch_out: 1 } 528c2ecf20Sopenharmony_cicpu: 2, pid: 31463, tid: 31496 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31496, switch_out: 1 } 538c2ecf20Sopenharmony_cicpu: 3, pid: 31463, tid: 31491 { type: context_switch, next_prev_pid: 31463, next_prev_tid: 31491, switch_out: 0 } 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci It is possible as well to use event.misc & perf.PERF_RECORD_MISC_SWITCH_OUT 568c2ecf20Sopenharmony_ci to figure out if this is a context switch in or out of the monitored threads. 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci If bored, please add command line option parsing support for these options :-) 598c2ecf20Sopenharmony_ci """ 608c2ecf20Sopenharmony_ci # main(context_switch = 1, thread = 31463) 618c2ecf20Sopenharmony_ci main() 62