162306a36Sopenharmony_ci# system call counts, by pid
262306a36Sopenharmony_ci# (c) 2010, Tom Zanussi <tzanussi@gmail.com>
362306a36Sopenharmony_ci# Licensed under the terms of the GNU GPL License version 2
462306a36Sopenharmony_ci#
562306a36Sopenharmony_ci# Displays system-wide system call totals, broken down by syscall.
662306a36Sopenharmony_ci# If a [comm] arg is specified, only syscalls called by [comm] are displayed.
762306a36Sopenharmony_ci
862306a36Sopenharmony_cifrom __future__ import print_function
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ciimport os, sys
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cisys.path.append(os.environ['PERF_EXEC_PATH'] + \
1362306a36Sopenharmony_ci	'/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_cifrom perf_trace_context import *
1662306a36Sopenharmony_cifrom Core import *
1762306a36Sopenharmony_cifrom Util import syscall_name
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ciusage = "perf script -s syscall-counts-by-pid.py [comm]\n";
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cifor_comm = None
2262306a36Sopenharmony_cifor_pid = None
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciif len(sys.argv) > 2:
2562306a36Sopenharmony_ci	sys.exit(usage)
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ciif len(sys.argv) > 1:
2862306a36Sopenharmony_ci	try:
2962306a36Sopenharmony_ci		for_pid = int(sys.argv[1])
3062306a36Sopenharmony_ci	except:
3162306a36Sopenharmony_ci		for_comm = sys.argv[1]
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_cisyscalls = autodict()
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cidef trace_begin():
3662306a36Sopenharmony_ci	print("Press control+C to stop and show the summary")
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cidef trace_end():
3962306a36Sopenharmony_ci	print_syscall_totals()
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_cidef raw_syscalls__sys_enter(event_name, context, common_cpu,
4262306a36Sopenharmony_ci		common_secs, common_nsecs, common_pid, common_comm,
4362306a36Sopenharmony_ci		common_callchain, id, args):
4462306a36Sopenharmony_ci	if (for_comm and common_comm != for_comm) or \
4562306a36Sopenharmony_ci		(for_pid and common_pid != for_pid ):
4662306a36Sopenharmony_ci		return
4762306a36Sopenharmony_ci	try:
4862306a36Sopenharmony_ci		syscalls[common_comm][common_pid][id] += 1
4962306a36Sopenharmony_ci	except TypeError:
5062306a36Sopenharmony_ci		syscalls[common_comm][common_pid][id] = 1
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_cidef syscalls__sys_enter(event_name, context, common_cpu,
5362306a36Sopenharmony_ci		common_secs, common_nsecs, common_pid, common_comm,
5462306a36Sopenharmony_ci		id, args):
5562306a36Sopenharmony_ci	raw_syscalls__sys_enter(**locals())
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_cidef print_syscall_totals():
5862306a36Sopenharmony_ci	if for_comm is not None:
5962306a36Sopenharmony_ci		print("\nsyscall events for %s:\n" % (for_comm))
6062306a36Sopenharmony_ci	else:
6162306a36Sopenharmony_ci		print("\nsyscall events by comm/pid:\n")
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci	print("%-40s  %10s" % ("comm [pid]/syscalls", "count"))
6462306a36Sopenharmony_ci	print("%-40s  %10s" % ("----------------------------------------",
6562306a36Sopenharmony_ci				"----------"))
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_ci	comm_keys = syscalls.keys()
6862306a36Sopenharmony_ci	for comm in comm_keys:
6962306a36Sopenharmony_ci		pid_keys = syscalls[comm].keys()
7062306a36Sopenharmony_ci		for pid in pid_keys:
7162306a36Sopenharmony_ci			print("\n%s [%d]" % (comm, pid))
7262306a36Sopenharmony_ci			id_keys = syscalls[comm][pid].keys()
7362306a36Sopenharmony_ci			for id, val in sorted(syscalls[comm][pid].items(),
7462306a36Sopenharmony_ci				key = lambda kv: (kv[1], kv[0]), reverse = True):
7562306a36Sopenharmony_ci				print("  %-38s  %10d" % (syscall_name(id), val))
76