18daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes/* 28daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project 38daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 48daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 58daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * you may not use this file except in compliance with the License. 68daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * You may obtain a copy of the License at 78daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 88daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 98daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * 108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Unless required by applicable law or agreed to in writing, software 118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * See the License for the specific language governing permissions and 148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * limitations under the License. 158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */ 168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_RUNTIME_THREAD_LIST_H_ 18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_RUNTIME_THREAD_LIST_H_ 198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 2076b6167407c2b6f5d40ad895b2793a6b037f54b2Elliott Hughes#include "base/mutex.h" 212dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "root_visitor.h" 228daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 232dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <bitset> 242dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include <list> 258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 262dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersnamespace art { 272dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Closure; 282dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersclass Thread; 297664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartierclass TimingLogger; 307664f5cd118b355a5fe0c7536cb48ac991ed2b62Mathieu Chartier 318daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesclass ThreadList { 328daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes public: 338daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes static const uint32_t kMaxThreadId = 0xFFFF; 348daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes static const uint32_t kInvalidId = 0; 358daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes static const uint32_t kMainId = 1; 368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 374dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes explicit ThreadList(); 388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes ~ThreadList(); 398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 4000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DumpForSigQuit(std::ostream& os) 41b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_) 42b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 4300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DumpLocked(std::ostream& os) // For thread suspend timeout dumps. 44b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) 45b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 467934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom pid_t GetLockOwner(); // For SignalCatcher. 478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 488d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes // Thread suspension support. 4900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ResumeAll() 50b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers UNLOCK_FUNCTION(Locks::mutator_lock_) 51b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 52b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 5300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void Resume(Thread* thread, bool for_debugger = false) 54b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 5500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 5600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Suspends all threads and gets exclusive access to the mutator_lock_. 5700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SuspendAll() 58b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_) 59b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 60858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier Locks::thread_suspend_count_lock_); 61858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier 62858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside 63858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier // of the suspend check. Returns how many checkpoints we should expect to run. 640e4627e593bc39f8e3d89c31f8977d55054c07ccMathieu Chartier size_t RunCheckpoint(Closure* checkpoint_function); 65858f1c5fd5e528d0b16040ced74d4636046a42d8Mathieu Chartier LOCKS_EXCLUDED(Locks::thread_list_lock_, 66b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 6700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 6800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Suspends all threads 6900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SuspendAllForDebugger() 70b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_, 71b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_list_lock_, 72b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 7300f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 7400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SuspendSelfForDebugger() 75b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 7600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers 7700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void UndoDebuggerSuspensions() 78b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 79b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 81f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes // Iterates over all the threads. 8200f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void ForEach(void (*callback)(Thread*, void*), void* context) 83b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 8447fce01c0f27dba716fa6b97242562fbc5c26eeaElliott Hughes 8500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Add/remove current thread from list. 8600f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void Register(Thread* self) 87120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) 88120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 89120f1c74a9768e958377b6c97897511b27ae58c8Ian Rogers void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers void VisitRoots(RootVisitor* visitor, void* arg) const 92b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 942dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers void VerifyRoots(VerifyRootVisitor* visitor, void* arg) const 956f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 966f1c94968ada57da433debf8e2d1b38a80ceb510Mathieu Chartier 9700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Return a copy of the thread list. 98b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) { 9900f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers return list_; 10000f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers } 10193e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 102f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes Thread* FindThreadByThinLockId(uint32_t thin_lock_id); 103f327e07b37e349b1ec5eaad6dc294a9b7a081d20Elliott Hughes 1048daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes private: 105cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers uint32_t AllocThreadId(Thread* self); 106cfaa455374aae0a08c8cb28b5bb306b17866d652Ian Rogers void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(allocated_ids_lock_); 107e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes 108b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 109b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 110abbe07d095547ded03c2e9d0d53943d43471278dElliott Hughes 11100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void DumpUnattachedThreads(std::ostream& os) 112b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_); 113e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes 11400f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void SuspendAllDaemonThreads() 115b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 116b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 11700f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers void WaitForOtherNonDaemonThreadsToExit() 118b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 119b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 1208daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 12150b35e2fd1a68cd1240e4a9d9f363e11764957d1Ian Rogers void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL) 122b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers LOCKS_EXCLUDED(Locks::thread_list_lock_, 123b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers Locks::thread_suspend_count_lock_); 124234ab15b00f8120282d1833e5d7480eca2e35a29Elliott Hughes 12500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers mutable Mutex allocated_ids_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 126f8349361a16a4e2796efe9f3586b994e8d4834e4Elliott Hughes std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(allocated_ids_lock_); 127e52e49b32f5cf862a414da63e5dbd2eb04ad758eElliott Hughes 12800f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // The actual list of all threads. 129b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_); 1308daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 13100f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll. 132b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 133b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 1348d768a954b101a9532f980253ac46be2c53aba11Elliott Hughes 13500f7d0eaa6bd93d33bf0c1429bf4ba0b3f28abacIan Rogers // Signaled when threads terminate. Used to determine when all non-daemons have terminated. 136b726dcb581bf72da46527378ccb6889020f0e6e9Ian Rogers ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_); 13793e74e8d879270071c3aa163f8495ada8d21f42fElliott Hughes 1388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes friend class Thread; 1398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 1408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes DISALLOW_COPY_AND_ASSIGN(ThreadList); 1418daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}; 1428daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 1438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes} // namespace art 1448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes 145fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif // ART_RUNTIME_THREAD_LIST_H_ 146