From 0c3cc6350749a441fd54f8f3f67b7c69775000c8 Mon Sep 17 00:00:00 2001 From: Hans Boehm Date: Thu, 5 Aug 2021 18:30:08 -0700 Subject: Handle suspend requests in getReferent() When waiting in getReferent or the like, use a TimedWait, so we can occasionally check for suspend requests, thus avoiding deadlocks that can arise from blocking indefinitely in a runnable state. This is not particularly clean, and may introduce short delays when we would otherwise deadlock. It's also a bit risky because we are now releasing the mutator lock in code that previously didn't. This is a hopefully more correct replacement for aosp/1784003, which overlooked some of the complications here. This does not handle a similar problem in the JNI weak reference code. Each additional use context adds risk here, due to the mutator lock release. Bug: 195336624 Bug: 195664026 Test: Build and boot AOSP with much shorter timeouts. Test: Confirm that the timeout code is invoked. Change-Id: I0ffb2ffd105bed9dcb8664f92b17cfbcf756a6e0 --- runtime/gc/reference_processor.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'runtime/gc/reference_processor.h') diff --git a/runtime/gc/reference_processor.h b/runtime/gc/reference_processor.h index 54de5cc572..8ea7bb1297 100644 --- a/runtime/gc/reference_processor.h +++ b/runtime/gc/reference_processor.h @@ -58,7 +58,7 @@ class ReferenceProcessor { // GetReferent fast path as an optimization. void EnableSlowPath() REQUIRES_SHARED(Locks::mutator_lock_); void BroadcastForSlowPath(Thread* self); - // Decode the referent, may block if references are being processed. + // Decode the referent, may block and allow suspension if references are being processed. ObjPtr GetReferent(Thread* self, ObjPtr reference) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::reference_processor_lock_); // Collects the cleared references and returns a task, to be executed after FinishGC, that will @@ -89,7 +89,7 @@ class ReferenceProcessor { // referents. void StartPreservingReferences(Thread* self) REQUIRES(!Locks::reference_processor_lock_); void StopPreservingReferences(Thread* self) REQUIRES(!Locks::reference_processor_lock_); - // Wait until reference processing is done. + // Wait until reference processing is done. May temporarily release both required locks. void WaitUntilDoneProcessingReferences(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::reference_processor_lock_); -- cgit v1.2.3-59-g8ed1b