thread_list.h revision 87f8b4cf0c1d6aab3eb5d1e99cc4e7cf175ef772
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#ifndef ART_RUNTIME_THREAD_LIST_H_ 18#define ART_RUNTIME_THREAD_LIST_H_ 19 20#include "base/mutex.h" 21#include "jni.h" 22#include "object_callbacks.h" 23 24#include <bitset> 25#include <list> 26 27namespace art { 28class Closure; 29class Thread; 30class TimingLogger; 31 32class ThreadList { 33 public: 34 static const uint32_t kMaxThreadId = 0xFFFF; 35 static const uint32_t kInvalidThreadId = 0; 36 static const uint32_t kMainThreadId = 1; 37 38 explicit ThreadList(); 39 ~ThreadList(); 40 41 void DumpForSigQuit(std::ostream& os) 42 LOCKS_EXCLUDED(Locks::thread_list_lock_) 43 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 44 void DumpLocked(std::ostream& os) // For thread suspend timeout dumps. 45 EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) 46 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 47 pid_t GetLockOwner(); // For SignalCatcher. 48 49 // Thread suspension support. 50 void ResumeAll() 51 UNLOCK_FUNCTION(Locks::mutator_lock_) 52 LOCKS_EXCLUDED(Locks::thread_list_lock_, 53 Locks::thread_suspend_count_lock_); 54 void Resume(Thread* thread, bool for_debugger = false) 55 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 56 57 // Suspends all threads and gets exclusive access to the mutator_lock_. 58 void SuspendAll() 59 EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_) 60 LOCKS_EXCLUDED(Locks::thread_list_lock_, 61 Locks::thread_suspend_count_lock_); 62 63 64 // Suspend a thread using a peer, typically used by the debugger. Returns the thread on success, 65 // else NULL. The peer is used to identify the thread to avoid races with the thread terminating. 66 // If the thread should be suspended then value of request_suspension should be true otherwise 67 // the routine will wait for a previous suspend request. If the suspension times out then *timeout 68 // is set to true. 69 static Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension, 70 bool* timed_out) 71 LOCKS_EXCLUDED(Locks::mutator_lock_, 72 Locks::thread_list_lock_, 73 Locks::thread_suspend_count_lock_); 74 75 // Suspend a thread using its thread id, typically used by lock/monitor inflation. Returns the 76 // thread on success else NULL. The thread id is used to identify the thread to avoid races with 77 // the thread terminating. Note that as thread ids are recycled this may not suspend the expected 78 // thread, that may be terminating. If the suspension times out then *timeout is set to true. 79 Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out) 80 LOCKS_EXCLUDED(Locks::mutator_lock_, 81 Locks::thread_list_lock_, 82 Locks::thread_suspend_count_lock_); 83 84 // Find an already suspended thread (or self) by its id. 85 Thread* FindThreadByThreadId(uint32_t thin_lock_id); 86 87 // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside 88 // of the suspend check. Returns how many checkpoints we should expect to run. 89 size_t RunCheckpoint(Closure* checkpoint_function) 90 LOCKS_EXCLUDED(Locks::thread_list_lock_, 91 Locks::thread_suspend_count_lock_); 92 93 size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function) 94 LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::thread_suspend_count_lock_); 95 96 // Suspends all threads 97 void SuspendAllForDebugger() 98 LOCKS_EXCLUDED(Locks::mutator_lock_, 99 Locks::thread_list_lock_, 100 Locks::thread_suspend_count_lock_); 101 102 void SuspendSelfForDebugger() 103 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 104 105 void UndoDebuggerSuspensions() 106 LOCKS_EXCLUDED(Locks::thread_list_lock_, 107 Locks::thread_suspend_count_lock_); 108 109 // Iterates over all the threads. 110 void ForEach(void (*callback)(Thread*, void*), void* context) 111 EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 112 113 // Add/remove current thread from list. 114 void Register(Thread* self) 115 EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) 116 LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 117 void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 118 119 void VisitRoots(RootCallback* callback, void* arg) const 120 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 121 122 void VerifyRoots(VerifyRootCallback* callback, void* arg) const 123 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 124 125 // Return a copy of the thread list. 126 std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) { 127 return list_; 128 } 129 130 void DumpNativeStacks(std::ostream& os) 131 LOCKS_EXCLUDED(Locks::thread_list_lock_); 132 133 private: 134 uint32_t AllocThreadId(Thread* self); 135 void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(allocated_ids_lock_); 136 137 bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 138 bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 139 140 void DumpUnattachedThreads(std::ostream& os) 141 LOCKS_EXCLUDED(Locks::thread_list_lock_); 142 143 void SuspendAllDaemonThreads() 144 LOCKS_EXCLUDED(Locks::thread_list_lock_, 145 Locks::thread_suspend_count_lock_); 146 void WaitForOtherNonDaemonThreadsToExit() 147 LOCKS_EXCLUDED(Locks::thread_list_lock_, 148 Locks::thread_suspend_count_lock_); 149 150 void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = NULL) 151 LOCKS_EXCLUDED(Locks::thread_list_lock_, 152 Locks::thread_suspend_count_lock_); 153 154 mutable Mutex allocated_ids_lock_ DEFAULT_MUTEX_ACQUIRED_AFTER; 155 std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(allocated_ids_lock_); 156 157 // The actual list of all threads. 158 std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_); 159 160 // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll. 161 int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 162 int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 163 164 // Signaled when threads terminate. Used to determine when all non-daemons have terminated. 165 ConditionVariable thread_exit_cond_ GUARDED_BY(Locks::thread_list_lock_); 166 167 friend class Thread; 168 169 DISALLOW_COPY_AND_ASSIGN(ThreadList); 170}; 171 172} // namespace art 173 174#endif // ART_RUNTIME_THREAD_LIST_H_ 175