summaryrefslogtreecommitdiff
path: root/runtime/thread_list.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/thread_list.cc')
-rw-r--r--runtime/thread_list.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/runtime/thread_list.cc b/runtime/thread_list.cc
index bddebbd5e7..ac5750b01c 100644
--- a/runtime/thread_list.cc
+++ b/runtime/thread_list.cc
@@ -269,6 +269,36 @@ size_t ThreadList::RunCheckpoint(Closure* checkpoint_function) {
return count + suspended_count_modified_threads.size() + 1;
}
+// Request that a checkpoint function be run on all active (non-suspended)
+// threads. Returns the number of successful requests.
+size_t ThreadList::RunCheckpointOnRunnableThreads(Closure* checkpoint_function) {
+ Thread* self = Thread::Current();
+ if (kIsDebugBuild) {
+ Locks::mutator_lock_->AssertNotExclusiveHeld(self);
+ Locks::thread_list_lock_->AssertNotHeld(self);
+ Locks::thread_suspend_count_lock_->AssertNotHeld(self);
+ CHECK_NE(self->GetState(), kRunnable);
+ }
+
+ size_t count = 0;
+ {
+ // Call a checkpoint function for each non-suspended thread.
+ MutexLock mu(self, *Locks::thread_list_lock_);
+ MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
+ for (const auto& thread : list_) {
+ if (thread != self) {
+ if (thread->RequestCheckpoint(checkpoint_function)) {
+ // This thread will run its checkpoint some time in the near future.
+ count++;
+ }
+ }
+ }
+ }
+
+ // Return the number of threads that will run the checkpoint function.
+ return count;
+}
+
void ThreadList::SuspendAll() {
Thread* self = Thread::Current();
DCHECK(self != nullptr);