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