Add ScopedThreadSuspension
Fixes the TransitionFromRunnableToSuspended and
TransitionFromSuspendedToRunnable pattern that was prone to errors.
Change-Id: Ie6ae9c0357c83b4fc4899d05dfa0975553170267
diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc
index 961b80f..9292c7a 100644
--- a/runtime/gc/heap.cc
+++ b/runtime/gc/heap.cc
@@ -887,13 +887,14 @@
// easily broken. Visit objects while GC isn't running by using
// IncrementDisableMovingGC() and threads are suspended.
IncrementDisableMovingGC(self);
- self->TransitionFromRunnableToSuspended(kWaitingForVisitObjects);
- ThreadList* tl = Runtime::Current()->GetThreadList();
- tl->SuspendAll(__FUNCTION__);
- VisitObjectsInternalRegionSpace(callback, arg);
- VisitObjectsInternal(callback, arg);
- tl->ResumeAll();
- self->TransitionFromSuspendedToRunnable();
+ {
+ ScopedThreadSuspension sts(self, kWaitingForVisitObjects);
+ ThreadList* tl = Runtime::Current()->GetThreadList();
+ tl->SuspendAll(__FUNCTION__);
+ VisitObjectsInternalRegionSpace(callback, arg);
+ VisitObjectsInternal(callback, arg);
+ tl->ResumeAll();
+ }
DecrementDisableMovingGC(self);
} else {
// GCs can move objects, so don't allow this.
diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc
index e1c5b64..77f606d 100644
--- a/runtime/gc/space/dlmalloc_space.cc
+++ b/runtime/gc/space/dlmalloc_space.cc
@@ -298,18 +298,16 @@
}
}
-void DlMallocSpace::LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) {
- UNUSED(failed_alloc_bytes);
- Thread* self = Thread::Current();
+void DlMallocSpace::LogFragmentationAllocFailure(std::ostream& os,
+ size_t failed_alloc_bytes ATTRIBUTE_UNUSED) {
+ Thread* const self = Thread::Current();
size_t max_contiguous_allocation = 0;
// To allow the Walk/InspectAll() to exclusively-lock the mutator
// lock, temporarily release the shared access to the mutator
// lock here by transitioning to the suspended state.
Locks::mutator_lock_->AssertSharedHeld(self);
- self->TransitionFromRunnableToSuspended(kSuspended);
+ ScopedThreadSuspension sts(self, kSuspended);
Walk(MSpaceChunkCallback, &max_contiguous_allocation);
- self->TransitionFromSuspendedToRunnable();
- Locks::mutator_lock_->AssertSharedHeld(self);
os << "; failed due to fragmentation (largest possible contiguous allocation "
<< max_contiguous_allocation << " bytes)";
}
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index 1a193c3..d8072ea 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -331,10 +331,8 @@
// The mutators are not suspended yet and we have a shared access
// to the mutator lock. Temporarily release the shared access by
// transitioning to the suspend state, and suspend the mutators.
- self->TransitionFromRunnableToSuspended(kSuspended);
+ ScopedThreadSuspension sts(self, kSuspended);
InspectAllRosAllocWithSuspendAll(callback, arg, do_null_callback_at_end);
- self->TransitionFromSuspendedToRunnable();
- Locks::mutator_lock_->AssertSharedHeld(self);
} else {
// The mutators are not suspended yet. Suspend the mutators.
InspectAllRosAllocWithSuspendAll(callback, arg, do_null_callback_at_end);