Mac build fix. Macs don't support timeouts on locks.
Change-Id: I75665300d9b99420972865109026c8c090748cef
diff --git a/src/mutex.cc b/src/mutex.cc
index dc33fbe..18c94535 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -302,10 +302,8 @@
CHECK_MUTEX_CALL(pthread_rwlock_unlock, (&rwlock_));
}
+#if HAVE_TIMED_RWLOCK
bool ReaderWriterMutex::ExclusiveLockWithTimeout(const timespec& abs_timeout) {
- // Check that timeouts are supported. Currently Darwin doesn't support timeouts, if we are
- // running on Darwin the timeout won't be respected.
-#if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112) >= 0L
int result = pthread_rwlock_timedwrlock(&rwlock_, &abs_timeout);
if (result == ETIMEDOUT) {
return false;
@@ -317,12 +315,8 @@
RegisterAsLockedWithCurrentThread();
AssertSharedHeld();
return true;
-#else
- UNUSED(abs_timeout);
- ExclusiveLock();
- return true;
-#endif
}
+#endif
void ReaderWriterMutex::SharedLock() {
CHECK_MUTEX_CALL(pthread_rwlock_rdlock, (&rwlock_));
diff --git a/src/mutex.h b/src/mutex.h
index 4899382..edd458d 100644
--- a/src/mutex.h
+++ b/src/mutex.h
@@ -28,6 +28,13 @@
#include "logging.h"
#include "macros.h"
+// Currently Darwin doesn't support locks with timeouts.
+#if !defined(__APPLE__)
+#define HAVE_TIMED_RWLOCK 1
+#else
+#define HAVE_TIMED_RWLOCK 0
+#endif
+
namespace art {
class LOCKABLE Mutex;
@@ -271,7 +278,9 @@
// Block until ReaderWriterMutex is free and acquire exclusive access. Returns true on success
// or false if timeout is reached.
+#if HAVE_TIMED_RWLOCK
bool ExclusiveLockWithTimeout(const timespec& abs_timeout) EXCLUSIVE_TRYLOCK_FUNCTION(true);
+#endif
// Block until ReaderWriterMutex is shared or free then acquire a share on the access.
void SharedLock() SHARED_LOCK_FUNCTION();
diff --git a/src/thread_list.cc b/src/thread_list.cc
index 0bd587c..6008e16 100644
--- a/src/thread_list.cc
+++ b/src/thread_list.cc
@@ -21,6 +21,7 @@
#include <unistd.h>
#include "debugger.h"
+#include "mutex.h"
#include "timing_logger.h"
#include "utils.h"
@@ -125,6 +126,7 @@
}
}
+#if HAVE_TIMED_RWLOCK
// Attempt to rectify locks so that we dump thread list with required locks before exiting.
static void UnsafeLogFatalForThreadSuspendAllTimeout() NO_THREAD_SAFETY_ANALYSIS {
Runtime* runtime = Runtime::Current();
@@ -143,6 +145,7 @@
runtime->GetThreadList()->DumpLocked(ss);
LOG(FATAL) << ss.str();
}
+#endif
void ThreadList::SuspendAll() {
Thread* self = Thread::Current();
@@ -174,14 +177,18 @@
}
}
- // Block on the mutator lock until all Runnable threads release their share of access. Timeout
- // if we wait more than 30 seconds.
+ // Block on the mutator lock until all Runnable threads release their share of access.
+#if HAVE_TIMED_RWLOCK
+ // Timeout if we wait more than 30 seconds.
timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += 30;
if (UNLIKELY(!GlobalSynchronization::mutator_lock_->ExclusiveLockWithTimeout(timeout))) {
UnsafeLogFatalForThreadSuspendAllTimeout();
}
+#else
+ GlobalSynchronization::mutator_lock_->ExclusiveLock();
+#endif
// Debug check that all threads are suspended.
AssertThreadsAreSuspended();
@@ -266,18 +273,22 @@
}
}
- // Block on the mutator lock until all Runnable threads release their share of access. Timeout
- // if we wait more than 30 seconds.
+ // Block on the mutator lock until all Runnable threads release their share of access then
+ // immediately unlock again.
+#if HAVE_TIMED_RWLOCK
+ // Timeout if we wait more than 30 seconds.
timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += 30;
if (!GlobalSynchronization::mutator_lock_->ExclusiveLockWithTimeout(timeout)) {
UnsafeLogFatalForThreadSuspendAllTimeout();
} else {
- // Debugger suspends all threads but doesn't hold onto the mutator_lock_.
GlobalSynchronization::mutator_lock_->ExclusiveUnlock();
}
-
+#else
+ GlobalSynchronization::mutator_lock_->ExclusiveLock();
+ GlobalSynchronization::mutator_lock_->ExclusiveUnlock();
+#endif
AssertThreadsAreSuspended();
VLOG(threads) << *self << " SuspendAll complete";