| .. | .. |
|---|
| 10 | 10 | # |
|---|
| 11 | 11 | # Measures futex contention |
|---|
| 12 | 12 | |
|---|
| 13 | | -import os, sys |
|---|
| 14 | | -sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') |
|---|
| 13 | +from __future__ import print_function |
|---|
| 14 | + |
|---|
| 15 | +import os |
|---|
| 16 | +import sys |
|---|
| 17 | +sys.path.append(os.environ['PERF_EXEC_PATH'] + |
|---|
| 18 | + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') |
|---|
| 15 | 19 | from Util import * |
|---|
| 16 | 20 | |
|---|
| 17 | 21 | process_names = {} |
|---|
| 18 | 22 | thread_thislock = {} |
|---|
| 19 | 23 | thread_blocktime = {} |
|---|
| 20 | 24 | |
|---|
| 21 | | -lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time |
|---|
| 22 | | -process_names = {} # long-lived pid-to-execname mapping |
|---|
| 25 | +lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time |
|---|
| 26 | +process_names = {} # long-lived pid-to-execname mapping |
|---|
| 27 | + |
|---|
| 23 | 28 | |
|---|
| 24 | 29 | def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, callchain, |
|---|
| 25 | | - nr, uaddr, op, val, utime, uaddr2, val3): |
|---|
| 26 | | - cmd = op & FUTEX_CMD_MASK |
|---|
| 27 | | - if cmd != FUTEX_WAIT: |
|---|
| 28 | | - return # we don't care about originators of WAKE events |
|---|
| 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 |
|---|
| 29 | 34 | |
|---|
| 30 | | - process_names[tid] = comm |
|---|
| 31 | | - thread_thislock[tid] = uaddr |
|---|
| 32 | | - thread_blocktime[tid] = nsecs(s, ns) |
|---|
| 35 | + process_names[tid] = comm |
|---|
| 36 | + thread_thislock[tid] = uaddr |
|---|
| 37 | + thread_blocktime[tid] = nsecs(s, ns) |
|---|
| 38 | + |
|---|
| 33 | 39 | |
|---|
| 34 | 40 | def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain, |
|---|
| 35 | | - nr, ret): |
|---|
| 36 | | - if thread_blocktime.has_key(tid): |
|---|
| 37 | | - elapsed = nsecs(s, ns) - thread_blocktime[tid] |
|---|
| 38 | | - add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed) |
|---|
| 39 | | - del thread_blocktime[tid] |
|---|
| 40 | | - del thread_thislock[tid] |
|---|
| 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 | + |
|---|
| 41 | 48 | |
|---|
| 42 | 49 | def trace_begin(): |
|---|
| 43 | | - print "Press control+C to stop and show the summary" |
|---|
| 50 | + print("Press control+C to stop and show the summary") |
|---|
| 51 | + |
|---|
| 44 | 52 | |
|---|
| 45 | 53 | def trace_end(): |
|---|
| 46 | | - for (tid, lock) in lock_waits: |
|---|
| 47 | | - min, max, avg, count = lock_waits[tid, lock] |
|---|
| 48 | | - print "%s[%d] lock %x contended %d times, %d avg ns" % \ |
|---|
| 49 | | - (process_names[tid], tid, lock, count, avg) |
|---|
| 50 | | - |
|---|
| 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)) |
|---|