add temporary perf scripts

Signed-off-by: Joel Fernandes <joel@joelfernandes.org>
diff --git a/bcc/misc/android-futex-contention-record b/bcc/misc/android-futex-contention-record
new file mode 100644
index 0000000..a12ff79
--- /dev/null
+++ b/bcc/misc/android-futex-contention-record
@@ -0,0 +1,2 @@
+#!/bin/bash
+perf record -a -g -e syscalls:sys_enter_futex -e syscalls:sys_exit_futex -e sched:sched_waking $@
diff --git a/bcc/misc/android-futex-contention-report b/bcc/misc/android-futex-contention-report
new file mode 100644
index 0000000..7a8c122
--- /dev/null
+++ b/bcc/misc/android-futex-contention-report
@@ -0,0 +1,4 @@
+#!/bin/bash
+# description: futext contention measurement
+
+perf script $@ -s "$PERF_EXEC_PATH"/scripts/python/android-futex-contention.py
diff --git a/bcc/misc/android-futex-contention.py b/bcc/misc/android-futex-contention.py
new file mode 100644
index 0000000..b3fab37
--- /dev/null
+++ b/bcc/misc/android-futex-contention.py
@@ -0,0 +1,115 @@
+# futex contention
+# (c) 2010, Arnaldo Carvalho de Melo <acme@redhat.com>
+# Licensed under the terms of the GNU GPL License version 2
+#
+# Translation of:
+#
+# http://sourceware.org/systemtap/wiki/WSFutexContention
+#
+# to perf python scripting.
+#
+# Measures futex contention
+
+import os, sys
+sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace')
+from Util import *
+
+process_names = {}
+thread_thislock = {}
+thread_blocktime = {}
+
+lock_waits = {} # long-lived stats on (tid,lock) blockage elapsed time
+waker_wakee = {} # maps the futex waker to wakee
+max_waits = {} # Details about a maximum contention like owner, owner chain
+process_names = {} # long-lived pid-to-execname mapping
+
+def android_lock(callchain):
+    for c in callchain:
+        if 'sym' in c and 'name' in c['sym']:
+            name = c['sym']['name']
+        else:
+            continue
+
+        if 'art::Monitor::Lock' in name:
+            return True
+    return False
+
+def print_callchain(callchain):
+    for c in callchain:
+        if 'sym' in c and 'name' in c['sym']:
+            name = c['sym']['name']
+        else:
+            continue
+
+        print("    %s" % (name))
+
+def sched__sched_waking(event_name, context, common_cpu,
+        common_secs, common_nsecs, common_pid, common_comm,
+        common_callchain, comm, pid, prio, success,
+        target_cpu):
+        waker_wakee[pid] = [common_pid, common_callchain]
+
+def syscalls__sys_enter_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
+			      nr, uaddr, op, val, utime, uaddr2, val3):
+
+	cmd = op & FUTEX_CMD_MASK
+        if cmd != FUTEX_WAIT or android_lock(callchain) == False:
+		return # we don't care about originators of WAKE events 
+                       # or futex uses that aren't android locks.
+
+	process_names[tid] = comm
+	thread_thislock[tid] = uaddr
+	thread_blocktime[tid] = nsecs(s, ns)
+
+def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain,
+			     nr, ret):
+
+        waker_pid = -1
+        waker_chain = "[no call chain]"
+
+	if thread_blocktime.has_key(tid):
+                # Gather stats about the contention (sum, min, max)
+		elapsed = nsecs(s, ns) - thread_blocktime[tid]
+		add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed)
+
+                # Track details about the maximum contention seen
+                # including owner and its callchain
+                if (tid, thread_thislock[tid]) in waker_wakee:
+                    prev_wait = waker_wakee[(tid, thread_thislock[tid])][0]
+                else:
+                    prev_wait = 0
+
+                if elapsed > prev_wait:
+                    if tid in waker_wakee:
+                        waker_pid = waker_wakee[tid][0]
+                        waker_chain = waker_wakee[tid][1]
+
+                    max_waits[(tid, thread_thislock[tid])] = [elapsed, waker_pid, waker_chain, callchain]
+
+		del thread_blocktime[tid]
+		del thread_thislock[tid]
+
+def trace_begin():
+	print "Press control+C to stop and show the summary"
+
+def trace_end():
+	for (tid, lock) in lock_waits:
+                print("\n==============================================================\n")
+		min, max, avg, count = lock_waits[tid, lock]
+		print "%s[%d] lock %x contended %d times, %d avg ns, %d max ns" % \
+		      (process_names[tid], tid, lock, count, avg, max)
+                print ""
+
+                if not (tid, lock) in max_waits:
+                    print"Max contention info not available"
+                    continue
+
+                print "Callstack of suffering task:"
+                print_callchain(max_waits[tid, lock][3])
+                print ""
+
+                waker_pid = max_waits[tid, lock][1]
+                waker_name = process_names[waker_pid] if waker_pid in process_names else "nameless-owner"
+                print "Owner %s caused this contention of %d. Owner's Call stack below:" % (waker_name, max_waits[tid, lock][0])
+                print_callchain(max_waits[tid, lock][2])
+