summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathieu Chartier <mathieuc@google.com>2014-07-16 01:44:49 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-07-15 20:36:09 +0000
commitfbde4dd1cb6db729e3f3ee5bdae0cdd824d73054 (patch)
tree1cd54bee2823ab0b57412c10cf718e20ba9dc645
parentebaca192314e21d26b97646fa962e468ff07b893 (diff)
parent251755cd511463260e60be98bf138b6aa1c14bf3 (diff)
downloadart-fbde4dd1cb6db729e3f3ee5bdae0cdd824d73054.zip
art-fbde4dd1cb6db729e3f3ee5bdae0cdd824d73054.tar.gz
art-fbde4dd1cb6db729e3f3ee5bdae0cdd824d73054.tar.bz2
Merge "Use sched_yield in Monitor::MonitorEnter."
-rw-r--r--runtime/monitor.cc6
-rw-r--r--runtime/thread_list.cc9
2 files changed, 13 insertions, 2 deletions
diff --git a/runtime/monitor.cc b/runtime/monitor.cc
index 5633a77..da481e4 100644
--- a/runtime/monitor.cc
+++ b/runtime/monitor.cc
@@ -746,7 +746,11 @@ mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj) {
contention_count++;
Runtime* runtime = Runtime::Current();
if (contention_count <= runtime->GetMaxSpinsBeforeThinkLockInflation()) {
- NanoSleep(1000); // Sleep for 1us and re-attempt.
+ // TODO: Consider switch thread state to kBlocked when we are yielding.
+ // Use sched_yield instead of NanoSleep since NanoSleep can wait much longer than the
+ // parameter you pass in. This can cause thread suspension to take excessively long
+ // make long pauses. See b/16307460.
+ sched_yield();
} else {
contention_count = 0;
InflateThinLocked(self, h_obj, lock_word, 0);
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index 54732fa..b649b62 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -39,6 +39,8 @@
namespace art {
+static constexpr uint64_t kLongThreadSuspendThreshold = MsToNs(5);
+
ThreadList::ThreadList()
: suspend_all_count_(0), debug_suspend_all_count_(0),
thread_exit_cond_("thread exit condition variable", *Locks::thread_list_lock_) {
@@ -304,8 +306,8 @@ void ThreadList::SuspendAll() {
DCHECK(self != nullptr);
VLOG(threads) << *self << " SuspendAll starting...";
-
ATRACE_BEGIN("Suspending mutator threads");
+ uint64_t start_time = NanoTime();
Locks::mutator_lock_->AssertNotHeld(self);
Locks::thread_list_lock_->AssertNotHeld(self);
@@ -338,6 +340,11 @@ void ThreadList::SuspendAll() {
Locks::mutator_lock_->ExclusiveLock(self);
#endif
+ uint64_t end_time = NanoTime();
+ if (end_time - start_time > kLongThreadSuspendThreshold) {
+ LOG(WARNING) << "Suspending all threads took: " << PrettyDuration(end_time - start_time);
+ }
+
if (kDebugLocking) {
// Debug check that all threads are suspended.
AssertThreadsAreSuspended(self, self);