summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Boehm <hboehm@google.com>2021-08-11 12:11:19 -0700
committerNicolas Geoffray <ngeoffray@google.com>2021-09-04 13:18:18 +0000
commitd4da905ba12bfcd9b967a47583f875bbcafeeda2 (patch)
tree1413702420fb5ee287b77706f79baecfb9185c02
parent1363c1bf72f25f088b1f83250e91a47fc8cc7173 (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.cc4
-rw-r--r--runtime/runtime.h14
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_);