diff options
Diffstat (limited to 'runtime/thread_list.h')
-rw-r--r-- | runtime/thread_list.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/runtime/thread_list.h b/runtime/thread_list.h new file mode 100644 index 0000000000..0470cfc3b9 --- /dev/null +++ b/runtime/thread_list.h @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_SRC_THREAD_LIST_H_ +#define ART_SRC_THREAD_LIST_H_ + +#include "base/mutex.h" +#include "root_visitor.h" + +#include <bitset> +#include <list> + +namespace art { +class Closure; +class Thread; +class TimingLogger; + +class ThreadList { + public: + static const uint32_t kMaxThreadId = 0xFFFF; + static const uint32_t kInvalidId = 0; + static const uint32_t kMainId = 1; + + explicit ThreadList(); + ~ThreadList(); + + void DumpForSigQuit(std::ostream& os) + LOCKS_EXCLUDED(Locks::thread_list_lock_) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void DumpLocked(std::ostream& os) // For thread suspend timeout dumps. + EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + pid_t GetLockOwner(); // For SignalCatcher. + + // Thread suspension support. + void ResumeAll() + UNLOCK_FUNCTION(Locks::mutator_lock_) + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + void Resume(Thread* thread, bool for_debugger = false) + LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); + + // Suspends all threads and gets exclusive access to the mutator_lock_. + void SuspendAll() + EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_) + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside + // of the suspend check. Returns how many checkpoints we should expect to run. + size_t RunCheckpoint(Closure* checkpoint_function); + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + // Suspends all threads + void SuspendAllForDebugger() + LOCKS_EXCLUDED(Locks::mutator_lock_, + Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + void SuspendSelfForDebugger() + LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); + + void UndoDebuggerSuspensions() + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + // Iterates over all the threads. + void ForEach(void (*callback)(Thread*, void*), void* context) + EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); + + // Add/remove current thread from list. + void Register(Thread* self) + EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) + LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); + void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); + + void VisitRoots(RootVisitor* visitor, void* arg) const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + // Return a copy of the thread list. + std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) { + return list_; + } + + Thread* FindThreadByThinLockId(uint32_t thin_lock_id); + + private: + typedef std::list<Thread*>::const_iterator It; // TODO: C++0x auto + + uint32_t AllocThreadId(Thread* self); + void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(allocated_ids_lock_); + + bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); + bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); + + void DumpUnattachedThreads(std::ostream& os) + LOCKS_EXCLUDED(Locks::thread_list_lock_); + + void SuspendAllDaemonThreads() + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + void WaitForOtherNonDaemonThreadsToExit() + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL) + LOCKS_EXCLUDED(Locks::thread_list_lock_, + Locks::thread_suspend_count_lock_); + + mutable Mutex allocated_ids_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; + std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(allocated_ids_lock_); + + // The actual list of all threads. + std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_); + + // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll. + int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); + int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); + + // Signaled when threads terminate. Used to determine when all non-daemons have terminated. + ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_); + + friend class Thread; + + DISALLOW_COPY_AND_ASSIGN(ThreadList); +}; + +} // namespace art + +#endif // ART_SRC_THREAD_LIST_H_ |