Home | History | Annotate | Download | only in misc
      1 # futex contention
      2 # (c) 2010, Arnaldo Carvalho de Melo <acme (at] 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 
     13 import os, sys
     14 sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
     15 from Util import *
     16 
     17 process_names = {}
     18 thread_thislock = {}
     19 thread_blocktime = {}
     20 
     21 lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time
     22 process_names = {} # long-lived pid-to-execname mapping
     23 
     24 def android_lock(callchain):
     25     for c in callchain:
     26         if 'sym' in c and 'name' in c['sym']:
     27             name = c['sym']['name']
     28         else:
     29             continue
     30 
     31         if 'art::Monitor::Lock' in name:
     32             return True
     33     return False
     34 
     35 def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
     36 			      nr, uaddr, op, val, utime, uaddr2, val3):
     37 
     38 	cmd = op & FUTEX_CMD_MASK
     39         if cmd != FUTEX_WAIT or android_lock(callchain) == False:
     40 		return # we don't care about originators of WAKE events 
     41                        # or futex uses that aren't android locks.
     42 
     43 	process_names[tid] = comm
     44 	thread_thislock[tid] = uaddr
     45 	thread_blocktime[tid] = nsecs(s, ns)
     46 
     47 def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
     48 			     nr, ret):
     49 	if thread_blocktime.has_key(tid):
     50 		elapsed = nsecs(s, ns) - thread_blocktime[tid]
     51 		add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed)
     52 		del thread_blocktime[tid]
     53 		del thread_thislock[tid]
     54 
     55 def trace_begin():
     56 	print "Press control+C to stop and show the summary"
     57 
     58 def trace_end():
     59 	for (tid, lock) in lock_waits:
     60 		min, max, avg, count = lock_waits[tid, lock]
     61 		print "%s[%d] lock %x contended %d times, %d avg ns" % \
     62 		      (process_names[tid], tid, lock, count, avg)
     63 
     64