Support for contention logging with ART futexes.

Remove dangerous postfix operators on AtomicInteger. Clean up the atomic stack.
Factor nanosleep into a useful shared utils.h routine.

Change-Id: I417a73007c23fe247f410f41b2fa41a717c22139
diff --git a/src/base/mutex.h b/src/base/mutex.h
index 190e779..8576c03 100644
--- a/src/base/mutex.h
+++ b/src/base/mutex.h
@@ -41,8 +41,16 @@
 #define HAVE_TIMED_RWLOCK 0
 #endif
 
+// Record Log contention information, dumpable via SIGQUIT.
+#define CONTENTION_LOGGING (0 && ART_USE_FUTEXES)
+const size_t kContentionLogSize = 64;
+#if CONTENTION_LOGGING
+#include "atomic_integer.h"
+#endif
+
 namespace art {
 
+class ScopedContentionRecorder;
 class Thread;
 
 const bool kDebugLocking = kIsDebugBuild;
@@ -57,17 +65,43 @@
   virtual bool IsMutex() const { return false; }
   virtual bool IsReaderWriterMutex() const { return false; }
 
+  virtual void Dump(std::ostream& os) const = 0;
+
+  static void DumpAll(std::ostream& os);
+
  protected:
   friend class ConditionVariable;
 
   BaseMutex(const char* name, LockLevel level);
-  virtual ~BaseMutex() {}
+  virtual ~BaseMutex();
   void RegisterAsLocked(Thread* self);
   void RegisterAsUnlocked(Thread* self);
   void CheckSafeToWait(Thread* self);
 
+  friend class ScopedContentionRecorder;
+
+  void RecordContention(uint64_t blocked_tid, uint64_t owner_tid, uint64_t milli_time_blocked);
+  void DumpContention(std::ostream& os) const;
+
   const LockLevel level_;  // Support for lock hierarchy.
   const std::string name_;
+#if CONTENTION_LOGGING
+  // A log entry that records contention but makes no guarantee that either tid will be held live.
+  struct ContentionLogEntry {
+    ContentionLogEntry() : blocked_tid(0), owner_tid(0) {}
+    uint64_t blocked_tid;
+    uint64_t owner_tid;
+    AtomicInteger count;
+  };
+  ContentionLogEntry contention_log_[kContentionLogSize];
+  // The next entry in the contention log to be updated. Value ranges from 0 to
+  // kContentionLogSize - 1.
+  AtomicInteger cur_content_log_entry_;
+  // Number of times the Mutex has been contended.
+  AtomicInteger contention_count_;
+  // Sum of time waited by all contenders in ms.
+  AtomicInteger wait_time_;
+#endif
 };
 
 // A Mutex is used to achieve mutual exclusion between threads. A Mutex can be used to gain
@@ -129,7 +163,7 @@
     return recursion_count_;
   }
 
-  std::string Dump() const;
+  virtual void Dump(std::ostream& os) const;
 
  private:
 #if ART_USE_FUTEXES
@@ -240,7 +274,7 @@
   // Id associated with exclusive owner.
   uint64_t GetExclusiveOwnerTid() const;
 
-  std::string Dump() const;
+  virtual void Dump(std::ostream& os) const;
 
  private:
 #if ART_USE_FUTEXES