Lines Matching full:thread
52 #include "thread.h"
89 // Detach the current thread if necessary. If we failed to start, there might not be any threads. in ShutDown()
90 // We need to detach the current thread here in case there's another thread waiting to join with in ShutDown()
93 Thread* self = Thread::Current(); in ShutDown()
107 // TODO: there's an unaddressed race here where a thread may attach during shutdown, see in ShutDown()
108 // Thread::Init. in ShutDown()
114 bool ThreadList::Contains(Thread* thread) { in Contains() argument
115 return find(list_.begin(), list_.end(), thread) != list_.end(); in Contains()
123 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); in DumpNativeStacks()
125 for (const auto& thread : list_) { in DumpNativeStacks() local
126 os << "DUMPING THREAD " << thread->GetTid() << "\n"; in DumpNativeStacks()
127 DumpNativeStack(os, unwinder, thread->GetTid(), "\t"); in DumpNativeStacks()
134 ScopedObjectAccess soa(Thread::Current()); in DumpForSigQuit()
149 // TODO: No thread safety analysis as DumpState with a null thread won't access fields, should in DumpUnattachedThread()
151 Thread::DumpState(os, nullptr, tid); in DumpUnattachedThread()
164 Thread* self = Thread::Current(); in DumpUnattachedThreads()
170 Thread* thread; in DumpUnattachedThreads() local
173 thread = FindThreadByTid(tid); in DumpUnattachedThreads()
175 if (thread == nullptr) { in DumpUnattachedThreads()
187 // A closure used by Thread::Dump.
193 // Avoid verifying count in case a thread doesn't end up passing through the barrier. in DumpCheckpoint()
200 void Run(Thread* thread) override { in Run() argument
201 // Note thread and self may not be equal if thread was already suspended at the point of the in Run()
203 Thread* self = Thread::Current(); in Run()
207 Thread::DumpOrder dump_order = thread->Dump(local_os, unwinder_, dump_native_stack_); in Run()
211 std::pair<Thread::DumpOrder, uint32_t> sort_key(dump_order, thread->GetThreadId()); in Run()
218 void Dump(Thread* self, std::ostream& os) { in Dump()
226 Thread* self = Thread::Current(); in WaitForThreadsToRunThroughCheckpoint()
237 // Storage for the per-thread dumps (guarded by lock since they are generated in parallel).
240 std::multimap<std::pair<Thread::DumpOrder, uint32_t>, std::ostringstream> os_ GUARDED_BY(lock_);
250 Thread* self = Thread::Current(); in Dump()
257 // Acquire mutator lock separately for each thread, to avoid long runnable code sequence in Dump()
272 void ThreadList::AssertOtherThreadsAreSuspended(Thread* self) { in AssertOtherThreadsAreSuspended()
275 for (const auto& thread : list_) { in AssertOtherThreadsAreSuspended() local
276 if (thread != self) { in AssertOtherThreadsAreSuspended()
277 CHECK(thread->IsSuspended()) in AssertOtherThreadsAreSuspended()
278 << "\nUnsuspended thread: <<" << *thread << "\n" in AssertOtherThreadsAreSuspended()
279 << "self: <<" << *Thread::Current(); in AssertOtherThreadsAreSuspended()
285 // Attempt to rectify locks so that we dump thread list with required locks before exiting.
287 // Increment gAborting before doing the thread list dump since we don't want any failures from in UnsafeLogFatalForThreadSuspendAllTimeout()
288 // AssertThreadSuspensionIsAllowable in cases where thread suspension is not allowed. in UnsafeLogFatalForThreadSuspendAllTimeout()
293 ss << "Thread suspend timeout\n"; in UnsafeLogFatalForThreadSuspendAllTimeout()
307 Thread* self = Thread::Current(); in RunCheckpoint()
316 std::vector<Thread*> remaining_threads; in RunCheckpoint()
322 // Thread-safety analysis wants the lock state to always be the same at every program point. in RunCheckpoint()
337 // First try to install checkpoint function in each thread. This will succeed only for in RunCheckpoint()
340 for (const auto& thread : list_) { in RunCheckpoint() local
341 if (thread != self) { in RunCheckpoint()
342 if (thread->RequestCheckpoint(checkpoint_function)) { in RunCheckpoint()
343 // This thread will run its checkpoint some time in the near future. in RunCheckpoint()
345 remaining_threads.push_back(thread); in RunCheckpoint()
348 // Thread either has honored or will honor the checkpoint, or it has been added to in RunCheckpoint()
355 // Register a ThreadExitFlag for each remaining thread. in RunCheckpoint()
373 Thread* thread = remaining_threads[i]; in RunCheckpoint() local
374 if (thread == nullptr) { in RunCheckpoint()
382 bool was_runnable = thread->RequestCheckpoint(checkpoint_function); in RunCheckpoint()
384 // Thread became runnable, and will run the checkpoint; we're done. in RunCheckpoint()
385 thread->UnregisterThreadExitFlag(&tefs[i]); in RunCheckpoint()
389 // Thread was still suspended, as expected. in RunCheckpoint()
390 // We need to run the checkpoint ourselves. Suspend thread so it stays suspended. in RunCheckpoint()
391 thread->IncrementSuspendCount(self); in RunCheckpoint()
392 if (LIKELY(thread->IsSuspended())) { in RunCheckpoint()
399 // checkpoint on behalf of thread. in RunCheckpoint()
400 Thread::EnsureFlipFunctionStarted(self, thread); in RunCheckpoint()
401 if (thread->GetStateAndFlags(std::memory_order_acquire) in RunCheckpoint()
402 .IsAnyOfFlagsSet(Thread::FlipFunctionFlags())) { in RunCheckpoint()
403 // There is another thread running the flip function for 'thread'. in RunCheckpoint()
404 // Instead of waiting for it to complete, move to the next thread. in RunCheckpoint()
409 thread->DecrementSuspendCount(self); in RunCheckpoint()
410 Thread::resume_cond_->Broadcast(self); in RunCheckpoint()
415 checkpoint_function->Run(thread); in RunCheckpoint()
419 thread->DecrementSuspendCount(self); in RunCheckpoint()
420 // In the case of a thread waiting for IO or the like, there will be no waiters in RunCheckpoint()
422 Thread::resume_cond_->Broadcast(self); in RunCheckpoint()
433 thread->DecrementSuspendCount(self); in RunCheckpoint()
434 Thread::resume_cond_->Broadcast(self); in RunCheckpoint()
436 thread->UnregisterThreadExitFlag(&tefs[i]); in RunCheckpoint()
439 // Thread may have become runnable between the time we last checked and in RunCheckpoint()
443 thread->DecrementSuspendCount(self); in RunCheckpoint()
444 Thread::resume_cond_->Broadcast(self); in RunCheckpoint()
463 DCHECK(std::all_of(remaining_threads.cbegin(), remaining_threads.cend(), [](Thread* thread) { in RunCheckpoint() argument
464 return thread == nullptr; in RunCheckpoint()
466 Thread::DCheckUnregisteredEverywhere(&tefs[0], &tefs[nthreads - 1]); in RunCheckpoint()
475 Thread* self = Thread::Current(); in RunEmptyCheckpoint()
486 for (Thread* thread : list_) { in RunEmptyCheckpoint()
487 if (thread != self) { in RunEmptyCheckpoint()
489 if (thread->RequestEmptyCheckpoint()) { in RunEmptyCheckpoint()
490 // This thread will run an empty checkpoint (decrement the empty checkpoint barrier) in RunEmptyCheckpoint()
494 runnable_thread_ids.push_back(thread->GetThreadId()); in RunEmptyCheckpoint()
498 if (thread->GetState() != ThreadState::kRunnable) { in RunEmptyCheckpoint()
517 // Wake up the runnable threads blocked on the mutexes that another thread, which is blocked in RunEmptyCheckpoint()
518 // on a weak ref access, holds (indirectly blocking for weak ref access through another thread in RunEmptyCheckpoint()
519 // and a mutex.) This needs to be done periodically because the thread may be preempted in RunEmptyCheckpoint()
541 ss << "Runnable thread IDs"; in RunEmptyCheckpoint()
554 for (Thread* thread : GetList()) { in RunEmptyCheckpoint()
555 uint32_t tid = thread->GetThreadId(); in RunEmptyCheckpoint()
560 thread->ReadFlag(ThreadFlag::kEmptyCheckpointRequest)) { in RunEmptyCheckpoint()
561 // Found a runnable thread that hasn't responded to the empty checkpoint request. in RunEmptyCheckpoint()
563 thread->Dump(LOG_STREAM(FATAL_WITHOUT_ABORT), in RunEmptyCheckpoint()
579 // Separate function to disable just the right amount of thread-safety analysis.
580 ALWAYS_INLINE void AcquireMutatorLockSharedUncontended(Thread* self) in AcquireMutatorLockSharedUncontended()
586 // A checkpoint/suspend-all hybrid to switch thread roots from
595 Thread* self = Thread::Current(); in FlipThreadRoots()
606 VLOG(threads) << "Suspending all for thread flip"; in FlipThreadRoots()
612 std::vector<Thread*> flipping_threads; // All suspended threads. Includes us. in FlipThreadRoots()
636 for (Thread* thread : list_) { in FlipThreadRoots()
639 DCHECK(thread == self || thread->IsSuspended()); in FlipThreadRoots()
640 thread->SetFlipFunction(thread_flip_visitor); in FlipThreadRoots()
643 int thread_index = thread == self ? 0 : i++; in FlipThreadRoots()
644 flipping_threads[thread_index] = thread; in FlipThreadRoots()
645 thread->NotifyOnThreadExit(&exit_flags[thread_index]); in FlipThreadRoots()
672 // will succeed, and the target thread will not be able to reenter a runnable state until one of in FlipThreadRoots()
690 Thread::EnsureFlipFunctionStarted( in FlipThreadRoots()
691 self, flipping_threads[i], Thread::StateAndFlags(0), &exit_flags[i], &finished); in FlipThreadRoots()
707 Thread::DCheckUnregisteredEverywhere(&exit_flags[0], &exit_flags[thread_count - 1]); in FlipThreadRoots()
777 if (getpriority(PRIO_PROCESS, 0 /* this thread */) > 0) { in WaitForSuspendBarrier()
778 // We're a low priority thread, and thus have a longer ANR timeout. Increase the suspend in WaitForSuspendBarrier()
783 // then compensate during the last one. This also allows somewhat longer thread monitoring in WaitForSuspendBarrier()
833 Thread* self = Thread::Current(); in SuspendAll()
838 VLOG(threads) << "Thread[null] SuspendAll for " << cause << " starting..."; in SuspendAll()
845 // All threads are known to have suspended (but a thread may still own the mutator lock) in SuspendAll()
846 // Make sure this thread grabs exclusive access to the mutator lock and its protected data. in SuspendAll()
855 // could result in a thread suspend timeout. in SuspendAll()
888 VLOG(threads) << "Thread[null] SuspendAll complete"; in SuspendAll()
893 void ThreadList::SuspendAllInternal(Thread* self, SuspendReason reason) { in SuspendAllInternal()
894 // self can be nullptr if this is an unregistered thread. in SuspendAllInternal()
926 for (const auto& thread : list_) { in SuspendAllInternal() local
927 if (thread == self) { in SuspendAllInternal()
930 VLOG(threads) << "requesting thread suspend: " << *thread; in SuspendAllInternal()
932 thread->IncrementSuspendCount(self, &pending_threads, nullptr, reason); in SuspendAllInternal()
933 if (thread->IsSuspended()) { in SuspendAllInternal()
934 // Effectively pass the barrier on behalf of the already suspended thread. in SuspendAllInternal()
935 // The thread itself cannot yet have acted on our request since we still hold the in SuspendAllInternal()
938 DCHECK_EQ(thread->tlsPtr_.active_suspendall_barrier, &pending_threads); in SuspendAllInternal()
940 thread->tlsPtr_.active_suspendall_barrier = nullptr; in SuspendAllInternal()
941 if (!thread->HasActiveSuspendBarrier()) { in SuspendAllInternal()
942 thread->AtomicClearFlag(ThreadFlag::kActiveSuspendBarrier); in SuspendAllInternal()
946 // The target thread was not yet suspended, and hence will be forced to execute in SuspendAllInternal()
967 Thread::resume_cond_->WaitHoldingLocks(self); in SuspendAllInternal()
974 Thread* culprit = nullptr; in SuspendAllInternal()
988 for (const auto& thread : list_) { in SuspendAllInternal() local
989 if (thread != self && !thread->IsSuspended()) { in SuspendAllInternal()
990 culprit = thread; in SuspendAllInternal()
991 oss << *thread << ", "; in SuspendAllInternal()
1009 getpriority(PRIO_PROCESS /* really thread */, culprit->GetTid()), in SuspendAllInternal()
1019 Thread* self = Thread::Current(); in ResumeAll()
1031 void ThreadList::ResumeAllInternal(Thread* self) { in ResumeAllInternal()
1036 VLOG(threads) << "Thread[null] ResumeAll starting"; in ResumeAllInternal()
1046 for (const auto& thread : list_) { in ResumeAllInternal() local
1047 if (thread != self) { in ResumeAllInternal()
1048 thread->DecrementSuspendCount(self); in ResumeAllInternal()
1063 VLOG(threads) << "Thread[null] ResumeAll waking others"; in ResumeAllInternal()
1065 Thread::resume_cond_->Broadcast(self); in ResumeAllInternal()
1070 VLOG(threads) << "Thread[null] ResumeAll complete"; in ResumeAllInternal()
1074 bool ThreadList::Resume(Thread* thread, SuspendReason reason) { in Resume() argument
1075 // This assumes there was an ATraceBegin when we suspended the thread. in Resume()
1078 Thread* self = Thread::Current(); in Resume()
1079 DCHECK_NE(thread, self); in Resume()
1080 VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") starting..." << reason; in Resume()
1087 if (UNLIKELY(!thread->IsSuspended())) { in Resume()
1089 << "Resume(" << reinterpret_cast<void*>(thread) << ") thread not suspended"; in Resume()
1092 if (!Contains(thread)) { in Resume()
1093 // We only expect threads within the thread-list to have been suspended otherwise we can't in Resume()
1096 << "Resume(" << reinterpret_cast<void*>(thread) << ") thread not within thread list"; in Resume()
1099 thread->DecrementSuspendCount(self, /*for_user_code=*/(reason == SuspendReason::kForUserCode)); in Resume()
1100 Thread::resume_cond_->Broadcast(self); in Resume()
1103 VLOG(threads) << "Resume(" << reinterpret_cast<void*>(thread) << ") finished waking others"; in Resume()
1107 bool ThreadList::SuspendThread(Thread* self, in SuspendThread()
1108 Thread* thread, in SuspendThread() argument
1115 pid_t tid = thread->GetTid(); in SuspendThread()
1122 thread->NotifyOnThreadExit(&tef); in SuspendThread()
1129 DCHECK(Contains(thread)); in SuspendThread()
1130 // This implementation fails if thread == self. Let the clients handle that case in SuspendThread()
1132 CHECK_NE(thread, self) << func_name << "(self)"; in SuspendThread()
1133 VLOG(threads) << func_name << " suspending: " << *thread; in SuspendThread()
1137 suspended_count = thread->suspended_count_; in SuspendThread()
1138 checkpoint_count = thread->checkpoint_count_; in SuspendThread()
1139 thread->IncrementSuspendCount(self, nullptr, &wrapped_barrier, reason); in SuspendThread()
1140 if (thread->IsSuspended()) { in SuspendThread()
1142 thread->RemoveFirstSuspend1Barrier(&wrapped_barrier); in SuspendThread()
1145 if (!thread->HasActiveSuspendBarrier()) { in SuspendThread()
1146 thread->AtomicClearFlag(ThreadFlag::kActiveSuspendBarrier); in SuspendThread()
1150 DCHECK_GT(thread->GetSuspendCount(), 0); in SuspendThread()
1153 // Else we hold the suspend count lock but another thread is trying to suspend us, in SuspendThread()
1154 // making it unsafe to try to suspend another thread in case we get a cycle. in SuspendThread()
1155 // Start the loop again, which will allow this thread to be suspended. in SuspendThread()
1171 thread->UnregisterThreadExitFlag(&tef); in SuspendThread()
1177 LOG(WARNING) << StringPrintf("Thread with tid %d exited before suspending", tid); in SuspendThread()
1190 // Caller will try again. Give up and resume the thread for now. We need to make sure in SuspendThread()
1198 thread->RemoveSuspend1Barrier(&wrapped_barrier); in SuspendThread()
1199 if (!thread->HasActiveSuspendBarrier()) { in SuspendThread()
1200 thread->AtomicClearFlag(ThreadFlag::kActiveSuspendBarrier); in SuspendThread()
1203 thread->DecrementSuspendCount(self, in SuspendThread()
1205 Thread::resume_cond_->Broadcast(self); in SuspendThread()
1209 thread->GetThreadName(name); in SuspendThread()
1213 first_barrier = thread->tlsPtr_.active_suspend1_barriers; in SuspendThread()
1215 // 'thread' should still have a suspend request pending, and hence stick around. Try to abort in SuspendThread()
1222 thread->GetStateAndFlags(std::memory_order_relaxed).GetValue(), in SuspendThread()
1223 thread->GetNativePriority(), in SuspendThread()
1224 getpriority(PRIO_PROCESS /* really thread */, thread->GetTid()), in SuspendThread()
1228 thread->suspended_count_ - suspended_count, in SuspendThread()
1229 thread->checkpoint_count_ - checkpoint_count, in SuspendThread()
1231 // Check one last time whether thread passed the suspend barrier. Empirically this seems to in SuspendThread()
1234 // thread still has a pointer to wrapped_barrier. Returning and continuing would be unsafe in SuspendThread()
1236 thread->AbortInThis(message); in SuspendThread()
1242 VLOG(threads) << func_name << " suspended: " << *thread; in SuspendThread()
1245 thread->GetThreadName(name); in SuspendThread()
1247 StringPrintf("%s suspended %s for tid=%d", func_name, name.c_str(), thread->GetTid()) in SuspendThread()
1251 CHECK(thread->IsSuspended()); in SuspendThread()
1253 thread->CheckBarrierInactive(&wrapped_barrier); in SuspendThread()
1258 Thread* ThreadList::SuspendThreadByPeer(jobject peer, SuspendReason reason) { in SuspendThreadByPeer()
1259 Thread* const self = Thread::Current(); in SuspendThreadByPeer()
1264 Thread* thread = Thread::FromManagedThread(self, thread_ptr); in SuspendThreadByPeer() local
1265 if (thread == nullptr || !Contains(thread)) { in SuspendThreadByPeer()
1266 if (thread == nullptr) { in SuspendThreadByPeer()
1269 LOG(WARNING) << "No such thread for suspend" in SuspendThreadByPeer()
1272 LOG(WARNING) << "SuspendThreadByPeer failed for unattached thread: " in SuspendThreadByPeer()
1273 << reinterpret_cast<void*>(thread); in SuspendThreadByPeer()
1279 VLOG(threads) << "SuspendThreadByPeer found thread: " << *thread; in SuspendThreadByPeer()
1281 bool success = SuspendThread(self, thread, reason, old_self_state, __func__, 0); in SuspendThreadByPeer()
1283 return success ? thread : nullptr; in SuspendThreadByPeer()
1286 Thread* ThreadList::SuspendThreadByThreadId(uint32_t thread_id, in SuspendThreadByThreadId()
1289 Thread* const self = Thread::Current(); in SuspendThreadByThreadId()
1295 Thread* thread = FindThreadByThreadId(thread_id); in SuspendThreadByThreadId() local
1296 if (thread == nullptr) { in SuspendThreadByThreadId()
1298 LOG(WARNING) << StringPrintf("No such thread id %d for suspend", thread_id); in SuspendThreadByThreadId()
1303 DCHECK(Contains(thread)); in SuspendThreadByThreadId()
1304 VLOG(threads) << "SuspendThreadByThreadId found thread: " << *thread; in SuspendThreadByThreadId()
1306 bool success = SuspendThread(self, thread, reason, old_self_state, __func__, attempt_of_4); in SuspendThreadByThreadId()
1308 return success ? thread : nullptr; in SuspendThreadByThreadId()
1311 Thread* ThreadList::FindThreadByThreadId(uint32_t thread_id) { in FindThreadByThreadId()
1312 for (const auto& thread : list_) { in FindThreadByThreadId() local
1313 if (thread->GetThreadId() == thread_id) { in FindThreadByThreadId()
1314 return thread; in FindThreadByThreadId()
1320 Thread* ThreadList::FindThreadByTid(int tid) { in FindThreadByTid()
1321 for (const auto& thread : list_) { in FindThreadByTid() local
1322 if (thread->GetTid() == tid) { in FindThreadByTid()
1323 return thread; in FindThreadByTid()
1331 Thread* self = Thread::Current(); in WaitForOtherNonDaemonThreadsToExit()
1341 // Awkward. Shutdown_cond_ is private, but the only live thread may not be registered yet. in WaitForOtherNonDaemonThreadsToExit()
1351 // threads access the thread list after it is deleted. TODO: This may not work for user daemon in WaitForOtherNonDaemonThreadsToExit()
1355 for (const auto& thread : list_) { in WaitForOtherNonDaemonThreadsToExit() local
1356 if (thread != self && !thread->IsDaemon()) { in WaitForOtherNonDaemonThreadsToExit()
1365 // Wait for another thread to exit before re-checking. in WaitForOtherNonDaemonThreadsToExit()
1372 Thread* self = Thread::Current(); in SuspendAllDaemonThreadsForShutdown()
1378 for (const auto& thread : list_) { in SuspendAllDaemonThreadsForShutdown() local
1381 CHECK(thread->IsDaemon()) << *thread; in SuspendAllDaemonThreadsForShutdown()
1382 if (thread != self) { in SuspendAllDaemonThreadsForShutdown()
1383 thread->IncrementSuspendCount(self); in SuspendAllDaemonThreadsForShutdown()
1388 thread->GetJniEnv()->SetFunctionsToRuntimeShutdownFunctions(); in SuspendAllDaemonThreadsForShutdown()
1396 // killing them and reclaiming thread stacks. We also have no mechanism for waiting until they in SuspendAllDaemonThreadsForShutdown()
1414 for (const auto& thread : list_) { in SuspendAllDaemonThreadsForShutdown() local
1415 if (thread != self && thread->GetState() == ThreadState::kRunnable) { in SuspendAllDaemonThreadsForShutdown()
1417 LOG(WARNING) << "daemon thread not yet suspended: " << *thread; in SuspendAllDaemonThreadsForShutdown()
1432 // We can get here if a daemon thread executed a fastnative native call, so that it in SuspendAllDaemonThreadsForShutdown()
1442 std::list<Thread*> list_copy; in SuspendAllDaemonThreadsForShutdown()
1449 for (const auto& thread : list_) { in SuspendAllDaemonThreadsForShutdown() local
1450 DCHECK(thread == self || !all_suspended || thread->GetState() != ThreadState::kRunnable); in SuspendAllDaemonThreadsForShutdown()
1452 thread->GetJniEnv()->SetRuntimeDeleted(); in SuspendAllDaemonThreadsForShutdown()
1469 void ThreadList::Register(Thread* self) { in Register()
1470 DCHECK_EQ(self, Thread::Current()); in Register()
1479 // Atomically add self to the thread list and make its thread_suspend_count_ reflect ongoing in Register()
1502 void ThreadList::Unregister(Thread* self, bool should_run_callbacks) { in Unregister()
1503 DCHECK_EQ(self, Thread::Current()); in Unregister()
1519 // suspend and so on, must happen at this point, and not in ~Thread. The self->Destroy is what in Unregister()
1521 // since we want the runtime to wait for the daemon threads to exit before deleting the thread in Unregister()
1527 // Remove and delete the Thread* while holding the thread_list_lock_ and in Unregister()
1528 // thread_suspend_count_lock_ so that the unregistering thread cannot be suspended. in Unregister()
1537 LOG(FATAL) << "Request to unregister unattached thread " << thread_name << "\n" << os.str(); in Unregister()
1541 Thread::StateAndFlags state_and_flags = self->GetStateAndFlags(std::memory_order_acquire); in Unregister()
1553 // We failed to remove the thread due to a suspend request or the like, loop and try again. in Unregister()
1556 // We flush the trace buffer in Thread::Destroy. We have to check again here because once the in Unregister()
1557 // Thread::Destroy finishes we wait for any active suspend requests to finish before deleting in Unregister()
1558 // the thread. If a new trace was started during the wait period we may allocate the trace buffer in Unregister()
1560 // of an exiting thread. It is not required to flush these entries but we need to release the in Unregister()
1561 // buffer. Ideally we should either not generate trace events for a thread that is exiting or use in Unregister()
1562 // a different mechanism to report the initial events on a trace start that doesn't use per-thread in Unregister()
1571 // Release the thread ID after the thread is finished and deleted to avoid cases where we can in Unregister()
1572 // temporarily have multiple threads with the same thread id. When this occurs, it causes in Unregister()
1576 // Clear the TLS data, so that the underlying native thread is recognizably detached. in Unregister()
1581 CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, nullptr), "detach self"); in Unregister()
1582 Thread::self_tls_ = nullptr; in Unregister()
1585 // Signal that a thread just detached. in Unregister()
1591 void ThreadList::ForEach(void (*callback)(Thread*, void*), void* context) { in ForEach() argument
1592 for (const auto& thread : list_) { in ForEach() local
1593 callback(thread, context); in ForEach()
1597 void ThreadList::WaitForUnregisterToComplete(Thread* self) { in WaitForUnregisterToComplete()
1600 LOG(WARNING) << "Waiting for a thread to finish unregistering"; in WaitForUnregisterToComplete()
1606 Thread* const self = Thread::Current(); in VisitRootsForSuspendedThreads()
1607 std::vector<Thread*> threads_to_visit; in VisitRootsForSuspendedThreads()
1613 for (Thread* thread : list_) { in VisitRootsForSuspendedThreads()
1614 thread->IncrementSuspendCount(self); in VisitRootsForSuspendedThreads()
1615 if (thread == self || thread->IsSuspended()) { in VisitRootsForSuspendedThreads()
1616 threads_to_visit.push_back(thread); in VisitRootsForSuspendedThreads()
1618 thread->DecrementSuspendCount(self); in VisitRootsForSuspendedThreads()
1625 for (Thread* thread : threads_to_visit) { in VisitRootsForSuspendedThreads()
1626 thread->VisitRoots(visitor, kVisitRootFlagAllRoots); in VisitRootsForSuspendedThreads()
1632 for (Thread* thread : threads_to_visit) { in VisitRootsForSuspendedThreads()
1633 thread->DecrementSuspendCount(self); in VisitRootsForSuspendedThreads()
1635 Thread::resume_cond_->Broadcast(self); in VisitRootsForSuspendedThreads()
1640 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); in VisitRoots()
1641 for (const auto& thread : list_) { in VisitRoots() local
1642 thread->VisitRoots(visitor, flags); in VisitRoots()
1647 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); in VisitReflectiveTargets()
1648 for (const auto& thread : list_) { in VisitReflectiveTargets() local
1649 thread->VisitReflectiveTargets(visitor); in VisitReflectiveTargets()
1654 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_); in SweepInterpreterCaches()
1655 for (const auto& thread : list_) { in SweepInterpreterCaches() local
1656 thread->SweepInterpreterCache(visitor); in SweepInterpreterCaches()
1660 uint32_t ThreadList::AllocThreadId(Thread* self) { in AllocThreadId()
1668 LOG(FATAL) << "Out of internal thread ids"; in AllocThreadId()
1672 void ThreadList::ReleaseThreadId(Thread* self, uint32_t id) { in ReleaseThreadId()