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