Make Mutexes work on Mac OS X 10.6
Change-Id: I1692f78df5891be91d620050b7214083fbafb10f
diff --git a/src/mutex.cc b/src/mutex.cc
index 18c9453..eef8bdc 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -35,18 +35,27 @@
namespace art {
-// This works on Mac OS 10.7, but hasn't been tested on older releases.
+// This works on Mac OS 10.6 but hasn't been tested on older releases.
struct __attribute__((__may_alias__)) darwin_pthread_mutex_t {
- uint32_t padding0[4];
- intptr_t padding1;
- uintptr_t owner_tid;
+ long padding0;
+ int padding1;
+ uint32_t padding2;
+ int16_t padding3;
+ int16_t padding4;
+ uint32_t padding5;
+ pthread_t darwin_pthread_mutex_owner;
// ...other stuff we don't care about.
};
struct __attribute__((__may_alias__)) darwin_pthread_rwlock_t {
- int32_t padding0[4];
- intptr_t padding1[2];
- uintptr_t rw_owner_tid;
+ long padding0;
+ pthread_mutex_t padding1;
+ int padding2;
+ pthread_cond_t padding3;
+ pthread_cond_t padding4;
+ int padding5;
+ int padding6;
+ pthread_t darwin_pthread_rwlock_owner;
// ...other stuff we don't care about.
};
@@ -178,9 +187,9 @@
Mutex::Mutex(const char* name, MutexLevel level, bool recursive)
: BaseMutex(name, level), recursive_(recursive), recursion_count_(0) {
-#if defined(__BIONIC__)
- // Use recursive mutexes as Bionic's non-recursive mutexes don't have TIDs to check lock
- // ownership of.
+#if defined(__BIONIC__) || defined(__APPLE__)
+ // Use recursive mutexes for bionic and Apple otherwise the
+ // non-recursive mutexes don't have TIDs to check lock ownership of.
pthread_mutexattr_t attributes;
CHECK_MUTEX_CALL(pthread_mutexattr_init, (&attributes));
CHECK_MUTEX_CALL(pthread_mutexattr_settype, (&attributes, PTHREAD_MUTEX_RECURSIVE));
@@ -267,7 +276,14 @@
#elif defined(__GLIBC__)
return reinterpret_cast<const glibc_pthread_mutex_t*>(&mutex_)->owner;
#elif defined(__APPLE__)
- return reinterpret_cast<const darwin_pthread_mutex_t*>(&mutex_)->owner_tid;
+ const darwin_pthread_mutex_t* dpmutex = reinterpret_cast<const darwin_pthread_mutex_t*>(&mutex_);
+ pthread_t owner = dpmutex->darwin_pthread_mutex_owner;
+ if ((owner == (pthread_t)0) || (owner == (pthread_t)-1)) {
+ return 0;
+ }
+ uint64_t tid;
+ CHECK_PTHREAD_CALL(pthread_threadid_np, (owner, &tid), __FUNCTION__); // Requires Mac OS 10.6
+ return tid;
#else
#error unsupported C library
#endif
@@ -369,7 +385,14 @@
#elif defined(__GLIBC__)
return reinterpret_cast<const glibc_pthread_rwlock_t*>(&rwlock_)->writer;
#elif defined(__APPLE__)
- return reinterpret_cast<const darwin_pthread_rwlock_t*>(&rwlock_)->rw_owner_tid;
+ const darwin_pthread_rwlock_t* dprwlock = reinterpret_cast<const darwin_pthread_rwlock_t*>(&rwlock_);
+ pthread_t owner = dprwlock->darwin_pthread_rwlock_owner;
+ if (owner == (pthread_t)0) {
+ return 0;
+ }
+ uint64_t tid;
+ CHECK_PTHREAD_CALL(pthread_threadid_np, (owner, &tid), __FUNCTION__); // Requires Mac OS 10.6
+ return tid;
#else
#error unsupported C library
#endif
diff --git a/src/mutex_test.cc b/src/mutex_test.cc
index 8a40cd6..a998939 100644
--- a/src/mutex_test.cc
+++ b/src/mutex_test.cc
@@ -137,6 +137,7 @@
TEST_F(MutexTest, SharedLockUnlock) {
ReaderWriterMutex mu("test rwmutex");
mu.AssertNotHeld();
+ mu.AssertNotExclusiveHeld();
mu.SharedLock();
mu.AssertSharedHeld();
mu.AssertNotExclusiveHeld();
diff --git a/src/utils.cc b/src/utils.cc
index d8b0837..6f18c27 100644
--- a/src/utils.cc
+++ b/src/utils.cc
@@ -53,16 +53,10 @@
namespace art {
pid_t GetTid() {
-#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
- // Darwin has a gettid(2), but it does something completely unrelated to tids.
- // There is a thread_selfid(2) that does what we want though, and it seems to be what their
- // pthreads implementation uses.
- return syscall(SYS_thread_selfid);
-#elif defined(__APPLE__)
- // On Mac OS 10.5 (which the build servers are still running) there was nothing usable.
- // We know we build 32-bit binaries and that the pthread_t is a pointer that uniquely identifies
- // the calling thread.
- return reinterpret_cast<pid_t>(pthread_self());
+#if defined(__APPLE__)
+ uint64_t owner;
+ CHECK_PTHREAD_CALL(pthread_threadid_np, (NULL, &owner), __FUNCTION__); // Requires Mac OS 10.6
+ return owner;
#else
// Neither bionic nor glibc exposes gettid(2).
return syscall(__NR_gettid);