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/histogram.h" 21 #include "base/mutex.h" 22 #include "gc_root.h" 23 #include "jni.h" 24 #include "object_callbacks.h" 25 26 #include <bitset> 27 #include <list> 28 29 namespace art { 30 namespace gc { 31 namespace collector { 32 class GarbageCollector; 33 } // namespac collector 34 } // namespace gc 35 class Closure; 36 class Thread; 37 class TimingLogger; 38 39 class ThreadList { 40 public: 41 static const uint32_t kMaxThreadId = 0xFFFF; 42 static const uint32_t kInvalidThreadId = 0; 43 static const uint32_t kMainThreadId = 1; 44 45 explicit ThreadList(); 46 ~ThreadList(); 47 48 void DumpForSigQuit(std::ostream& os) 49 LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::mutator_lock_); 50 // For thread suspend timeout dumps. 51 void Dump(std::ostream& os) 52 LOCKS_EXCLUDED(Locks::thread_list_lock_, Locks::thread_suspend_count_lock_); 53 pid_t GetLockOwner(); // For SignalCatcher. 54 55 // Thread suspension support. 56 void ResumeAll() 57 UNLOCK_FUNCTION(Locks::mutator_lock_) 58 LOCKS_EXCLUDED(Locks::thread_list_lock_, 59 Locks::thread_suspend_count_lock_); 60 void Resume(Thread* thread, bool for_debugger = false) 61 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 62 63 // Suspends all threads and gets exclusive access to the mutator_lock_. 64 // If long suspend is true, then other people who try to suspend will never timeout. Long suspend 65 // is currenly used for hprof since large heaps take a long time. 66 void SuspendAll(const char* cause, bool long_suspend = false) 67 EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_) 68 LOCKS_EXCLUDED(Locks::thread_list_lock_, 69 Locks::thread_suspend_count_lock_); 70 71 72 // Suspend a thread using a peer, typically used by the debugger. Returns the thread on success, 73 // else null. The peer is used to identify the thread to avoid races with the thread terminating. 74 // If the thread should be suspended then value of request_suspension should be true otherwise 75 // the routine will wait for a previous suspend request. If the suspension times out then *timeout 76 // is set to true. 77 Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension, 78 bool* timed_out) 79 LOCKS_EXCLUDED(Locks::mutator_lock_, 80 Locks::thread_list_lock_, 81 Locks::thread_suspend_count_lock_); 82 83 // Suspend a thread using its thread id, typically used by lock/monitor inflation. Returns the 84 // thread on success else null. The thread id is used to identify the thread to avoid races with 85 // the thread terminating. Note that as thread ids are recycled this may not suspend the expected 86 // thread, that may be terminating. If the suspension times out then *timeout is set to true. 87 Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out) 88 LOCKS_EXCLUDED(Locks::mutator_lock_, 89 Locks::thread_list_lock_, 90 Locks::thread_suspend_count_lock_); 91 92 // Find an already suspended thread (or self) by its id. 93 Thread* FindThreadByThreadId(uint32_t thin_lock_id); 94 95 // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside 96 // of the suspend check. Returns how many checkpoints we should expect to run. 97 size_t RunCheckpoint(Closure* checkpoint_function) 98 LOCKS_EXCLUDED(Locks::thread_list_lock_, 99 Locks::thread_suspend_count_lock_); 100 101 size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function) 102 LOCKS_EXCLUDED(Locks::thread_list_lock_, 103 Locks::thread_suspend_count_lock_); 104 105 // Flip thread roots from from-space refs to to-space refs. Used by 106 // the concurrent copying collector. 107 size_t FlipThreadRoots(Closure* thread_flip_visitor, Closure* flip_callback, 108 gc::collector::GarbageCollector* collector) 109 LOCKS_EXCLUDED(Locks::mutator_lock_, 110 Locks::thread_list_lock_, 111 Locks::thread_suspend_count_lock_); 112 113 // Suspends all threads 114 void SuspendAllForDebugger() 115 LOCKS_EXCLUDED(Locks::mutator_lock_, 116 Locks::thread_list_lock_, 117 Locks::thread_suspend_count_lock_); 118 119 void SuspendSelfForDebugger() 120 LOCKS_EXCLUDED(Locks::thread_suspend_count_lock_); 121 122 // Resume all threads 123 void ResumeAllForDebugger() 124 LOCKS_EXCLUDED(Locks::thread_list_lock_, 125 Locks::thread_suspend_count_lock_); 126 127 void UndoDebuggerSuspensions() 128 LOCKS_EXCLUDED(Locks::thread_list_lock_, 129 Locks::thread_suspend_count_lock_); 130 131 // Iterates over all the threads. 132 void ForEach(void (*callback)(Thread*, void*), void* context) 133 EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 134 135 // Add/remove current thread from list. 136 void Register(Thread* self) 137 EXCLUSIVE_LOCKS_REQUIRED(Locks::runtime_shutdown_lock_) 138 LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 139 void Unregister(Thread* self) LOCKS_EXCLUDED(Locks::mutator_lock_, Locks::thread_list_lock_); 140 141 void VisitRoots(RootVisitor* visitor) const 142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 143 144 // Return a copy of the thread list. GetList()145 std::list<Thread*> GetList() EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_) { 146 return list_; 147 } 148 149 void DumpNativeStacks(std::ostream& os) 150 LOCKS_EXCLUDED(Locks::thread_list_lock_); 151 152 private: 153 uint32_t AllocThreadId(Thread* self); 154 void ReleaseThreadId(Thread* self, uint32_t id) LOCKS_EXCLUDED(Locks::allocated_thread_ids_lock_); 155 156 bool Contains(Thread* thread) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 157 bool Contains(pid_t tid) EXCLUSIVE_LOCKS_REQUIRED(Locks::thread_list_lock_); 158 159 void DumpUnattachedThreads(std::ostream& os) 160 LOCKS_EXCLUDED(Locks::thread_list_lock_); 161 162 void SuspendAllDaemonThreads() 163 LOCKS_EXCLUDED(Locks::thread_list_lock_, 164 Locks::thread_suspend_count_lock_); 165 void WaitForOtherNonDaemonThreadsToExit() 166 LOCKS_EXCLUDED(Locks::thread_list_lock_, 167 Locks::thread_suspend_count_lock_); 168 169 void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr) 170 LOCKS_EXCLUDED(Locks::thread_list_lock_, 171 Locks::thread_suspend_count_lock_); 172 173 std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(Locks::allocated_thread_ids_lock_); 174 175 // The actual list of all threads. 176 std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_); 177 178 // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll. 179 int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 180 int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_); 181 182 // Number of threads unregistering, ~ThreadList blocks until this hits 0. 183 int unregistering_count_ GUARDED_BY(Locks::thread_list_lock_); 184 185 // Thread suspend time histogram. Only modified when all the threads are suspended, so guarding 186 // by mutator lock ensures no thread can read when another thread is modifying it. 187 Histogram<uint64_t> suspend_all_historam_ GUARDED_BY(Locks::mutator_lock_); 188 189 // Whether or not the current thread suspension is long. 190 bool long_suspend_; 191 192 friend class Thread; 193 194 DISALLOW_COPY_AND_ASSIGN(ThreadList); 195 }; 196 197 } // namespace art 198 199 #endif // ART_RUNTIME_THREAD_LIST_H_ 200