Work around a bionic bug until I can fix bionic.

Also remove the Thread::pthread_ field, which isn't really needed. We also
don't need to update the TLS pointer to our Thread*, because the
address will be the same in the child anyway.

Change-Id: I595832a682a03ccdbb510e8e9ce0a32d5c6526b3
diff --git a/src/asm_support.h b/src/asm_support.h
index f81966f..2f2cf4c 100644
--- a/src/asm_support.h
+++ b/src/asm_support.h
@@ -10,13 +10,13 @@
 #define rSELF r9
 #define rLR r14
 // Offset of field Thread::suspend_count_ verified in InitCpu
-#define THREAD_SUSPEND_COUNT_OFFSET 388
+#define THREAD_SUSPEND_COUNT_OFFSET 384
 // Offset of field Thread::suspend_count_ verified in InitCpu
-#define THREAD_EXCEPTION_OFFSET 384
+#define THREAD_EXCEPTION_OFFSET 380
 
 #elif defined(__i386__)
 // Offset of field Thread::self_ verified in InitCpu
-#define THREAD_SELF_OFFSET 376
+#define THREAD_SELF_OFFSET 372
 #endif
 
 #endif  // ART_SRC_ASM_SUPPORT_H_
diff --git a/src/mutex.cc b/src/mutex.cc
index 27bb627..ee096a3 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -67,8 +67,16 @@
 }
 
 pid_t Mutex::GetOwner() {
-#ifdef __BIONIC__
+#if defined(__BIONIC__)
   return static_cast<pid_t>((mutex_.value >> 16) & 0xffff);
+#elif defined(__GLIBC__)
+  struct __attribute__((__may_alias__)) glibc_pthread_t {
+    int lock;
+    unsigned int count;
+    int owner;
+    // ...other stuff we don't care about.
+  };
+  return reinterpret_cast<glibc_pthread_t*>(&mutex_)->owner;
 #else
   UNIMPLEMENTED(FATAL);
   return 0;
diff --git a/src/mutex.h b/src/mutex.h
index 43194e9..37d5510 100644
--- a/src/mutex.h
+++ b/src/mutex.h
@@ -45,15 +45,11 @@
   }
 
   void AssertHeld() {
-#ifdef __BIONIC__
     DCHECK_EQ(GetOwner(), GetTid());
-#endif
   }
 
   void AssertNotHeld() {
-#ifdef __BIONIC__
     DCHECK_NE(GetOwner(), GetTid());
-#endif
   }
 
  private:
diff --git a/src/thread.cc b/src/thread.cc
index cb71dcf..6473df0 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -148,17 +148,19 @@
   tid_ = ::art::GetTid();
 }
 
-void Thread::InitPthread() {
-  pthread_ = pthread_self();
-}
-
-void Thread::InitPthreadKeySelf() {
-  CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach");
-}
-
 void Thread::InitAfterFork() {
   InitTid();
-  InitPthreadKeySelf();
+#if defined(__BIONIC__)
+  // Work around a bionic bug.
+  struct bionic_pthread_internal_t {
+    void*  next;
+    void** pref;
+    pthread_attr_t attr;
+    pid_t kernel_id;
+    // et cetera. we just need 'kernel_id' so we can stop here.
+  };
+  reinterpret_cast<bionic_pthread_internal_t*>(pthread_self())->kernel_id = tid_;
+#endif
 }
 
 void* Thread::CreateCallback(void* arg) {
@@ -236,11 +238,12 @@
   // and know that we're not racing to assign it.
   SetVmData(peer, native_thread);
 
+  pthread_t new_pthread;
   pthread_attr_t attr;
   CHECK_PTHREAD_CALL(pthread_attr_init, (&attr), "new thread");
   CHECK_PTHREAD_CALL(pthread_attr_setdetachstate, (&attr, PTHREAD_CREATE_DETACHED), "PTHREAD_CREATE_DETACHED");
   CHECK_PTHREAD_CALL(pthread_attr_setstacksize, (&attr, stack_size), stack_size);
-  CHECK_PTHREAD_CALL(pthread_create, (&native_thread->pthread_, &attr, Thread::CreateCallback, native_thread), "new thread");
+  CHECK_PTHREAD_CALL(pthread_create, (&new_pthread, &attr, Thread::CreateCallback, native_thread), "new thread");
   CHECK_PTHREAD_CALL(pthread_attr_destroy, (&attr), "new thread");
 
   // Let the child know when it's safe to start running.
@@ -254,11 +257,9 @@
   thin_lock_id_ = Runtime::Current()->GetThreadList()->AllocThreadId();
 
   InitTid();
-  InitPthread();
-
   InitStackHwm();
 
-  InitPthreadKeySelf();
+  CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, this), "attach");
 
   jni_env_ = new JNIEnvExt(this, runtime->GetJavaVM());
 
@@ -325,7 +326,7 @@
 
 void Thread::InitStackHwm() {
   pthread_attr_t attributes;
-  CHECK_PTHREAD_CALL(pthread_getattr_np, (pthread_, &attributes), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_getattr_np, (pthread_self(), &attributes), __FUNCTION__);
 
   void* temp_stack_base;
   CHECK_PTHREAD_CALL(pthread_attr_getstack, (&attributes, &temp_stack_base, &stack_size_),
@@ -406,7 +407,7 @@
 
   int policy;
   sched_param sp;
-  CHECK_PTHREAD_CALL(pthread_getschedparam, (pthread_, &policy, &sp), __FUNCTION__);
+  CHECK_PTHREAD_CALL(pthread_getschedparam, (pthread_self(), &policy, &sp), __FUNCTION__);
 
   std::string scheduler_group(GetSchedulerGroup(GetTid()));
   if (scheduler_group.empty()) {
@@ -431,7 +432,7 @@
      << " nice=" << getpriority(PRIO_PROCESS, GetTid())
      << " sched=" << policy << "/" << sp.sched_priority
      << " cgrp=" << scheduler_group
-     << " handle=" << GetImpl() << "\n";
+     << " handle=" << pthread_self() << "\n";
 
   // Grab the scheduler stats for this thread.
   std::string scheduler_stats;
@@ -1369,7 +1370,6 @@
 
 std::ostream& operator<<(std::ostream& os, const Thread& thread) {
   os << "Thread[" << &thread
-     << ",pthread_t=" << thread.GetImpl()
      << ",tid=" << thread.GetTid()
      << ",id=" << thread.GetThinLockId()
      << ",state=" << thread.GetState()
diff --git a/src/thread.h b/src/thread.h
index 0884d6a..e0c5d19 100644
--- a/src/thread.h
+++ b/src/thread.h
@@ -223,10 +223,6 @@
     return tid_;
   }
 
-  pthread_t GetImpl() const {
-    return pthread_;
-  }
-
   Object* GetPeer() const {
     return peer_;
   }
@@ -475,7 +471,6 @@
   void InitCpu();
   void InitFunctionPointers();
   void InitTid();
-  void InitPthread();
   void InitPthreadKeySelf();
   void InitStackHwm();
 
@@ -499,9 +494,6 @@
   // System thread id.
   pid_t tid_;
 
-  // Native thread handle.
-  pthread_t pthread_;
-
   // Our managed peer (an instance of java.lang.Thread).
   Object* peer_;