diff options
author | Hans Boehm <hboehm@google.com> | 2021-08-11 12:11:19 -0700 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2021-09-04 13:18:18 +0000 |
commit | d4da905ba12bfcd9b967a47583f875bbcafeeda2 (patch) | |
tree | 1413702420fb5ee287b77706f79baecfb9185c02 | |
parent | 1363c1bf72f25f088b1f83250e91a47fc8cc7173 (diff) |
Do not acquire runtime_shutdown_lock_ in Abort()
Abort can be called, particularly in OOM situations, when we already
hold the lock. Abort() should minimize the locks it acquires.
This is intended to be a minimal, low-risk change. Generated code
should be essentially unchanged, except in Abort(). This does not
address the question of whether IsShuttingDown really needs to
lock at all.
Test: Build and boot AOSP.
Bug: 195884830
Merged-In: I0ee4a7ca7348153436fec0fecc1d1f2ca1f7a30c
(cherry picked from commit 70aa29e2d93ba66e71a8ff88c9210719efae1c31)
Change-Id: I9d7dca18bc480a37197bca3205834da13321cc58
(cherry picked from commit aefbed79a1e37d6901228b0a7e03ce63c2495703)
-rw-r--r-- | runtime/runtime.cc | 4 | ||||
-rw-r--r-- | runtime/runtime.h | 14 |
2 files changed, 13 insertions, 5 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 433f564b2d..6c99c1fa8d 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -410,7 +410,7 @@ Runtime::~Runtime() { while (threads_being_born_ > 0) { shutdown_cond_->Wait(self); } - shutting_down_ = true; + SetShuttingDown(); } // Shutdown and wait for the daemons. CHECK(self != nullptr); @@ -641,7 +641,7 @@ void Runtime::Abort(const char* msg) { // May be coming from an unattached thread. if (Thread::Current() == nullptr) { Runtime* current = Runtime::Current(); - if (current != nullptr && current->IsStarted() && !current->IsShuttingDown(nullptr)) { + if (current != nullptr && current->IsStarted() && !current->IsShuttingDownUnsafe()) { // We do not flag this to the unexpected-signal handler so that that may dump the stack. abort(); UNREACHABLE(); diff --git a/runtime/runtime.h b/runtime/runtime.h index 68456cd37b..b2093a303c 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -222,7 +222,13 @@ class Runtime { bool IsShuttingDown(Thread* self); bool IsShuttingDownLocked() const REQUIRES(Locks::runtime_shutdown_lock_) { - return shutting_down_; + return shutting_down_.load(std::memory_order_relaxed); + } + bool IsShuttingDownUnsafe() const { + return shutting_down_.load(std::memory_order_relaxed); + } + void SetShuttingDown() REQUIRES(Locks::runtime_shutdown_lock_) { + shutting_down_.store(true, std::memory_order_relaxed); } size_t NumberOfThreadsBeingBorn() const REQUIRES(Locks::runtime_shutdown_lock_) { @@ -1190,8 +1196,10 @@ class Runtime { // Waited upon until no threads are being born. std::unique_ptr<ConditionVariable> shutdown_cond_ GUARDED_BY(Locks::runtime_shutdown_lock_); - // Set when runtime shutdown is past the point that new threads may attach. - bool shutting_down_ GUARDED_BY(Locks::runtime_shutdown_lock_); + // Set when runtime shutdown is past the point that new threads may attach. Usually + // GUARDED_BY(Locks::runtime_shutdown_lock_). But we need to check it in Abort without the + // lock, because we may already own it. + std::atomic<bool> shutting_down_; // The runtime is starting to shutdown but is blocked waiting on shutdown_cond_. bool shutting_down_started_ GUARDED_BY(Locks::runtime_shutdown_lock_); |