blob: 9c28c87b845edf488787aac46a9f142dc193671a [file] [log] [blame]
Elliott Hughes8daa0922011-09-11 13:46:25 -07001/*
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#include "thread_list.h"
18
Elliott Hughesabbe07d2012-06-05 17:42:23 -070019#include <dirent.h>
20#include <sys/types.h>
Elliott Hughes038a8062011-09-18 14:12:41 -070021#include <unistd.h>
22
Elliott Hughes76b61672012-12-12 17:47:30 -080023#include "base/mutex.h"
Sameer Abu Asala8439542013-02-14 16:06:42 -080024#include "base/timing_logger.h"
Elliott Hughes475fc232011-10-25 15:00:35 -070025#include "debugger.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080026#include "thread.h"
Elliott Hughesabbe07d2012-06-05 17:42:23 -070027#include "utils.h"
Elliott Hughes475fc232011-10-25 15:00:35 -070028
Elliott Hughes8daa0922011-09-11 13:46:25 -070029namespace art {
30
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -080031ThreadList::ThreadList()
Elliott Hughese52e49b2012-04-02 16:05:44 -070032 : allocated_ids_lock_("allocated thread ids lock"),
Ian Rogers00f7d0e2012-07-19 15:28:27 -070033 suspend_all_count_(0), debug_suspend_all_count_(0),
Ian Rogersc604d732012-10-14 16:09:54 -070034 thread_exit_cond_("thread exit condition variable", *Locks::thread_list_lock_) {
Elliott Hughes8daa0922011-09-11 13:46:25 -070035}
36
37ThreadList::~ThreadList() {
Elliott Hughese52e49b2012-04-02 16:05:44 -070038 // Detach the current thread if necessary. If we failed to start, there might not be any threads.
Elliott Hughes6a144332012-04-03 13:07:11 -070039 // We need to detach the current thread here in case there's another thread waiting to join with
40 // us.
Elliott Hughes8daa0922011-09-11 13:46:25 -070041 if (Contains(Thread::Current())) {
42 Runtime::Current()->DetachCurrentThread();
43 }
Elliott Hughes6a144332012-04-03 13:07:11 -070044
45 WaitForOtherNonDaemonThreadsToExit();
Ian Rogers00f7d0e2012-07-19 15:28:27 -070046 // TODO: there's an unaddressed race here where a thread may attach during shutdown, see
47 // Thread::Init.
Elliott Hughes6a144332012-04-03 13:07:11 -070048 SuspendAllDaemonThreads();
Elliott Hughes8daa0922011-09-11 13:46:25 -070049}
50
51bool ThreadList::Contains(Thread* thread) {
52 return find(list_.begin(), list_.end(), thread) != list_.end();
53}
54
Elliott Hughesabbe07d2012-06-05 17:42:23 -070055bool ThreadList::Contains(pid_t tid) {
56 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
57 if ((*it)->tid_ == tid) {
58 return true;
59 }
60 }
61 return false;
62}
63
Brian Carlstrom24a3c2e2011-10-17 18:07:52 -070064pid_t ThreadList::GetLockOwner() {
Ian Rogersb726dcb2012-09-05 08:57:23 -070065 return Locks::thread_list_lock_->GetExclusiveOwnerTid();
Elliott Hughesaccd83d2011-10-17 14:25:58 -070066}
67
Elliott Hughesc967f782012-04-16 10:23:15 -070068void ThreadList::DumpForSigQuit(std::ostream& os) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -070069 {
Ian Rogers50b35e22012-10-04 10:09:15 -070070 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -070071 DumpLocked(os);
72 }
Elliott Hughesabbe07d2012-06-05 17:42:23 -070073 DumpUnattachedThreads(os);
74}
75
Ian Rogerscfaa4552012-11-26 21:00:08 -080076static void DumpUnattachedThread(std::ostream& os, pid_t tid) NO_THREAD_SAFETY_ANALYSIS {
77 // TODO: No thread safety analysis as DumpState with a NULL thread won't access fields, should
78 // refactor DumpState to avoid skipping analysis.
Elliott Hughesabbe07d2012-06-05 17:42:23 -070079 Thread::DumpState(os, NULL, tid);
80 DumpKernelStack(os, tid, " kernel: ", false);
Brian Carlstromed8b7232012-06-27 17:54:47 -070081 // TODO: Reenable this when the native code in system_server can handle it.
82 // Currently "adb shell kill -3 `pid system_server`" will cause it to exit.
83 if (false) {
84 DumpNativeStack(os, tid, " native: ", false);
85 }
Elliott Hughesabbe07d2012-06-05 17:42:23 -070086 os << "\n";
87}
88
89void ThreadList::DumpUnattachedThreads(std::ostream& os) {
90 DIR* d = opendir("/proc/self/task");
91 if (!d) {
92 return;
93 }
94
Ian Rogers50b35e22012-10-04 10:09:15 -070095 Thread* self = Thread::Current();
Elliott Hughes4696b5b2012-10-30 10:35:10 -070096 dirent* e;
97 while ((e = readdir(d)) != NULL) {
Elliott Hughesabbe07d2012-06-05 17:42:23 -070098 char* end;
Elliott Hughes4696b5b2012-10-30 10:35:10 -070099 pid_t tid = strtol(e->d_name, &end, 10);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700100 if (!*end) {
101 bool contains;
102 {
Ian Rogers50b35e22012-10-04 10:09:15 -0700103 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700104 contains = Contains(tid);
105 }
106 if (!contains) {
107 DumpUnattachedThread(os, tid);
108 }
Elliott Hughesabbe07d2012-06-05 17:42:23 -0700109 }
110 }
111 closedir(d);
Elliott Hughesff738062012-02-03 15:00:42 -0800112}
113
114void ThreadList::DumpLocked(std::ostream& os) {
Elliott Hughes8daa0922011-09-11 13:46:25 -0700115 os << "DALVIK THREADS (" << list_.size() << "):\n";
Elliott Hughes8daa0922011-09-11 13:46:25 -0700116 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
117 (*it)->Dump(os);
118 os << "\n";
119 }
120}
121
Ian Rogers50b35e22012-10-04 10:09:15 -0700122void ThreadList::AssertThreadsAreSuspended(Thread* self, Thread* ignore1, Thread* ignore2) {
123 MutexLock mu(self, *Locks::thread_list_lock_);
124 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Elliott Hughes8d768a92011-09-14 16:35:25 -0700125 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
126 Thread* thread = *it;
jeffhao725a9572012-11-13 18:20:12 -0800127 if (thread != ignore1 && thread != ignore2) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700128 CHECK(thread->IsSuspended())
129 << "\nUnsuspended thread: <<" << *thread << "\n"
130 << "self: <<" << *Thread::Current();
131 }
Elliott Hughes8d768a92011-09-14 16:35:25 -0700132 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700133}
134
Ian Rogers66aee5c2012-08-15 17:17:47 -0700135#if HAVE_TIMED_RWLOCK
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700136// Attempt to rectify locks so that we dump thread list with required locks before exiting.
Ian Rogers81d425b2012-09-27 16:03:43 -0700137static void UnsafeLogFatalForThreadSuspendAllTimeout(Thread* self) NO_THREAD_SAFETY_ANALYSIS {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700138 Runtime* runtime = Runtime::Current();
139 std::ostringstream ss;
140 ss << "Thread suspend timeout\n";
141 runtime->DumpLockHolders(ss);
142 ss << "\n";
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700143 runtime->GetThreadList()->DumpLocked(ss);
144 LOG(FATAL) << ss.str();
145}
Ian Rogers66aee5c2012-08-15 17:17:47 -0700146#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700147
Mathieu Chartier0e4627e2012-10-23 16:13:36 -0700148size_t ThreadList::RunCheckpoint(Closure* checkpoint_function) {
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700149 Thread* self = Thread::Current();
150 if (kIsDebugBuild) {
Mathieu Chartier2b82db42012-11-14 17:29:05 -0800151 Locks::mutator_lock_->AssertNotExclusiveHeld(self);
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700152 Locks::thread_list_lock_->AssertNotHeld(self);
153 Locks::thread_suspend_count_lock_->AssertNotHeld(self);
154 CHECK_NE(self->GetState(), kRunnable);
155 }
156
157 std::vector<Thread*> suspended_count_modified_threads;
158 size_t count = 0;
159 {
160 // Call a checkpoint function for each thread, threads which are suspend get their checkpoint
161 // manually called.
162 MutexLock mu(self, *Locks::thread_list_lock_);
163 // TODO: C++0x auto.
164 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
165 Thread* thread = *it;
166 if (thread != self) {
167 for (;;) {
168 if (thread->RequestCheckpoint(checkpoint_function)) {
169 // This thread will run it's checkpoint some time in the near future.
170 count++;
171 break;
172 } else {
173 // We are probably suspended, try to make sure that we stay suspended.
174 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
175 // The thread switched back to runnable.
176 if (thread->GetState() == kRunnable) {
177 continue;
178 }
179 thread->ModifySuspendCount(self, +1, false);
180 suspended_count_modified_threads.push_back(thread);
181 break;
182 }
183 }
184 }
185 }
186 }
187
188 // Run the checkpoint on ourself while we wait for threads to suspend.
189 checkpoint_function->Run(self);
190
191 // Run the checkpoint on the suspended threads.
192 for (size_t i = 0; i < suspended_count_modified_threads.size(); ++i) {
193 Thread* thread = suspended_count_modified_threads[i];
194 if (!thread->IsSuspended()) {
195 // Wait until the thread is suspended.
196 uint64_t start = NanoTime();
197 do {
198 // Sleep for 100us.
199 usleep(100);
200 } while (!thread->IsSuspended());
201 uint64_t end = NanoTime();
202 // Shouldn't need to wait for longer than 1 millisecond.
203 const uint64_t threshold = 1;
204 if (NsToMs(end - start) > threshold) {
Sameer Abu Asala8439542013-02-14 16:06:42 -0800205 LOG(INFO) << "Warning: waited longer than " << threshold
206 << " ms for thread suspend\n";
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700207 }
208 }
209 // We know for sure that the thread is suspended at this point.
210 thread->RunCheckpointFunction();
211 {
212 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
213 thread->ModifySuspendCount(self, -1, false);
214 }
215 }
216
Mathieu Chartier664bebf2012-11-12 16:54:11 -0800217 {
218 // Imitate ResumeAll, threads may be waiting on Thread::resume_cond_ since we raised their
219 // suspend count. Now the suspend_count_ is lowered so we must do the broadcast.
220 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
221 Thread::resume_cond_->Broadcast(self);
222 }
223
Mathieu Chartier858f1c52012-10-17 17:45:55 -0700224 // Add one for self.
225 return count + suspended_count_modified_threads.size() + 1;
226}
227
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700228void ThreadList::SuspendAll() {
229 Thread* self = Thread::Current();
230
231 VLOG(threads) << *self << " SuspendAll starting...";
232
233 if (kIsDebugBuild) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700234 Locks::mutator_lock_->AssertNotHeld(self);
235 Locks::thread_list_lock_->AssertNotHeld(self);
236 Locks::thread_suspend_count_lock_->AssertNotHeld(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700237 CHECK_NE(self->GetState(), kRunnable);
238 }
239 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700240 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700241 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700242 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700243 // Update global suspend all state for attaching threads.
244 ++suspend_all_count_;
245 // Increment everybody's suspend count (except our own).
246 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
247 Thread* thread = *it;
248 if (thread == self) {
249 continue;
250 }
251 VLOG(threads) << "requesting thread suspend: " << *thread;
Ian Rogers01ae5802012-09-28 16:14:01 -0700252 thread->ModifySuspendCount(self, +1, false);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700253 }
254 }
255 }
256
Ian Rogers66aee5c2012-08-15 17:17:47 -0700257 // Block on the mutator lock until all Runnable threads release their share of access.
258#if HAVE_TIMED_RWLOCK
259 // Timeout if we wait more than 30 seconds.
Ian Rogersc604d732012-10-14 16:09:54 -0700260 if (UNLIKELY(!Locks::mutator_lock_->ExclusiveLockWithTimeout(self, 30 * 1000, 0))) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700261 UnsafeLogFatalForThreadSuspendAllTimeout(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700262 }
Ian Rogers66aee5c2012-08-15 17:17:47 -0700263#else
Ian Rogers81d425b2012-09-27 16:03:43 -0700264 Locks::mutator_lock_->ExclusiveLock(self);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700265#endif
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700266
267 // Debug check that all threads are suspended.
Ian Rogers50b35e22012-10-04 10:09:15 -0700268 AssertThreadsAreSuspended(self, self);
Elliott Hughes8d768a92011-09-14 16:35:25 -0700269
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800270 VLOG(threads) << *self << " SuspendAll complete";
Elliott Hughes8d768a92011-09-14 16:35:25 -0700271}
272
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700273void ThreadList::ResumeAll() {
274 Thread* self = Thread::Current();
275
276 VLOG(threads) << *self << " ResumeAll starting";
Ian Rogers01ae5802012-09-28 16:14:01 -0700277
278 // Debug check that all threads are suspended.
Ian Rogers50b35e22012-10-04 10:09:15 -0700279 AssertThreadsAreSuspended(self, self);
Ian Rogers01ae5802012-09-28 16:14:01 -0700280
Ian Rogers81d425b2012-09-27 16:03:43 -0700281 Locks::mutator_lock_->ExclusiveUnlock(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700282 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700283 MutexLock mu(self, *Locks::thread_list_lock_);
284 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700285 // Update global suspend all state for attaching threads.
286 --suspend_all_count_;
287 // Decrement the suspend counts for all threads.
288 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
289 Thread* thread = *it;
290 if (thread == self) {
291 continue;
292 }
Ian Rogers01ae5802012-09-28 16:14:01 -0700293 thread->ModifySuspendCount(self, -1, false);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700294 }
295
296 // Broadcast a notification to all suspended threads, some or all of
297 // which may choose to wake up. No need to wait for them.
298 VLOG(threads) << *self << " ResumeAll waking others";
Ian Rogersc604d732012-10-14 16:09:54 -0700299 Thread::resume_cond_->Broadcast(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700300 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700301 VLOG(threads) << *self << " ResumeAll complete";
302}
303
304void ThreadList::Resume(Thread* thread, bool for_debugger) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700305 Thread* self = Thread::Current();
306 DCHECK_NE(thread, self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700307 VLOG(threads) << "Resume(" << *thread << ") starting..." << (for_debugger ? " (debugger)" : "");
Elliott Hughes01158d72011-09-19 19:47:10 -0700308
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700309 {
310 // To check Contains.
Ian Rogers81d425b2012-09-27 16:03:43 -0700311 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700312 // To check IsSuspended.
Ian Rogers81d425b2012-09-27 16:03:43 -0700313 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
314 DCHECK(thread->IsSuspended());
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700315 if (!Contains(thread)) {
316 return;
317 }
Ian Rogers01ae5802012-09-28 16:14:01 -0700318 thread->ModifySuspendCount(self, -1, for_debugger);
Elliott Hughes01158d72011-09-19 19:47:10 -0700319 }
320
321 {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700322 VLOG(threads) << "Resume(" << *thread << ") waking others";
Ian Rogers81d425b2012-09-27 16:03:43 -0700323 MutexLock mu(self, *Locks::thread_suspend_count_lock_);
Ian Rogersc604d732012-10-14 16:09:54 -0700324 Thread::resume_cond_->Broadcast(self);
Elliott Hughes01158d72011-09-19 19:47:10 -0700325 }
326
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700327 VLOG(threads) << "Resume(" << *thread << ") complete";
328}
Elliott Hughes01158d72011-09-19 19:47:10 -0700329
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700330void ThreadList::SuspendAllForDebugger() {
331 Thread* self = Thread::Current();
332 Thread* debug_thread = Dbg::GetDebugThread();
333
334 VLOG(threads) << *self << " SuspendAllForDebugger starting...";
335
336 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700337 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700338 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700339 MutexLock mu(self, *Locks::thread_suspend_count_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700340 // Update global suspend all state for attaching threads.
341 ++suspend_all_count_;
342 ++debug_suspend_all_count_;
343 // Increment everybody's suspend count (except our own).
344 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
345 Thread* thread = *it;
346 if (thread == self || thread == debug_thread) {
347 continue;
348 }
349 VLOG(threads) << "requesting thread suspend: " << *thread;
Ian Rogers01ae5802012-09-28 16:14:01 -0700350 thread->ModifySuspendCount(self, +1, true);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700351 }
352 }
353 }
354
Ian Rogers66aee5c2012-08-15 17:17:47 -0700355 // Block on the mutator lock until all Runnable threads release their share of access then
356 // immediately unlock again.
357#if HAVE_TIMED_RWLOCK
358 // Timeout if we wait more than 30 seconds.
Ian Rogersc604d732012-10-14 16:09:54 -0700359 if (!Locks::mutator_lock_->ExclusiveLockWithTimeout(self, 30 * 1000, 0)) {
Ian Rogers81d425b2012-09-27 16:03:43 -0700360 UnsafeLogFatalForThreadSuspendAllTimeout(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700361 } else {
Ian Rogers81d425b2012-09-27 16:03:43 -0700362 Locks::mutator_lock_->ExclusiveUnlock(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700363 }
Ian Rogers66aee5c2012-08-15 17:17:47 -0700364#else
Ian Rogers81d425b2012-09-27 16:03:43 -0700365 Locks::mutator_lock_->ExclusiveLock(self);
366 Locks::mutator_lock_->ExclusiveUnlock(self);
Ian Rogers66aee5c2012-08-15 17:17:47 -0700367#endif
Ian Rogers50b35e22012-10-04 10:09:15 -0700368 AssertThreadsAreSuspended(self, self, debug_thread);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700369
370 VLOG(threads) << *self << " SuspendAll complete";
Elliott Hughes01158d72011-09-19 19:47:10 -0700371}
372
Elliott Hughes475fc232011-10-25 15:00:35 -0700373void ThreadList::SuspendSelfForDebugger() {
374 Thread* self = Thread::Current();
Elliott Hughes01158d72011-09-19 19:47:10 -0700375
Elliott Hughes475fc232011-10-25 15:00:35 -0700376 // The debugger thread must not suspend itself due to debugger activity!
377 Thread* debug_thread = Dbg::GetDebugThread();
378 CHECK(debug_thread != NULL);
379 CHECK(self != debug_thread);
jeffhaoa77f0f62012-12-05 17:19:31 -0800380 CHECK_NE(self->GetState(), kRunnable);
381 Locks::mutator_lock_->AssertNotHeld(self);
Elliott Hughes475fc232011-10-25 15:00:35 -0700382
jeffhaoa77f0f62012-12-05 17:19:31 -0800383 {
384 // Collisions with other suspends aren't really interesting. We want
385 // to ensure that we're the only one fiddling with the suspend count
386 // though.
387 MutexLock mu(self, *Locks::thread_suspend_count_lock_);
388 self->ModifySuspendCount(self, +1, true);
389 CHECK_GT(self->suspend_count_, 0);
390 }
Elliott Hughes475fc232011-10-25 15:00:35 -0700391
Elliott Hughes1f729aa2012-03-02 13:55:41 -0800392 VLOG(threads) << *self << " self-suspending (debugger)";
Elliott Hughes475fc232011-10-25 15:00:35 -0700393
394 // Tell JDWP that we've completed suspension. The JDWP thread can't
395 // tell us to resume before we're fully asleep because we hold the
396 // suspend count lock.
397 Dbg::ClearWaitForEventThread();
398
jeffhaoa77f0f62012-12-05 17:19:31 -0800399 {
400 MutexLock mu(self, *Locks::thread_suspend_count_lock_);
401 while (self->suspend_count_ != 0) {
402 Thread::resume_cond_->Wait(self);
403 if (self->suspend_count_ != 0) {
404 // The condition was signaled but we're still suspended. This
405 // can happen if the debugger lets go while a SIGQUIT thread
406 // dump event is pending (assuming SignalCatcher was resumed for
407 // just long enough to try to grab the thread-suspend lock).
408 LOG(DEBUG) << *self << " still suspended after undo "
409 << "(suspend count=" << self->suspend_count_ << ")";
410 }
Elliott Hughes475fc232011-10-25 15:00:35 -0700411 }
jeffhaoa77f0f62012-12-05 17:19:31 -0800412 CHECK_EQ(self->suspend_count_, 0);
Elliott Hughes475fc232011-10-25 15:00:35 -0700413 }
jeffhaoa77f0f62012-12-05 17:19:31 -0800414
Elliott Hughes1f729aa2012-03-02 13:55:41 -0800415 VLOG(threads) << *self << " self-reviving (debugger)";
Elliott Hughes475fc232011-10-25 15:00:35 -0700416}
417
Elliott Hughes234ab152011-10-26 14:02:26 -0700418void ThreadList::UndoDebuggerSuspensions() {
419 Thread* self = Thread::Current();
420
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800421 VLOG(threads) << *self << " UndoDebuggerSuspensions starting";
Elliott Hughes234ab152011-10-26 14:02:26 -0700422
423 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700424 MutexLock mu(self, *Locks::thread_list_lock_);
425 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700426 // Update global suspend all state for attaching threads.
427 suspend_all_count_ -= debug_suspend_all_count_;
428 debug_suspend_all_count_ = 0;
429 // Update running threads.
Elliott Hughes234ab152011-10-26 14:02:26 -0700430 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
431 Thread* thread = *it;
432 if (thread == self || thread->debug_suspend_count_ == 0) {
433 continue;
434 }
Ian Rogers01ae5802012-09-28 16:14:01 -0700435 thread->ModifySuspendCount(self, -thread->debug_suspend_count_, true);
Elliott Hughes234ab152011-10-26 14:02:26 -0700436 }
437 }
438
439 {
Ian Rogers81d425b2012-09-27 16:03:43 -0700440 MutexLock mu(self, *Locks::thread_suspend_count_lock_);
Ian Rogersc604d732012-10-14 16:09:54 -0700441 Thread::resume_cond_->Broadcast(self);
Elliott Hughes234ab152011-10-26 14:02:26 -0700442 }
443
Elliott Hughes4dd9b4d2011-12-12 18:29:24 -0800444 VLOG(threads) << "UndoDebuggerSuspensions(" << *self << ") complete";
Elliott Hughes234ab152011-10-26 14:02:26 -0700445}
446
Elliott Hughese52e49b2012-04-02 16:05:44 -0700447void ThreadList::WaitForOtherNonDaemonThreadsToExit() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700448 Thread* self = Thread::Current();
449 Locks::mutator_lock_->AssertNotHeld(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700450 bool all_threads_are_daemons;
451 do {
Ian Rogers120f1c72012-09-28 17:17:10 -0700452 {
453 // No more threads can be born after we start to shutdown.
454 MutexLock mu(self, *Locks::runtime_shutdown_lock_);
455 CHECK(Runtime::Current()->IsShuttingDown());
456 CHECK_EQ(Runtime::Current()->NumberOfThreadsBeingBorn(), 0U);
457 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700458 all_threads_are_daemons = true;
Ian Rogers120f1c72012-09-28 17:17:10 -0700459 MutexLock mu(self, *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700460 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700461 Thread* thread = *it;
Anwar Ghuloum97543682013-06-14 12:58:16 -0700462 if (thread != self && !thread->IsDaemon()) {
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700463 all_threads_are_daemons = false;
464 break;
465 }
466 }
467 if (!all_threads_are_daemons) {
468 // Wait for another thread to exit before re-checking.
Ian Rogersc604d732012-10-14 16:09:54 -0700469 thread_exit_cond_.Wait(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700470 }
Brian Carlstromdf629502013-07-17 22:39:56 -0700471 } while (!all_threads_are_daemons);
Elliott Hughes038a8062011-09-18 14:12:41 -0700472}
473
474void ThreadList::SuspendAllDaemonThreads() {
Ian Rogers81d425b2012-09-27 16:03:43 -0700475 Thread* self = Thread::Current();
476 MutexLock mu(self, *Locks::thread_list_lock_);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700477 { // Tell all the daemons it's time to suspend.
Ian Rogers81d425b2012-09-27 16:03:43 -0700478 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Elliott Hughes038a8062011-09-18 14:12:41 -0700479 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
480 Thread* thread = *it;
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700481 // This is only run after all non-daemon threads have exited, so the remainder should all be
482 // daemons.
Ian Rogers7e762862012-10-22 15:45:08 -0700483 CHECK(thread->IsDaemon()) << *thread;
Ian Rogers81d425b2012-09-27 16:03:43 -0700484 if (thread != self) {
Ian Rogers01ae5802012-09-28 16:14:01 -0700485 thread->ModifySuspendCount(self, +1, false);
Elliott Hughese52e49b2012-04-02 16:05:44 -0700486 }
Elliott Hughes038a8062011-09-18 14:12:41 -0700487 }
488 }
Elliott Hughes038a8062011-09-18 14:12:41 -0700489 // Give the threads a chance to suspend, complaining if they're slow.
490 bool have_complained = false;
491 for (int i = 0; i < 10; ++i) {
492 usleep(200 * 1000);
493 bool all_suspended = true;
494 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
495 Thread* thread = *it;
Ian Rogers81d425b2012-09-27 16:03:43 -0700496 if (thread != self && thread->GetState() == kRunnable) {
Elliott Hughes038a8062011-09-18 14:12:41 -0700497 if (!have_complained) {
498 LOG(WARNING) << "daemon thread not yet suspended: " << *thread;
499 have_complained = true;
500 }
501 all_suspended = false;
502 }
503 }
504 if (all_suspended) {
505 return;
506 }
507 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700508 LOG(ERROR) << "suspend all daemons failed";
509}
510void ThreadList::Register(Thread* self) {
511 DCHECK_EQ(self, Thread::Current());
512
513 if (VLOG_IS_ON(threads)) {
514 std::ostringstream oss;
515 self->ShortDump(oss); // We don't hold the mutator_lock_ yet and so cannot call Dump.
516 LOG(INFO) << "ThreadList::Register() " << *self << "\n" << oss;
517 }
518
519 // Atomically add self to the thread list and make its thread_suspend_count_ reflect ongoing
520 // SuspendAll requests.
Ian Rogers81d425b2012-09-27 16:03:43 -0700521 MutexLock mu(self, *Locks::thread_list_lock_);
522 MutexLock mu2(self, *Locks::thread_suspend_count_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700523 self->suspend_count_ = suspend_all_count_;
524 self->debug_suspend_count_ = debug_suspend_all_count_;
Ian Rogers01ae5802012-09-28 16:14:01 -0700525 if (self->suspend_count_ > 0) {
526 self->AtomicSetFlag(kSuspendRequest);
527 }
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700528 CHECK(!Contains(self));
529 list_.push_back(self);
530}
531
532void ThreadList::Unregister(Thread* self) {
533 DCHECK_EQ(self, Thread::Current());
534
535 VLOG(threads) << "ThreadList::Unregister() " << *self;
536
537 // Any time-consuming destruction, plus anything that can call back into managed code or
538 // suspend and so on, must happen at this point, and not in ~Thread.
539 self->Destroy();
540
Ian Rogerscfaa4552012-11-26 21:00:08 -0800541 uint32_t thin_lock_id = self->thin_lock_id_;
542 self->thin_lock_id_ = 0;
543 ReleaseThreadId(self, thin_lock_id);
544 while (self != NULL) {
545 // Remove and delete the Thread* while holding the thread_list_lock_ and
546 // thread_suspend_count_lock_ so that the unregistering thread cannot be suspended.
Ian Rogers0878d652013-04-18 17:38:35 -0700547 // Note: deliberately not using MutexLock that could hold a stale self pointer.
548 Locks::thread_list_lock_->ExclusiveLock(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700549 CHECK(Contains(self));
Ian Rogerscfaa4552012-11-26 21:00:08 -0800550 // Note: we don't take the thread_suspend_count_lock_ here as to be suspending a thread other
551 // than yourself you need to hold the thread_list_lock_ (see Thread::ModifySuspendCount).
552 if (!self->IsSuspended()) {
553 list_.remove(self);
554 delete self;
555 self = NULL;
556 }
Ian Rogers0878d652013-04-18 17:38:35 -0700557 Locks::thread_list_lock_->ExclusiveUnlock(self);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700558 }
559
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700560 // Clear the TLS data, so that the underlying native thread is recognizably detached.
561 // (It may wish to reattach later.)
562 CHECK_PTHREAD_CALL(pthread_setspecific, (Thread::pthread_key_self_, NULL), "detach self");
563
564 // Signal that a thread just detached.
Ian Rogers81d425b2012-09-27 16:03:43 -0700565 MutexLock mu(NULL, *Locks::thread_list_lock_);
Ian Rogersc604d732012-10-14 16:09:54 -0700566 thread_exit_cond_.Signal(NULL);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700567}
568
569void ThreadList::ForEach(void (*callback)(Thread*, void*), void* context) {
570 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
571 callback(*it, context);
572 }
573}
574
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800575void ThreadList::VisitRoots(RootVisitor* visitor, void* arg) const {
Ian Rogers81d425b2012-09-27 16:03:43 -0700576 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700577 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
578 (*it)->VisitRoots(visitor, arg);
579 }
Elliott Hughes038a8062011-09-18 14:12:41 -0700580}
581
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800582void ThreadList::VerifyRoots(VerifyRootVisitor* visitor, void* arg) const {
Mathieu Chartier6f1c9492012-10-15 12:08:41 -0700583 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
584 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
585 (*it)->VerifyRoots(visitor, arg);
586 }
587}
588
Ian Rogerscfaa4552012-11-26 21:00:08 -0800589uint32_t ThreadList::AllocThreadId(Thread* self) {
590 MutexLock mu(self, allocated_ids_lock_);
Elliott Hughes8daa0922011-09-11 13:46:25 -0700591 for (size_t i = 0; i < allocated_ids_.size(); ++i) {
592 if (!allocated_ids_[i]) {
593 allocated_ids_.set(i);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700594 return i + 1; // Zero is reserved to mean "invalid".
Elliott Hughes8daa0922011-09-11 13:46:25 -0700595 }
596 }
597 LOG(FATAL) << "Out of internal thread ids";
598 return 0;
599}
600
Ian Rogerscfaa4552012-11-26 21:00:08 -0800601void ThreadList::ReleaseThreadId(Thread* self, uint32_t id) {
602 MutexLock mu(self, allocated_ids_lock_);
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700603 --id; // Zero is reserved to mean "invalid".
Elliott Hughes8daa0922011-09-11 13:46:25 -0700604 DCHECK(allocated_ids_[id]) << id;
605 allocated_ids_.reset(id);
606}
607
Elliott Hughesf327e072013-01-09 16:01:26 -0800608Thread* ThreadList::FindThreadByThinLockId(uint32_t thin_lock_id) {
609 MutexLock mu(Thread::Current(), *Locks::thread_list_lock_);
610 for (It it = list_.begin(), end = list_.end(); it != end; ++it) {
611 if ((*it)->GetThinLockId() == thin_lock_id) {
612 return *it;
613 }
614 }
615 return NULL;
616}
617
Elliott Hughes8daa0922011-09-11 13:46:25 -0700618} // namespace art