Add more functionality to the thread and mutex implementation.

Change-Id: I33b2e53acb4c4c6653f13f1bbdd77cc7ce27e581
diff --git a/src/thread.cc b/src/thread.cc
new file mode 100644
index 0000000..abd45db
--- /dev/null
+++ b/src/thread.cc
@@ -0,0 +1,104 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+
+#include "src/thread.h"
+
+#include <algorithm>
+#include <list>
+#include <errno.h>
+#include <pthread.h>
+
+#include "src/runtime.h"
+
+namespace art {
+
+pthread_key_t Thread::pthread_key_self_;
+
+Mutex* Mutex::Create(const char* name) {
+  Mutex* mu = new Mutex(name);
+  int result = pthread_mutex_init(&mu->lock_impl_, NULL);
+  CHECK(result == 0);
+  return mu;
+}
+
+void Mutex::Lock() {
+  int result = pthread_mutex_lock(&lock_impl_);
+  CHECK_EQ(result, 0);
+  SetOwner(Thread::Current());
+}
+
+bool Mutex::TryLock() {
+  int result = pthread_mutex_lock(&lock_impl_);
+  if (result == EBUSY) {
+    return false;
+  } else {
+    CHECK_EQ(result, 0);
+    SetOwner(Thread::Current());
+    return true;
+  }
+}
+
+void Mutex::Unlock() {
+  CHECK(GetOwner() == Thread::Current());
+  int result = pthread_mutex_unlock(&lock_impl_);
+  CHECK_EQ(result, 0);
+  SetOwner(Thread::Current());
+}
+
+Thread* Thread::Create(const char* name) {
+  LOG(FATAL) << "Unimplemented";
+  return NULL;
+}
+
+static void ThreadExitCheck(void* arg) {
+  LG << "Thread exit check";
+}
+
+bool Thread::Init() {
+  // Allocate a TLS slot.
+  if (pthread_key_create(&Thread::pthread_key_self_, ThreadExitCheck) != 0) {
+    LOG(WARN) << "pthread_key_create failed";
+    return false;
+  }
+
+  // Double-check the TLS slot allocation.
+  if (pthread_getspecific(pthread_key_self_) != NULL) {
+    LOG(WARN) << "newly-created pthread TLS slot is not NULL";
+    return false;
+  }
+
+  // TODO: initialize other locks and condition variables
+
+  return true;
+}
+
+ThreadList::ThreadList() {
+  lock_ = Mutex::Create("ThreadList::Lock");
+}
+
+ThreadList::~ThreadList() {
+  // Make sure that all threads have exited and unregistered when we
+  // reach this point. This means that all daemon threads had been
+  // shutdown cleanly.
+  CHECK_EQ(list_.size(), 0);
+  delete lock_;
+  lock_ = NULL;
+}
+
+void ThreadList::Register(Thread* thread) {
+  MutexLock mu(lock_);
+  CHECK(find(list_.begin(), list_.end(), thread) == list_.end());
+  list_.push_front(thread);
+}
+
+void ThreadList::Unregister(Thread* thread) {
+  MutexLock mu(lock_);
+  CHECK(find(list_.begin(), list_.end(), thread) != list_.end());
+  list_.remove(thread);
+}
+
+void ThreadList::Init(Runtime* runtime) {
+  ThreadList* thread_list = new ThreadList();
+  runtime->SetThreadList(thread_list);
+}
+
+}  // namespace