1# futex contention 2# (c) 2010, Arnaldo Carvalho de Melo <acme@redhat.com> 3# Licensed under the terms of the GNU GPL License version 2 4# 5# Translation of: 6# 7# http://sourceware.org/systemtap/wiki/WSFutexContention 8# 9# to perf python scripting. 10# 11# Measures futex contention 12 13from __future__ import print_function 14 15import os 16import sys 17sys.path.append(os.environ['PERF_EXEC_PATH'] + 18 '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') 19from Util import * 20 21process_names = {} 22thread_thislock = {} 23thread_blocktime = {} 24 25lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time 26process_names = {} # long-lived pid-to-execname mapping 27 28 29def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, callchain, 30 nr, uaddr, op, val, utime, uaddr2, val3): 31 cmd = op & FUTEX_CMD_MASK 32 if cmd != FUTEX_WAIT: 33 return # we don't care about originators of WAKE events 34 35 process_names[tid] = comm 36 thread_thislock[tid] = uaddr 37 thread_blocktime[tid] = nsecs(s, ns) 38 39 40def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain, 41 nr, ret): 42 if tid in thread_blocktime: 43 elapsed = nsecs(s, ns) - thread_blocktime[tid] 44 add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed) 45 del thread_blocktime[tid] 46 del thread_thislock[tid] 47 48 49def trace_begin(): 50 print("Press control+C to stop and show the summary") 51 52 53def trace_end(): 54 for (tid, lock) in lock_waits: 55 min, max, avg, count = lock_waits[tid, lock] 56 print("%s[%d] lock %x contended %d times, %d avg ns [max: %d ns, min %d ns]" % 57 (process_names[tid], tid, lock, count, avg, max, min)) 58