Merge "Restore "CFG rework for explicit exception edges"" into dalvik-dev
diff --git a/src/mutex.cc b/src/mutex.cc
index 182f6f0..18c94535 100644
--- a/src/mutex.cc
+++ b/src/mutex.cc
@@ -267,7 +267,7 @@
#elif defined(__GLIBC__)
return reinterpret_cast<const glibc_pthread_mutex_t*>(&mutex_)->owner;
#elif defined(__APPLE__)
- return reinterpret_cast<darwin_pthread_mutex_t*>(&mutex_)->owner_tid;
+ return reinterpret_cast<const darwin_pthread_mutex_t*>(&mutex_)->owner_tid;
#else
#error unsupported C library
#endif
@@ -302,6 +302,7 @@
CHECK_MUTEX_CALL(pthread_rwlock_unlock, (&rwlock_));
}
+#if HAVE_TIMED_RWLOCK
bool ReaderWriterMutex::ExclusiveLockWithTimeout(const timespec& abs_timeout) {
int result = pthread_rwlock_timedwrlock(&rwlock_, &abs_timeout);
if (result == ETIMEDOUT) {
@@ -309,12 +310,13 @@
}
if (result != 0) {
errno = result;
- PLOG(FATAL) << "pthread_mutex_trylock failed for " << name_;
+ PLOG(FATAL) << "pthread_rwlock_timedwrlock failed for " << name_;
}
RegisterAsLockedWithCurrentThread();
AssertSharedHeld();
return true;
}
+#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";