Fix thread hang

- Primary problem was ScopedThreadListLock was releasing heap lock in constructor instead of destructor
- Secondary problem was ScopedThreadListLock should not be used with Mutex::Wait
- Added Thread.getStackTrace case to ThreadStress that reproduces YouTube problem
- Added Mutex::GetDepth and related methods that were useful in diagnoising this issue

Change-Id: I1bdc7245e9b411378b98f4dcf498ad66eb96366d
diff --git a/src/mutex_test.cc b/src/mutex_test.cc
new file mode 100644
index 0000000..bafd789
--- /dev/null
+++ b/src/mutex_test.cc
@@ -0,0 +1,53 @@
+// Copyright 2012 Google Inc. All Rights Reserved.
+
+#include "mutex.h"
+
+#include "gtest/gtest.h"
+
+namespace art {
+
+TEST(Mutex, LockUnlock) {
+  Mutex mu("test mutex");
+  mu.AssertDepth(0U);
+  mu.Lock();
+  mu.AssertDepth(1U);
+  mu.Unlock();
+  mu.AssertDepth(0U);
+}
+
+TEST(Mutex, TryLockUnlock) {
+  Mutex mu("test mutex");
+  mu.AssertDepth(0U);
+  mu.TryLock();
+  mu.AssertDepth(1U);
+  mu.Unlock();
+  mu.AssertDepth(0U);
+}
+
+TEST(Mutex, RecursiveLockUnlock) {
+  Mutex mu("test mutex");
+  mu.AssertDepth(0U);
+  mu.Lock();
+  mu.AssertDepth(1U);
+  mu.Lock();
+  mu.AssertDepth(2U);
+  mu.Unlock();
+  mu.AssertDepth(1U);
+  mu.Unlock();
+  mu.AssertDepth(0U);
+}
+
+TEST(Mutex, RecursiveTryLockUnlock) {
+  Mutex mu("test mutex");
+  mu.AssertDepth(0U);
+  mu.TryLock();
+  mu.AssertDepth(1U);
+  mu.TryLock();
+  mu.AssertDepth(2U);
+  mu.Unlock();
+  mu.AssertDepth(1U);
+  mu.Unlock();
+  mu.AssertDepth(0U);
+}
+
+}  // namespace art