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 "barrier.h"
21 #include "base/histogram.h"
22 #include "base/mutex.h"
23 #include "base/time_utils.h"
24 #include "base/value_object.h"
25 #include "gc_root.h"
26 #include "jni.h"
27 #include "object_callbacks.h"
28 
29 #include <bitset>
30 #include <list>
31 #include <vector>
32 
33 namespace art {
34 namespace gc {
35   namespace collector {
36     class GarbageCollector;
37   }  // namespac collector
38 }  // namespace gc
39 class Closure;
40 class Thread;
41 class TimingLogger;
42 
43 class ThreadList {
44  public:
45   static constexpr uint32_t kMaxThreadId = 0xFFFF;
46   static constexpr uint32_t kInvalidThreadId = 0;
47   static constexpr uint32_t kMainThreadId = 1;
48   static constexpr uint64_t kDefaultThreadSuspendTimeout = MsToNs(kIsDebugBuild ? 50000 : 10000);
49 
50   explicit ThreadList(uint64_t thread_suspend_timeout_ns);
51   ~ThreadList();
52 
53   void DumpForSigQuit(std::ostream& os)
54       REQUIRES(!Locks::thread_list_lock_, !Locks::mutator_lock_);
55   // For thread suspend timeout dumps.
56   void Dump(std::ostream& os, bool dump_native_stack = true)
57       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
58   pid_t GetLockOwner();  // For SignalCatcher.
59 
60   // Thread suspension support.
61   void ResumeAll()
62       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
63       UNLOCK_FUNCTION(Locks::mutator_lock_);
64   void Resume(Thread* thread, bool for_debugger = false)
65       REQUIRES(!Locks::thread_suspend_count_lock_);
66 
67   // Suspends all threads and gets exclusive access to the mutator_lock_.
68   // If long_suspend is true, then other threads who try to suspend will never timeout.
69   // long_suspend is currenly used for hprof since large heaps take a long time.
70   void SuspendAll(const char* cause, bool long_suspend = false)
71       EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
72       REQUIRES(!Locks::thread_list_lock_,
73                !Locks::thread_suspend_count_lock_,
74                !Locks::mutator_lock_);
75 
76   // Suspend a thread using a peer, typically used by the debugger. Returns the thread on success,
77   // else null. The peer is used to identify the thread to avoid races with the thread terminating.
78   // If the thread should be suspended then value of request_suspension should be true otherwise
79   // the routine will wait for a previous suspend request. If the suspension times out then *timeout
80   // is set to true.
81   Thread* SuspendThreadByPeer(jobject peer, bool request_suspension, bool debug_suspension,
82                               bool* timed_out)
83       REQUIRES(!Locks::mutator_lock_,
84                !Locks::thread_list_lock_,
85                !Locks::thread_suspend_count_lock_);
86 
87   // Suspend a thread using its thread id, typically used by lock/monitor inflation. Returns the
88   // thread on success else null. The thread id is used to identify the thread to avoid races with
89   // the thread terminating. Note that as thread ids are recycled this may not suspend the expected
90   // thread, that may be terminating. If the suspension times out then *timeout is set to true.
91   Thread* SuspendThreadByThreadId(uint32_t thread_id, bool debug_suspension, bool* timed_out)
92       REQUIRES(!Locks::mutator_lock_,
93                !Locks::thread_list_lock_,
94                !Locks::thread_suspend_count_lock_);
95 
96   // Find an existing thread (or self) by its thread id (not tid).
97   Thread* FindThreadByThreadId(uint32_t thread_id) REQUIRES(Locks::thread_list_lock_);
98 
99   // Run a checkpoint on threads, running threads are not suspended but run the checkpoint inside
100   // of the suspend check. Returns how many checkpoints that are expected to run, including for
101   // already suspended threads for b/24191051. Run the callback, if non-null, inside the
102   // thread_list_lock critical section after determining the runnable/suspended states of the
103   // threads.
104   size_t RunCheckpoint(Closure* checkpoint_function, Closure* callback = nullptr)
105       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
106 
107   // Run an empty checkpoint on threads. Wait until threads pass the next suspend point or are
108   // suspended. This is used to ensure that the threads finish or aren't in the middle of an
109   // in-flight mutator heap access (eg. a read barrier.) Runnable threads will respond by
110   // decrementing the empty checkpoint barrier count. This works even when the weak ref access is
111   // disabled. Only one concurrent use is currently supported.
112   void RunEmptyCheckpoint()
113       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
114 
115   size_t RunCheckpointOnRunnableThreads(Closure* checkpoint_function)
116       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
117 
118   // Flip thread roots from from-space refs to to-space refs. Used by
119   // the concurrent copying collector.
120   size_t FlipThreadRoots(Closure* thread_flip_visitor,
121                          Closure* flip_callback,
122                          gc::collector::GarbageCollector* collector)
123       REQUIRES(!Locks::mutator_lock_,
124                !Locks::thread_list_lock_,
125                !Locks::thread_suspend_count_lock_);
126 
127   // Suspends all threads
128   void SuspendAllForDebugger()
129       REQUIRES(!Locks::mutator_lock_,
130                !Locks::thread_list_lock_,
131                !Locks::thread_suspend_count_lock_);
132 
133   void SuspendSelfForDebugger()
134       REQUIRES(!Locks::thread_suspend_count_lock_);
135 
136   // Resume all threads
137   void ResumeAllForDebugger()
138       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
139 
140   void UndoDebuggerSuspensions()
141       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
142 
143   // Iterates over all the threads.
144   void ForEach(void (*callback)(Thread*, void*), void* context)
145       REQUIRES(Locks::thread_list_lock_);
146 
147   // Add/remove current thread from list.
148   void Register(Thread* self)
149       REQUIRES(Locks::runtime_shutdown_lock_)
150       REQUIRES(!Locks::mutator_lock_,
151                !Locks::thread_list_lock_,
152                !Locks::thread_suspend_count_lock_);
153   void Unregister(Thread* self)
154       REQUIRES(!Locks::mutator_lock_,
155                !Locks::thread_list_lock_,
156                !Locks::thread_suspend_count_lock_);
157 
158   void VisitRoots(RootVisitor* visitor, VisitRootFlags flags) const
159       REQUIRES_SHARED(Locks::mutator_lock_);
160 
161   void VisitRootsForSuspendedThreads(RootVisitor* visitor)
162       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
163       REQUIRES_SHARED(Locks::mutator_lock_);
164 
165   // Return a copy of the thread list.
GetList()166   std::list<Thread*> GetList() REQUIRES(Locks::thread_list_lock_) {
167     return list_;
168   }
169 
170   void DumpNativeStacks(std::ostream& os)
171       REQUIRES(!Locks::thread_list_lock_);
172 
EmptyCheckpointBarrier()173   Barrier* EmptyCheckpointBarrier() {
174     return empty_checkpoint_barrier_.get();
175   }
176 
177  private:
178   uint32_t AllocThreadId(Thread* self);
179   void ReleaseThreadId(Thread* self, uint32_t id) REQUIRES(!Locks::allocated_thread_ids_lock_);
180 
181   bool Contains(Thread* thread) REQUIRES(Locks::thread_list_lock_);
182   bool Contains(pid_t tid) REQUIRES(Locks::thread_list_lock_);
183   size_t RunCheckpoint(Closure* checkpoint_function, bool includeSuspended)
184       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
185 
186   void DumpUnattachedThreads(std::ostream& os, bool dump_native_stack)
187       REQUIRES(!Locks::thread_list_lock_);
188 
189   void SuspendAllDaemonThreadsForShutdown()
190       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
191   void WaitForOtherNonDaemonThreadsToExit()
192       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
193 
194   void SuspendAllInternal(Thread* self,
195                           Thread* ignore1,
196                           Thread* ignore2 = nullptr,
197                           bool debug_suspend = false)
198       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
199 
200   void AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2 = nullptr)
201       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_);
202 
203   std::bitset<kMaxThreadId> allocated_ids_ GUARDED_BY(Locks::allocated_thread_ids_lock_);
204 
205   // The actual list of all threads.
206   std::list<Thread*> list_ GUARDED_BY(Locks::thread_list_lock_);
207 
208   // Ongoing suspend all requests, used to ensure threads added to list_ respect SuspendAll.
209   int suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
210   int debug_suspend_all_count_ GUARDED_BY(Locks::thread_suspend_count_lock_);
211 
212   // Number of threads unregistering, ~ThreadList blocks until this hits 0.
213   int unregistering_count_ GUARDED_BY(Locks::thread_list_lock_);
214 
215   // Thread suspend time histogram. Only modified when all the threads are suspended, so guarding
216   // by mutator lock ensures no thread can read when another thread is modifying it.
217   Histogram<uint64_t> suspend_all_historam_ GUARDED_BY(Locks::mutator_lock_);
218 
219   // Whether or not the current thread suspension is long.
220   bool long_suspend_;
221 
222   // Thread suspension timeout in nanoseconds.
223   const uint64_t thread_suspend_timeout_ns_;
224 
225   std::unique_ptr<Barrier> empty_checkpoint_barrier_;
226 
227   friend class Thread;
228 
229   DISALLOW_COPY_AND_ASSIGN(ThreadList);
230 };
231 
232 // Helper for suspending all threads and
233 class ScopedSuspendAll : public ValueObject {
234  public:
235   explicit ScopedSuspendAll(const char* cause, bool long_suspend = false)
236      EXCLUSIVE_LOCK_FUNCTION(Locks::mutator_lock_)
237      REQUIRES(!Locks::thread_list_lock_,
238               !Locks::thread_suspend_count_lock_,
239               !Locks::mutator_lock_);
240   // No REQUIRES(mutator_lock_) since the unlock function already asserts this.
241   ~ScopedSuspendAll()
242       REQUIRES(!Locks::thread_list_lock_, !Locks::thread_suspend_count_lock_)
243       UNLOCK_FUNCTION(Locks::mutator_lock_);
244 };
245 
246 }  // namespace art
247 
248 #endif  // ART_RUNTIME_THREAD_LIST_H_
249