blob: 3f63132eea292cf32733f4045dddb3ab7cd8f157 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 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 */
The Android Open Source Project99409882009-03-18 22:20:24 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Thread support.
19 */
20#include "Dalvik.h"
21
22#include "utils/threads.h" // need Android thread priorities
23
24#include <stdlib.h>
25#include <unistd.h>
26#include <sys/time.h>
27#include <sys/resource.h>
28#include <sys/mman.h>
29#include <errno.h>
Andy McFaddend62c0b52009-08-04 15:02:12 -070030#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080031
32#if defined(HAVE_PRCTL)
33#include <sys/prctl.h>
34#endif
35
36/* desktop Linux needs a little help with gettid() */
37#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
38#define __KERNEL__
39# include <linux/unistd.h>
40#ifdef _syscall0
41_syscall0(pid_t,gettid)
42#else
43pid_t gettid() { return syscall(__NR_gettid);}
44#endif
45#undef __KERNEL__
46#endif
47
San Mehat256fc152009-04-21 14:03:06 -070048// Change this to enable logging on cgroup errors
49#define ENABLE_CGROUP_ERR_LOGGING 0
50
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080051// change this to LOGV/LOGD to debug thread activity
52#define LOG_THREAD LOGVV
53
54/*
55Notes on Threading
56
57All threads are native pthreads. All threads, except the JDWP debugger
58thread, are visible to code running in the VM and to the debugger. (We
59don't want the debugger to try to manipulate the thread that listens for
60instructions from the debugger.) Internal VM threads are in the "system"
61ThreadGroup, all others are in the "main" ThreadGroup, per convention.
62
63The GC only runs when all threads have been suspended. Threads are
64expected to suspend themselves, using a "safe point" mechanism. We check
65for a suspend request at certain points in the main interpreter loop,
66and on requests coming in from native code (e.g. all JNI functions).
67Certain debugger events may inspire threads to self-suspend.
68
69Native methods must use JNI calls to modify object references to avoid
70clashes with the GC. JNI doesn't provide a way for native code to access
71arrays of objects as such -- code must always get/set individual entries --
72so it should be possible to fully control access through JNI.
73
74Internal native VM threads, such as the finalizer thread, must explicitly
75check for suspension periodically. In most cases they will be sound
76asleep on a condition variable, and won't notice the suspension anyway.
77
78Threads may be suspended by the GC, debugger, or the SIGQUIT listener
79thread. The debugger may suspend or resume individual threads, while the
80GC always suspends all threads. Each thread has a "suspend count" that
81is incremented on suspend requests and decremented on resume requests.
82When the count is zero, the thread is runnable. This allows us to fulfill
83a debugger requirement: if the debugger suspends a thread, the thread is
84not allowed to run again until the debugger resumes it (or disconnects,
85in which case we must resume all debugger-suspended threads).
86
87Paused threads sleep on a condition variable, and are awoken en masse.
88Certain "slow" VM operations, such as starting up a new thread, will be
89done in a separate "VMWAIT" state, so that the rest of the VM doesn't
90freeze up waiting for the operation to finish. Threads must check for
91pending suspension when leaving VMWAIT.
92
93Because threads suspend themselves while interpreting code or when native
94code makes JNI calls, there is no risk of suspending while holding internal
95VM locks. All threads can enter a suspended (or native-code-only) state.
96Also, we don't have to worry about object references existing solely
97in hardware registers.
98
99We do, however, have to worry about objects that were allocated internally
100and aren't yet visible to anything else in the VM. If we allocate an
101object, and then go to sleep on a mutex after changing to a non-RUNNING
102state (e.g. while trying to allocate a second object), the first object
103could be garbage-collected out from under us while we sleep. To manage
104this, we automatically add all allocated objects to an internal object
105tracking list, and only remove them when we know we won't be suspended
106before the object appears in the GC root set.
107
108The debugger may choose to suspend or resume a single thread, which can
109lead to application-level deadlocks; this is expected behavior. The VM
110will only check for suspension of single threads when the debugger is
111active (the java.lang.Thread calls for this are deprecated and hence are
112not supported). Resumption of a single thread is handled by decrementing
113the thread's suspend count and sending a broadcast signal to the condition
114variable. (This will cause all threads to wake up and immediately go back
115to sleep, which isn't tremendously efficient, but neither is having the
116debugger attached.)
117
118The debugger is not allowed to resume threads suspended by the GC. This
119is trivially enforced by ignoring debugger requests while the GC is running
120(the JDWP thread is suspended during GC).
121
122The VM maintains a Thread struct for every pthread known to the VM. There
123is a java/lang/Thread object associated with every Thread. At present,
124there is no safe way to go from a Thread object to a Thread struct except by
125locking and scanning the list; this is necessary because the lifetimes of
126the two are not closely coupled. We may want to change this behavior,
127though at present the only performance impact is on the debugger (see
128threadObjToThread()). See also notes about dvmDetachCurrentThread().
129*/
130/*
131Alternate implementation (signal-based):
132
133Threads run without safe points -- zero overhead. The VM uses a signal
134(e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
135
136The trouble with using signals to suspend threads is that it means a thread
137can be in the middle of an operation when garbage collection starts.
138To prevent some sticky situations, we have to introduce critical sections
139to the VM code.
140
141Critical sections temporarily block suspension for a given thread.
142The thread must move to a non-blocked state (and self-suspend) after
143finishing its current task. If the thread blocks on a resource held
144by a suspended thread, we're hosed.
145
146One approach is to require that no blocking operations, notably
147acquisition of mutexes, can be performed within a critical section.
148This is too limiting. For example, if thread A gets suspended while
149holding the thread list lock, it will prevent the GC or debugger from
150being able to safely access the thread list. We need to wrap the critical
151section around the entire operation (enter critical, get lock, do stuff,
152release lock, exit critical).
153
154A better approach is to declare that certain resources can only be held
155within critical sections. A thread that enters a critical section and
156then gets blocked on the thread list lock knows that the thread it is
157waiting for is also in a critical section, and will release the lock
158before suspending itself. Eventually all threads will complete their
159operations and self-suspend. For this to work, the VM must:
160
161 (1) Determine the set of resources that may be accessed from the GC or
162 debugger threads. The mutexes guarding those go into the "critical
163 resource set" (CRS).
164 (2) Ensure that no resource in the CRS can be acquired outside of a
165 critical section. This can be verified with an assert().
166 (3) Ensure that only resources in the CRS can be held while in a critical
167 section. This is harder to enforce.
168
169If any of these conditions are not met, deadlock can ensue when grabbing
170resources in the GC or debugger (#1) or waiting for threads to suspend
171(#2,#3). (You won't actually deadlock in the GC, because if the semantics
172above are followed you don't need to lock anything in the GC. The risk is
173rather that the GC will access data structures in an intermediate state.)
174
175This approach requires more care and awareness in the VM than
176safe-pointing. Because the GC and debugger are fairly intrusive, there
177really aren't any internal VM resources that aren't shared. Thus, the
178enter/exit critical calls can be added to internal mutex wrappers, which
179makes it easy to get #1 and #2 right.
180
181An ordering should be established for all locks to avoid deadlocks.
182
183Monitor locks, which are also implemented with pthread calls, should not
184cause any problems here. Threads fighting over such locks will not be in
185critical sections and can be suspended freely.
186
187This can get tricky if we ever need exclusive access to VM and non-VM
188resources at the same time. It's not clear if this is a real concern.
189
190There are (at least) two ways to handle the incoming signals:
191
192 (a) Always accept signals. If we're in a critical section, the signal
193 handler just returns without doing anything (the "suspend level"
194 should have been incremented before the signal was sent). Otherwise,
195 if the "suspend level" is nonzero, we go to sleep.
196 (b) Block signals in critical sections. This ensures that we can't be
197 interrupted in a critical section, but requires pthread_sigmask()
198 calls on entry and exit.
199
200This is a choice between blocking the message and blocking the messenger.
201Because UNIX signals are unreliable (you can only know that you have been
202signaled, not whether you were signaled once or 10 times), the choice is
203not significant for correctness. The choice depends on the efficiency
204of pthread_sigmask() and the desire to actually block signals. Either way,
205it is best to ensure that there is only one indication of "blocked";
206having two (i.e. block signals and set a flag, then only send a signal
207if the flag isn't set) can lead to race conditions.
208
209The signal handler must take care to copy registers onto the stack (via
210setjmp), so that stack scans find all references. Because we have to scan
211native stacks, "exact" GC is not possible with this approach.
212
213Some other concerns with flinging signals around:
214 - Odd interactions with some debuggers (e.g. gdb on the Mac)
215 - Restrictions on some standard library calls during GC (e.g. don't
216 use printf on stdout to print GC debug messages)
217*/
218
219#define kMaxThreadId ((1<<15) - 1)
220#define kMainThreadId ((1<<1) | 1)
221
222
223static Thread* allocThread(int interpStackSize);
224static bool prepareThread(Thread* thread);
225static void setThreadSelf(Thread* thread);
226static void unlinkThread(Thread* thread);
227static void freeThread(Thread* thread);
228static void assignThreadId(Thread* thread);
229static bool createFakeEntryFrame(Thread* thread);
230static bool createFakeRunFrame(Thread* thread);
231static void* interpThreadStart(void* arg);
232static void* internalThreadStart(void* arg);
233static void threadExitUncaughtException(Thread* thread, Object* group);
234static void threadExitCheck(void* arg);
235static void waitForThreadSuspend(Thread* self, Thread* thread);
236static int getThreadPriorityFromSystem(void);
237
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700238/*
239 * The JIT needs to know if any thread is suspended. We do this by
240 * maintaining a global sum of all threads' suspend counts. All suspendCount
241 * updates should go through this after aquiring threadSuspendCountLock.
242 */
243static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
244{
245 *pSuspendCount += delta;
246 gDvm.sumThreadSuspendCount += delta;
247}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800248
249/*
250 * Initialize thread list and main thread's environment. We need to set
251 * up some basic stuff so that dvmThreadSelf() will work when we start
252 * loading classes (e.g. to check for exceptions).
253 */
254bool dvmThreadStartup(void)
255{
256 Thread* thread;
257
258 /* allocate a TLS slot */
259 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
260 LOGE("ERROR: pthread_key_create failed\n");
261 return false;
262 }
263
264 /* test our pthread lib */
265 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
266 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
267
268 /* prep thread-related locks and conditions */
269 dvmInitMutex(&gDvm.threadListLock);
270 pthread_cond_init(&gDvm.threadStartCond, NULL);
271 //dvmInitMutex(&gDvm.vmExitLock);
272 pthread_cond_init(&gDvm.vmExitCond, NULL);
273 dvmInitMutex(&gDvm._threadSuspendLock);
274 dvmInitMutex(&gDvm.threadSuspendCountLock);
275 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
276#ifdef WITH_DEADLOCK_PREDICTION
277 dvmInitMutex(&gDvm.deadlockHistoryLock);
278#endif
279
280 /*
281 * Dedicated monitor for Thread.sleep().
282 * TODO: change this to an Object* so we don't have to expose this
283 * call, and we interact better with JDWP monitor calls. Requires
284 * deferring the object creation to much later (e.g. final "main"
285 * thread prep) or until first use.
286 */
287 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
288
289 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
290
291 thread = allocThread(gDvm.stackSize);
292 if (thread == NULL)
293 return false;
294
295 /* switch mode for when we run initializers */
296 thread->status = THREAD_RUNNING;
297
298 /*
299 * We need to assign the threadId early so we can lock/notify
300 * object monitors. We'll set the "threadObj" field later.
301 */
302 prepareThread(thread);
303 gDvm.threadList = thread;
304
305#ifdef COUNT_PRECISE_METHODS
306 gDvm.preciseMethods = dvmPointerSetAlloc(200);
307#endif
308
309 return true;
310}
311
312/*
313 * We're a little farther up now, and can load some basic classes.
314 *
315 * We're far enough along that we can poke at java.lang.Thread and friends,
316 * but should not assume that static initializers have run (or cause them
317 * to do so). That means no object allocations yet.
318 */
319bool dvmThreadObjStartup(void)
320{
321 /*
322 * Cache the locations of these classes. It's likely that we're the
323 * first to reference them, so they're being loaded now.
324 */
325 gDvm.classJavaLangThread =
326 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
327 gDvm.classJavaLangVMThread =
328 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
329 gDvm.classJavaLangThreadGroup =
330 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
331 if (gDvm.classJavaLangThread == NULL ||
332 gDvm.classJavaLangThreadGroup == NULL ||
333 gDvm.classJavaLangThreadGroup == NULL)
334 {
335 LOGE("Could not find one or more essential thread classes\n");
336 return false;
337 }
338
339 /*
340 * Cache field offsets. This makes things a little faster, at the
341 * expense of hard-coding non-public field names into the VM.
342 */
343 gDvm.offJavaLangThread_vmThread =
344 dvmFindFieldOffset(gDvm.classJavaLangThread,
345 "vmThread", "Ljava/lang/VMThread;");
346 gDvm.offJavaLangThread_group =
347 dvmFindFieldOffset(gDvm.classJavaLangThread,
348 "group", "Ljava/lang/ThreadGroup;");
349 gDvm.offJavaLangThread_daemon =
350 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
351 gDvm.offJavaLangThread_name =
352 dvmFindFieldOffset(gDvm.classJavaLangThread,
353 "name", "Ljava/lang/String;");
354 gDvm.offJavaLangThread_priority =
355 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
356
357 if (gDvm.offJavaLangThread_vmThread < 0 ||
358 gDvm.offJavaLangThread_group < 0 ||
359 gDvm.offJavaLangThread_daemon < 0 ||
360 gDvm.offJavaLangThread_name < 0 ||
361 gDvm.offJavaLangThread_priority < 0)
362 {
363 LOGE("Unable to find all fields in java.lang.Thread\n");
364 return false;
365 }
366
367 gDvm.offJavaLangVMThread_thread =
368 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
369 "thread", "Ljava/lang/Thread;");
370 gDvm.offJavaLangVMThread_vmData =
371 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
372 if (gDvm.offJavaLangVMThread_thread < 0 ||
373 gDvm.offJavaLangVMThread_vmData < 0)
374 {
375 LOGE("Unable to find all fields in java.lang.VMThread\n");
376 return false;
377 }
378
379 /*
380 * Cache the vtable offset for "run()".
381 *
382 * We don't want to keep the Method* because then we won't find see
383 * methods defined in subclasses.
384 */
385 Method* meth;
386 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
387 if (meth == NULL) {
388 LOGE("Unable to find run() in java.lang.Thread\n");
389 return false;
390 }
391 gDvm.voffJavaLangThread_run = meth->methodIndex;
392
393 /*
394 * Cache vtable offsets for ThreadGroup methods.
395 */
396 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
397 "removeThread", "(Ljava/lang/Thread;)V");
398 if (meth == NULL) {
399 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
400 return false;
401 }
402 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
403
404 return true;
405}
406
407/*
408 * All threads should be stopped by now. Clean up some thread globals.
409 */
410void dvmThreadShutdown(void)
411{
412 if (gDvm.threadList != NULL) {
Andy McFaddenf17638e2009-08-04 16:38:40 -0700413 /*
414 * If we walk through the thread list and try to free the
415 * lingering thread structures (which should only be for daemon
416 * threads), the daemon threads may crash if they execute before
417 * the process dies. Let them leak.
418 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800419 freeThread(gDvm.threadList);
420 gDvm.threadList = NULL;
421 }
422
423 dvmFreeBitVector(gDvm.threadIdMap);
424
425 dvmFreeMonitorList();
426
427 pthread_key_delete(gDvm.pthreadKeySelf);
428}
429
430
431/*
432 * Grab the suspend count global lock.
433 */
434static inline void lockThreadSuspendCount(void)
435{
436 /*
437 * Don't try to change to VMWAIT here. When we change back to RUNNING
438 * we have to check for a pending suspend, which results in grabbing
439 * this lock recursively. Doesn't work with "fast" pthread mutexes.
440 *
441 * This lock is always held for very brief periods, so as long as
442 * mutex ordering is respected we shouldn't stall.
443 */
444 int cc = pthread_mutex_lock(&gDvm.threadSuspendCountLock);
445 assert(cc == 0);
446}
447
448/*
449 * Release the suspend count global lock.
450 */
451static inline void unlockThreadSuspendCount(void)
452{
453 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
454}
455
456/*
457 * Grab the thread list global lock.
458 *
459 * This is held while "suspend all" is trying to make everybody stop. If
460 * the shutdown is in progress, and somebody tries to grab the lock, they'll
461 * have to wait for the GC to finish. Therefore it's important that the
462 * thread not be in RUNNING mode.
463 *
464 * We don't have to check to see if we should be suspended once we have
465 * the lock. Nobody can suspend all threads without holding the thread list
466 * lock while they do it, so by definition there isn't a GC in progress.
Andy McFadden44860362009-08-06 17:56:14 -0700467 *
468 * TODO: consider checking for suspend after acquiring the lock, and
469 * backing off if set. As stated above, it can't happen during normal
470 * execution, but it *can* happen during shutdown when daemon threads
471 * are being suspended.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800472 */
473void dvmLockThreadList(Thread* self)
474{
475 ThreadStatus oldStatus;
476
477 if (self == NULL) /* try to get it from TLS */
478 self = dvmThreadSelf();
479
480 if (self != NULL) {
481 oldStatus = self->status;
482 self->status = THREAD_VMWAIT;
483 } else {
Andy McFadden44860362009-08-06 17:56:14 -0700484 /* happens during VM shutdown */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800485 //LOGW("NULL self in dvmLockThreadList\n");
486 oldStatus = -1; // shut up gcc
487 }
488
489 int cc = pthread_mutex_lock(&gDvm.threadListLock);
490 assert(cc == 0);
491
492 if (self != NULL)
493 self->status = oldStatus;
494}
495
496/*
497 * Release the thread list global lock.
498 */
499void dvmUnlockThreadList(void)
500{
501 int cc = pthread_mutex_unlock(&gDvm.threadListLock);
502 assert(cc == 0);
503}
504
The Android Open Source Project99409882009-03-18 22:20:24 -0700505/*
506 * Convert SuspendCause to a string.
507 */
508static const char* getSuspendCauseStr(SuspendCause why)
509{
510 switch (why) {
511 case SUSPEND_NOT: return "NOT?";
512 case SUSPEND_FOR_GC: return "gc";
513 case SUSPEND_FOR_DEBUG: return "debug";
514 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
515 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
516 default: return "UNKNOWN";
517 }
518}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800519
520/*
521 * Grab the "thread suspend" lock. This is required to prevent the
522 * GC and the debugger from simultaneously suspending all threads.
523 *
524 * If we fail to get the lock, somebody else is trying to suspend all
525 * threads -- including us. If we go to sleep on the lock we'll deadlock
526 * the VM. Loop until we get it or somebody puts us to sleep.
527 */
528static void lockThreadSuspend(const char* who, SuspendCause why)
529{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800530 const int kSpinSleepTime = 3*1000*1000; /* 3s */
531 u8 startWhen = 0; // init req'd to placate gcc
532 int sleepIter = 0;
533 int cc;
534
535 do {
536 cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
537 if (cc != 0) {
538 if (!dvmCheckSuspendPending(NULL)) {
539 /*
Andy McFadden2aa43612009-06-17 16:29:30 -0700540 * Could be that a resume-all is in progress, and something
541 * grabbed the CPU when the wakeup was broadcast. The thread
542 * performing the resume hasn't had a chance to release the
Andy McFaddene8059be2009-06-04 14:34:14 -0700543 * thread suspend lock. (We release before the broadcast,
544 * so this should be a narrow window.)
Andy McFadden2aa43612009-06-17 16:29:30 -0700545 *
546 * Could be we hit the window as a suspend was started,
547 * and the lock has been grabbed but the suspend counts
548 * haven't been incremented yet.
The Android Open Source Project99409882009-03-18 22:20:24 -0700549 *
550 * Could be an unusual JNI thread-attach thing.
551 *
552 * Could be the debugger telling us to resume at roughly
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800553 * the same time we're posting an event.
554 */
The Android Open Source Project99409882009-03-18 22:20:24 -0700555 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
556 " it's held, no suspend pending\n",
557 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
558 } else {
559 /* we suspended; reset timeout */
560 sleepIter = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800561 }
562
563 /* give the lock-holder a chance to do some work */
564 if (sleepIter == 0)
565 startWhen = dvmGetRelativeTimeUsec();
566 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
The Android Open Source Project99409882009-03-18 22:20:24 -0700567 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800568 " bailing\n",
The Android Open Source Project99409882009-03-18 22:20:24 -0700569 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
Andy McFadden2aa43612009-06-17 16:29:30 -0700570 /* threads are not suspended, thread dump could crash */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800571 dvmDumpAllThreads(false);
572 dvmAbort();
573 }
574 }
575 } while (cc != 0);
576 assert(cc == 0);
577}
578
579/*
580 * Release the "thread suspend" lock.
581 */
582static inline void unlockThreadSuspend(void)
583{
584 int cc = pthread_mutex_unlock(&gDvm._threadSuspendLock);
585 assert(cc == 0);
586}
587
588
589/*
590 * Kill any daemon threads that still exist. All of ours should be
591 * stopped, so these should be Thread objects or JNI-attached threads
592 * started by the application. Actively-running threads are likely
593 * to crash the process if they continue to execute while the VM
594 * shuts down, so we really need to kill or suspend them. (If we want
595 * the VM to restart within this process, we need to kill them, but that
596 * leaves open the possibility of orphaned resources.)
597 *
598 * Waiting for the thread to suspend may be unwise at this point, but
599 * if one of these is wedged in a critical section then we probably
600 * would've locked up on the last GC attempt.
601 *
602 * It's possible for this function to get called after a failed
603 * initialization, so be careful with assumptions about the environment.
Andy McFadden44860362009-08-06 17:56:14 -0700604 *
605 * This will be called from whatever thread calls DestroyJavaVM, usually
606 * but not necessarily the main thread. It's likely, but not guaranteed,
607 * that the current thread has already been cleaned up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800608 */
609void dvmSlayDaemons(void)
610{
Andy McFadden44860362009-08-06 17:56:14 -0700611 Thread* self = dvmThreadSelf(); // may be null
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800612 Thread* target;
Andy McFadden44860362009-08-06 17:56:14 -0700613 int threadId = 0;
614 bool doWait = false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800615
616 //dvmEnterCritical(self);
617 dvmLockThreadList(self);
618
Andy McFadden44860362009-08-06 17:56:14 -0700619 if (self != NULL)
620 threadId = self->threadId;
621
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800622 target = gDvm.threadList;
623 while (target != NULL) {
624 if (target == self) {
625 target = target->next;
626 continue;
627 }
628
629 if (!dvmGetFieldBoolean(target->threadObj,
630 gDvm.offJavaLangThread_daemon))
631 {
Andy McFadden44860362009-08-06 17:56:14 -0700632 /* should never happen; suspend it with the rest */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800633 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
Andy McFadden44860362009-08-06 17:56:14 -0700634 threadId, target->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800635 }
636
Andy McFadden44860362009-08-06 17:56:14 -0700637 char* threadName = dvmGetThreadName(target);
638 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
639 threadId, target->threadId, threadName);
640 free(threadName);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800641
Andy McFadden44860362009-08-06 17:56:14 -0700642 /* mark as suspended */
643 lockThreadSuspendCount();
644 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
645 unlockThreadSuspendCount();
646 doWait = true;
647
648 target = target->next;
649 }
650
651 //dvmDumpAllThreads(false);
652
653 /*
654 * Unlock the thread list, relocking it later if necessary. It's
655 * possible a thread is in VMWAIT after calling dvmLockThreadList,
656 * and that function *doesn't* check for pending suspend after
657 * acquiring the lock. We want to let them finish their business
658 * and see the pending suspend before we continue here.
659 *
660 * There's no guarantee of mutex fairness, so this might not work.
661 * (The alternative is to have dvmLockThreadList check for suspend
662 * after acquiring the lock and back off, something we should consider.)
663 */
664 dvmUnlockThreadList();
665
666 if (doWait) {
667 usleep(200 * 1000);
668
669 dvmLockThreadList(self);
670
671 /*
672 * Sleep for a bit until the threads have suspended. We're trying
673 * to exit, so don't wait for too long.
674 */
675 int i;
676 for (i = 0; i < 10; i++) {
677 bool allSuspended = true;
678
679 target = gDvm.threadList;
680 while (target != NULL) {
681 if (target == self) {
682 target = target->next;
683 continue;
684 }
685
686 if (target->status == THREAD_RUNNING && !target->isSuspended) {
687 LOGD("threadid=%d not ready yet\n", target->threadId);
688 allSuspended = false;
689 break;
690 }
691
692 target = target->next;
693 }
694
695 if (allSuspended) {
696 LOGD("threadid=%d: all daemons have suspended\n", threadId);
697 break;
698 } else {
699 LOGD("threadid=%d: waiting for daemons to suspend\n", threadId);
700 }
701
702 usleep(200 * 1000);
703 }
704 dvmUnlockThreadList();
705 }
706
707#if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
708 /*
709 * Abandon the threads and recover their resources.
710 */
711 target = gDvm.threadList;
712 while (target != NULL) {
713 Thread* nextTarget = target->next;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800714 unlinkThread(target);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800715 freeThread(target);
716 target = nextTarget;
717 }
Andy McFadden44860362009-08-06 17:56:14 -0700718#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800719
Andy McFadden44860362009-08-06 17:56:14 -0700720 //dvmDumpAllThreads(true);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800721}
722
723
724/*
725 * Finish preparing the parts of the Thread struct required to support
726 * JNI registration.
727 */
728bool dvmPrepMainForJni(JNIEnv* pEnv)
729{
730 Thread* self;
731
732 /* main thread is always first in list at this point */
733 self = gDvm.threadList;
734 assert(self->threadId == kMainThreadId);
735
736 /* create a "fake" JNI frame at the top of the main thread interp stack */
737 if (!createFakeEntryFrame(self))
738 return false;
739
740 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
741 dvmSetJniEnvThreadId(pEnv, self);
742 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
743
744 return true;
745}
746
747
748/*
749 * Finish preparing the main thread, allocating some objects to represent
750 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
Andy McFaddena1a7a342009-05-04 13:29:30 -0700751 * This will execute some interpreted code (e.g. class initializers).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800752 */
753bool dvmPrepMainThread(void)
754{
755 Thread* thread;
756 Object* groupObj;
757 Object* threadObj;
758 Object* vmThreadObj;
759 StringObject* threadNameStr;
760 Method* init;
761 JValue unused;
762
763 LOGV("+++ finishing prep on main VM thread\n");
764
765 /* main thread is always first in list at this point */
766 thread = gDvm.threadList;
767 assert(thread->threadId == kMainThreadId);
768
769 /*
770 * Make sure the classes are initialized. We have to do this before
771 * we create an instance of them.
772 */
773 if (!dvmInitClass(gDvm.classJavaLangClass)) {
774 LOGE("'Class' class failed to initialize\n");
775 return false;
776 }
777 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
778 !dvmInitClass(gDvm.classJavaLangThread) ||
779 !dvmInitClass(gDvm.classJavaLangVMThread))
780 {
781 LOGE("thread classes failed to initialize\n");
782 return false;
783 }
784
785 groupObj = dvmGetMainThreadGroup();
786 if (groupObj == NULL)
787 return false;
788
789 /*
790 * Allocate and construct a Thread with the internal-creation
791 * constructor.
792 */
793 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
794 if (threadObj == NULL) {
795 LOGE("unable to allocate main thread object\n");
796 return false;
797 }
798 dvmReleaseTrackedAlloc(threadObj, NULL);
799
800 threadNameStr = dvmCreateStringFromCstr("main", ALLOC_DEFAULT);
801 if (threadNameStr == NULL)
802 return false;
803 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
804
805 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
806 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
807 assert(init != NULL);
808 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
809 THREAD_NORM_PRIORITY, false);
810 if (dvmCheckException(thread)) {
811 LOGE("exception thrown while constructing main thread object\n");
812 return false;
813 }
814
815 /*
816 * Allocate and construct a VMThread.
817 */
818 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
819 if (vmThreadObj == NULL) {
820 LOGE("unable to allocate main vmthread object\n");
821 return false;
822 }
823 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
824
825 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
826 "(Ljava/lang/Thread;)V");
827 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
828 if (dvmCheckException(thread)) {
829 LOGE("exception thrown while constructing main vmthread object\n");
830 return false;
831 }
832
833 /* set the VMThread.vmData field to our Thread struct */
834 assert(gDvm.offJavaLangVMThread_vmData != 0);
835 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
836
837 /*
838 * Stuff the VMThread back into the Thread. From this point on, other
Andy McFaddena1a7a342009-05-04 13:29:30 -0700839 * Threads will see that this Thread is running (at least, they would,
840 * if there were any).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800841 */
842 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
843 vmThreadObj);
844
845 thread->threadObj = threadObj;
846
847 /*
Andy McFaddena1a7a342009-05-04 13:29:30 -0700848 * Set the context class loader. This invokes a ClassLoader method,
849 * which could conceivably call Thread.currentThread(), so we want the
850 * Thread to be fully configured before we do this.
851 */
852 Object* systemLoader = dvmGetSystemClassLoader();
853 if (systemLoader == NULL) {
854 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
855 /* keep going */
856 }
857 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
858 "contextClassLoader", "Ljava/lang/ClassLoader;");
859 if (ctxtClassLoaderOffset < 0) {
860 LOGE("Unable to find contextClassLoader field in Thread\n");
861 return false;
862 }
863 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
864
865 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800866 * Finish our thread prep.
867 */
868
869 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
870 gDvm.nonDaemonThreadCount++;
871
872 return true;
873}
874
875
876/*
877 * Alloc and initialize a Thread struct.
878 *
879 * "threadObj" is the java.lang.Thread object. It will be NULL for the
880 * main VM thread, but non-NULL for everything else.
881 *
882 * Does not create any objects, just stuff on the system (malloc) heap. (If
883 * this changes, we need to use ALLOC_NO_GC. And also verify that we're
884 * ready to load classes at the time this is called.)
885 */
886static Thread* allocThread(int interpStackSize)
887{
888 Thread* thread;
889 u1* stackBottom;
890
891 thread = (Thread*) calloc(1, sizeof(Thread));
892 if (thread == NULL)
893 return NULL;
894
895 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
896
897 thread->status = THREAD_INITIALIZING;
898 thread->suspendCount = 0;
899
900#ifdef WITH_ALLOC_LIMITS
901 thread->allocLimit = -1;
902#endif
903
904 /*
905 * Allocate and initialize the interpreted code stack. We essentially
906 * "lose" the alloc pointer, which points at the bottom of the stack,
907 * but we can get it back later because we know how big the stack is.
908 *
909 * The stack must be aligned on a 4-byte boundary.
910 */
911#ifdef MALLOC_INTERP_STACK
912 stackBottom = (u1*) malloc(interpStackSize);
913 if (stackBottom == NULL) {
914 free(thread);
915 return NULL;
916 }
917 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
918#else
919 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
920 MAP_PRIVATE | MAP_ANON, -1, 0);
921 if (stackBottom == MAP_FAILED) {
922 free(thread);
923 return NULL;
924 }
925#endif
926
927 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
928 thread->interpStackSize = interpStackSize;
929 thread->interpStackStart = stackBottom + interpStackSize;
930 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
931
932 /* give the thread code a chance to set things up */
933 dvmInitInterpStack(thread, interpStackSize);
934
935 return thread;
936}
937
938/*
939 * Get a meaningful thread ID. At present this only has meaning under Linux,
940 * where getpid() and gettid() sometimes agree and sometimes don't depending
941 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
942 */
943pid_t dvmGetSysThreadId(void)
944{
945#ifdef HAVE_GETTID
946 return gettid();
947#else
948 return getpid();
949#endif
950}
951
952/*
953 * Finish initialization of a Thread struct.
954 *
955 * This must be called while executing in the new thread, but before the
956 * thread is added to the thread list.
957 *
958 * *** NOTE: The threadListLock must be held by the caller (needed for
959 * assignThreadId()).
960 */
961static bool prepareThread(Thread* thread)
962{
963 assignThreadId(thread);
964 thread->handle = pthread_self();
965 thread->systemTid = dvmGetSysThreadId();
966
967 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
968 // (int) getpid());
969 setThreadSelf(thread);
970
971 LOGV("threadid=%d: interp stack at %p\n",
972 thread->threadId, thread->interpStackStart - thread->interpStackSize);
973
974 /*
975 * Initialize invokeReq.
976 */
977 pthread_mutex_init(&thread->invokeReq.lock, NULL);
978 pthread_cond_init(&thread->invokeReq.cv, NULL);
979
980 /*
981 * Initialize our reference tracking tables.
982 *
983 * The JNI local ref table *must* be fixed-size because we keep pointers
984 * into the table in our stack frames.
985 *
986 * Most threads won't use jniMonitorRefTable, so we clear out the
987 * structure but don't call the init function (which allocs storage).
988 */
989 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
990 kJniLocalRefMax, kJniLocalRefMax))
991 return false;
992 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
993 kInternalRefDefault, kInternalRefMax))
994 return false;
995
996 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
997
998 return true;
999}
1000
1001/*
1002 * Remove a thread from the internal list.
1003 * Clear out the links to make it obvious that the thread is
1004 * no longer on the list. Caller must hold gDvm.threadListLock.
1005 */
1006static void unlinkThread(Thread* thread)
1007{
1008 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1009 if (thread == gDvm.threadList) {
1010 assert(thread->prev == NULL);
1011 gDvm.threadList = thread->next;
1012 } else {
1013 assert(thread->prev != NULL);
1014 thread->prev->next = thread->next;
1015 }
1016 if (thread->next != NULL)
1017 thread->next->prev = thread->prev;
1018 thread->prev = thread->next = NULL;
1019}
1020
1021/*
1022 * Free a Thread struct, and all the stuff allocated within.
1023 */
1024static void freeThread(Thread* thread)
1025{
1026 if (thread == NULL)
1027 return;
1028
1029 /* thread->threadId is zero at this point */
1030 LOGVV("threadid=%d: freeing\n", thread->threadId);
1031
1032 if (thread->interpStackStart != NULL) {
1033 u1* interpStackBottom;
1034
1035 interpStackBottom = thread->interpStackStart;
1036 interpStackBottom -= thread->interpStackSize;
1037#ifdef MALLOC_INTERP_STACK
1038 free(interpStackBottom);
1039#else
1040 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1041 LOGW("munmap(thread stack) failed\n");
1042#endif
1043 }
1044
1045 dvmClearReferenceTable(&thread->jniLocalRefTable);
1046 dvmClearReferenceTable(&thread->internalLocalRefTable);
1047 if (&thread->jniMonitorRefTable.table != NULL)
1048 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1049
1050 free(thread);
1051}
1052
1053/*
1054 * Like pthread_self(), but on a Thread*.
1055 */
1056Thread* dvmThreadSelf(void)
1057{
1058 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1059}
1060
1061/*
1062 * Explore our sense of self. Stuffs the thread pointer into TLS.
1063 */
1064static void setThreadSelf(Thread* thread)
1065{
1066 int cc;
1067
1068 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1069 if (cc != 0) {
1070 /*
1071 * Sometimes this fails under Bionic with EINVAL during shutdown.
1072 * This can happen if the timing is just right, e.g. a thread
1073 * fails to attach during shutdown, but the "fail" path calls
1074 * here to ensure we clean up after ourselves.
1075 */
1076 if (thread != NULL) {
1077 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1078 dvmAbort(); /* the world is fundamentally hosed */
1079 }
1080 }
1081}
1082
1083/*
1084 * This is associated with the pthreadKeySelf key. It's called by the
1085 * pthread library when a thread is exiting and the "self" pointer in TLS
1086 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
1087 * operation this should never be called.
1088 *
1089 * This is mainly of use to ensure that we don't leak resources if, for
1090 * example, a thread attaches itself to us with AttachCurrentThread and
1091 * then exits without notifying the VM.
Andy McFadden34e25bb2009-04-15 13:27:12 -07001092 *
1093 * We could do the detach here instead of aborting, but this will lead to
1094 * portability problems. Other implementations do not do this check and
1095 * will simply be unaware that the thread has exited, leading to resource
1096 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1097 * VM tries to shut down).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001098 */
1099static void threadExitCheck(void* arg)
1100{
1101 Thread* thread = (Thread*) arg;
1102
1103 LOGI("In threadExitCheck %p\n", arg);
1104 assert(thread != NULL);
1105
1106 if (thread->status != THREAD_ZOMBIE) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001107 LOGE("Native thread exited without telling us\n");
1108 dvmAbort();
1109 }
1110}
1111
1112
1113/*
1114 * Assign the threadId. This needs to be a small integer so that our
1115 * "thin" locks fit in a small number of bits.
1116 *
1117 * We reserve zero for use as an invalid ID.
1118 *
1119 * This must be called with threadListLock held (unless we're still
1120 * initializing the system).
1121 */
1122static void assignThreadId(Thread* thread)
1123{
1124 /* Find a small unique integer. threadIdMap is a vector of
1125 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1126 * bit, meaning that it will always be < kMaxThreadId.
1127 *
1128 * The thin locking magic requires that the low bit is always
1129 * set, so we do it once, here.
1130 */
1131 int num = dvmAllocBit(gDvm.threadIdMap);
1132 if (num < 0) {
1133 LOGE("Ran out of thread IDs\n");
1134 dvmAbort(); // TODO: make this a non-fatal error result
1135 }
1136
1137 thread->threadId = ((num + 1) << 1) | 1;
1138
1139 assert(thread->threadId != 0);
1140 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1141}
1142
1143/*
1144 * Give back the thread ID.
1145 */
1146static void releaseThreadId(Thread* thread)
1147{
1148 assert(thread->threadId > 0);
1149 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1150 thread->threadId = 0;
1151}
1152
1153
1154/*
1155 * Add a stack frame that makes it look like the native code in the main
1156 * thread was originally invoked from interpreted code. This gives us a
1157 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1158 * VM begins by executing "main" in a class, so in a way this brings us
1159 * closer to the spec.
1160 */
1161static bool createFakeEntryFrame(Thread* thread)
1162{
1163 assert(thread->threadId == kMainThreadId); // main thread only
1164
1165 /* find the method on first use */
1166 if (gDvm.methFakeNativeEntry == NULL) {
1167 ClassObject* nativeStart;
1168 Method* mainMeth;
1169
1170 nativeStart = dvmFindSystemClassNoInit(
1171 "Ldalvik/system/NativeStart;");
1172 if (nativeStart == NULL) {
1173 LOGE("Unable to find dalvik.system.NativeStart class\n");
1174 return false;
1175 }
1176
1177 /*
1178 * Because we are creating a frame that represents application code, we
1179 * want to stuff the application class loader into the method's class
1180 * loader field, even though we're using the system class loader to
1181 * load it. This makes life easier over in JNI FindClass (though it
1182 * could bite us in other ways).
1183 *
1184 * Unfortunately this is occurring too early in the initialization,
1185 * of necessity coming before JNI is initialized, and we're not quite
1186 * ready to set up the application class loader.
1187 *
1188 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1189 * and check it in FindClass. The method is private so nobody else
1190 * can call it.
1191 */
1192 //nativeStart->classLoader = dvmGetSystemClassLoader();
1193
1194 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1195 "main", "([Ljava/lang/String;)V");
1196 if (mainMeth == NULL) {
1197 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1198 return false;
1199 }
1200
1201 gDvm.methFakeNativeEntry = mainMeth;
1202 }
1203
1204 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1205}
1206
1207
1208/*
1209 * Add a stack frame that makes it look like the native thread has been
1210 * executing interpreted code. This gives us a place to hang JNI local
1211 * references.
1212 */
1213static bool createFakeRunFrame(Thread* thread)
1214{
1215 ClassObject* nativeStart;
1216 Method* runMeth;
1217
1218 assert(thread->threadId != 1); // not for main thread
1219
1220 nativeStart =
1221 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1222 if (nativeStart == NULL) {
1223 LOGE("Unable to find dalvik.system.NativeStart class\n");
1224 return false;
1225 }
1226
1227 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1228 if (runMeth == NULL) {
1229 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1230 return false;
1231 }
1232
1233 return dvmPushJNIFrame(thread, runMeth);
1234}
1235
1236/*
1237 * Helper function to set the name of the current thread
1238 */
1239static void setThreadName(const char *threadName)
1240{
1241#if defined(HAVE_PRCTL)
1242 int hasAt = 0;
1243 int hasDot = 0;
1244 const char *s = threadName;
1245 while (*s) {
1246 if (*s == '.') hasDot = 1;
1247 else if (*s == '@') hasAt = 1;
1248 s++;
1249 }
1250 int len = s - threadName;
1251 if (len < 15 || hasAt || !hasDot) {
1252 s = threadName;
1253 } else {
1254 s = threadName + len - 15;
1255 }
1256 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1257#endif
1258}
1259
1260/*
1261 * Create a thread as a result of java.lang.Thread.start().
1262 *
1263 * We do have to worry about some concurrency problems, e.g. programs
1264 * that try to call Thread.start() on the same object from multiple threads.
1265 * (This will fail for all but one, but we have to make sure that it succeeds
1266 * for exactly one.)
1267 *
1268 * Some of the complexity here arises from our desire to mimic the
1269 * Thread vs. VMThread class decomposition we inherited. We've been given
1270 * a Thread, and now we need to create a VMThread and then populate both
1271 * objects. We also need to create one of our internal Thread objects.
1272 *
1273 * Pass in a stack size of 0 to get the default.
1274 */
1275bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1276{
1277 pthread_attr_t threadAttr;
1278 pthread_t threadHandle;
1279 Thread* self;
1280 Thread* newThread = NULL;
1281 Object* vmThreadObj = NULL;
1282 int stackSize;
1283
1284 assert(threadObj != NULL);
1285
1286 if(gDvm.zygote) {
1287 dvmThrowException("Ljava/lang/IllegalStateException;",
1288 "No new threads in -Xzygote mode");
1289
1290 goto fail;
1291 }
1292
1293 self = dvmThreadSelf();
1294 if (reqStackSize == 0)
1295 stackSize = gDvm.stackSize;
1296 else if (reqStackSize < kMinStackSize)
1297 stackSize = kMinStackSize;
1298 else if (reqStackSize > kMaxStackSize)
1299 stackSize = kMaxStackSize;
1300 else
1301 stackSize = reqStackSize;
1302
1303 pthread_attr_init(&threadAttr);
1304 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1305
1306 /*
1307 * To minimize the time spent in the critical section, we allocate the
1308 * vmThread object here.
1309 */
1310 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1311 if (vmThreadObj == NULL)
1312 goto fail;
1313
1314 newThread = allocThread(stackSize);
1315 if (newThread == NULL)
1316 goto fail;
1317 newThread->threadObj = threadObj;
1318
1319 assert(newThread->status == THREAD_INITIALIZING);
1320
1321 /*
1322 * We need to lock out other threads while we test and set the
1323 * "vmThread" field in java.lang.Thread, because we use that to determine
1324 * if this thread has been started before. We use the thread list lock
1325 * because it's handy and we're going to need to grab it again soon
1326 * anyway.
1327 */
1328 dvmLockThreadList(self);
1329
1330 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1331 dvmUnlockThreadList();
1332 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1333 "thread has already been started");
1334 goto fail;
1335 }
1336
1337 /*
1338 * There are actually three data structures: Thread (object), VMThread
1339 * (object), and Thread (C struct). All of them point to at least one
1340 * other.
1341 *
1342 * As soon as "VMThread.vmData" is assigned, other threads can start
1343 * making calls into us (e.g. setPriority).
1344 */
1345 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1346 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1347
1348 /*
1349 * Thread creation might take a while, so release the lock.
1350 */
1351 dvmUnlockThreadList();
1352
Andy McFadden2aa43612009-06-17 16:29:30 -07001353 int cc, oldStatus;
1354 oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1355 cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1356 newThread);
1357 oldStatus = dvmChangeStatus(self, oldStatus);
1358
1359 if (cc != 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001360 /*
1361 * Failure generally indicates that we have exceeded system
1362 * resource limits. VirtualMachineError is probably too severe,
1363 * so use OutOfMemoryError.
1364 */
1365 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1366
1367 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1368
1369 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1370 "thread creation failed");
1371 goto fail;
1372 }
1373
1374 /*
1375 * We need to wait for the thread to start. Otherwise, depending on
1376 * the whims of the OS scheduler, we could return and the code in our
1377 * thread could try to do operations on the new thread before it had
1378 * finished starting.
1379 *
1380 * The new thread will lock the thread list, change its state to
1381 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1382 * on gDvm.threadStartCond (which uses the thread list lock). This
1383 * thread (the parent) will either see that the thread is already ready
1384 * after we grab the thread list lock, or will be awakened from the
1385 * condition variable on the broadcast.
1386 *
1387 * We don't want to stall the rest of the VM while the new thread
1388 * starts, which can happen if the GC wakes up at the wrong moment.
1389 * So, we change our own status to VMWAIT, and self-suspend if
1390 * necessary after we finish adding the new thread.
1391 *
1392 *
1393 * We have to deal with an odd race with the GC/debugger suspension
1394 * mechanism when creating a new thread. The information about whether
1395 * or not a thread should be suspended is contained entirely within
1396 * the Thread struct; this is usually cleaner to deal with than having
1397 * one or more globally-visible suspension flags. The trouble is that
1398 * we could create the thread while the VM is trying to suspend all
1399 * threads. The suspend-count won't be nonzero for the new thread,
1400 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1401 *
1402 * The easiest way to deal with this is to prevent the new thread from
1403 * running until the parent says it's okay. This results in the
Andy McFadden2aa43612009-06-17 16:29:30 -07001404 * following (correct) sequence of events for a "badly timed" GC
1405 * (where '-' is us, 'o' is the child, and '+' is some other thread):
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001406 *
1407 * - call pthread_create()
1408 * - lock thread list
1409 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1410 * - sleep on condition var (mutex = thread list lock) until child starts
1411 * + GC triggered by another thread
1412 * + thread list locked; suspend counts updated; thread list unlocked
1413 * + loop waiting for all runnable threads to suspend
1414 * + success, start GC
1415 * o child thread wakes, signals condition var to wake parent
1416 * o child waits for parent ack on condition variable
1417 * - we wake up, locking thread list
1418 * - add child to thread list
1419 * - unlock thread list
1420 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1421 * + GC finishes; all threads in thread list are resumed
1422 * - lock thread list
1423 * - set child to THREAD_VMWAIT, and signal it to start
1424 * - unlock thread list
1425 * o child resumes
1426 * o child changes state to THREAD_RUNNING
1427 *
1428 * The above shows the GC starting up during thread creation, but if
1429 * it starts anywhere after VMThread.create() is called it will
1430 * produce the same series of events.
1431 *
1432 * Once the child is in the thread list, it will be suspended and
1433 * resumed like any other thread. In the above scenario the resume-all
1434 * code will try to resume the new thread, which was never actually
1435 * suspended, and try to decrement the child's thread suspend count to -1.
1436 * We can catch this in the resume-all code.
1437 *
1438 * Bouncing back and forth between threads like this adds a small amount
1439 * of scheduler overhead to thread startup.
1440 *
1441 * One alternative to having the child wait for the parent would be
1442 * to have the child inherit the parents' suspension count. This
1443 * would work for a GC, since we can safely assume that the parent
1444 * thread didn't cause it, but we must only do so if the parent suspension
1445 * was caused by a suspend-all. If the parent was being asked to
1446 * suspend singly by the debugger, the child should not inherit the value.
1447 *
1448 * We could also have a global "new thread suspend count" that gets
1449 * picked up by new threads before changing state to THREAD_RUNNING.
1450 * This would be protected by the thread list lock and set by a
1451 * suspend-all.
1452 */
1453 dvmLockThreadList(self);
1454 assert(self->status == THREAD_RUNNING);
1455 self->status = THREAD_VMWAIT;
1456 while (newThread->status != THREAD_STARTING)
1457 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1458
1459 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1460 newThread->next = gDvm.threadList->next;
1461 if (newThread->next != NULL)
1462 newThread->next->prev = newThread;
1463 newThread->prev = gDvm.threadList;
1464 gDvm.threadList->next = newThread;
1465
1466 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1467 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1468
1469 dvmUnlockThreadList();
1470
1471 /* change status back to RUNNING, self-suspending if necessary */
1472 dvmChangeStatus(self, THREAD_RUNNING);
1473
1474 /*
1475 * Tell the new thread to start.
1476 *
1477 * We must hold the thread list lock before messing with another thread.
1478 * In the general case we would also need to verify that newThread was
1479 * still in the thread list, but in our case the thread has not started
1480 * executing user code and therefore has not had a chance to exit.
1481 *
1482 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1483 * comes with a suspend-pending check.
1484 */
1485 dvmLockThreadList(self);
1486
1487 assert(newThread->status == THREAD_STARTING);
1488 newThread->status = THREAD_VMWAIT;
1489 pthread_cond_broadcast(&gDvm.threadStartCond);
1490
1491 dvmUnlockThreadList();
1492
1493 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1494 return true;
1495
1496fail:
1497 freeThread(newThread);
1498 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1499 return false;
1500}
1501
1502/*
1503 * pthread entry function for threads started from interpreted code.
1504 */
1505static void* interpThreadStart(void* arg)
1506{
1507 Thread* self = (Thread*) arg;
1508
1509 char *threadName = dvmGetThreadName(self);
1510 setThreadName(threadName);
1511 free(threadName);
1512
1513 /*
1514 * Finish initializing the Thread struct.
1515 */
1516 prepareThread(self);
1517
1518 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1519
1520 /*
1521 * Change our status and wake our parent, who will add us to the
1522 * thread list and advance our state to VMWAIT.
1523 */
1524 dvmLockThreadList(self);
1525 self->status = THREAD_STARTING;
1526 pthread_cond_broadcast(&gDvm.threadStartCond);
1527
1528 /*
1529 * Wait until the parent says we can go. Assuming there wasn't a
1530 * suspend pending, this will happen immediately. When it completes,
1531 * we're full-fledged citizens of the VM.
1532 *
1533 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1534 * because the pthread_cond_wait below needs to reacquire a lock that
1535 * suspend-all is also interested in. If we get unlucky, the parent could
1536 * change us to THREAD_RUNNING, then a GC could start before we get
1537 * signaled, and suspend-all will grab the thread list lock and then
1538 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1539 * trying to get the lock.
1540 */
1541 while (self->status != THREAD_VMWAIT)
1542 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1543
1544 dvmUnlockThreadList();
1545
1546 /*
1547 * Add a JNI context.
1548 */
1549 self->jniEnv = dvmCreateJNIEnv(self);
1550
1551 /*
1552 * Change our state so the GC will wait for us from now on. If a GC is
1553 * in progress this call will suspend us.
1554 */
1555 dvmChangeStatus(self, THREAD_RUNNING);
1556
1557 /*
1558 * Notify the debugger & DDM. The debugger notification may cause
1559 * us to suspend ourselves (and others).
1560 */
1561 if (gDvm.debuggerConnected)
1562 dvmDbgPostThreadStart(self);
1563
1564 /*
1565 * Set the system thread priority according to the Thread object's
1566 * priority level. We don't usually need to do this, because both the
1567 * Thread object and system thread priorities inherit from parents. The
1568 * tricky case is when somebody creates a Thread object, calls
1569 * setPriority(), and then starts the thread. We could manage this with
1570 * a "needs priority update" flag to avoid the redundant call.
1571 */
Andy McFadden4879df92009-08-07 14:49:40 -07001572 int priority = dvmGetFieldInt(self->threadObj,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001573 gDvm.offJavaLangThread_priority);
1574 dvmChangeThreadPriority(self, priority);
1575
1576 /*
1577 * Execute the "run" method.
1578 *
1579 * At this point our stack is empty, so somebody who comes looking for
1580 * stack traces right now won't have much to look at. This is normal.
1581 */
1582 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1583 JValue unused;
1584
1585 LOGV("threadid=%d: calling run()\n", self->threadId);
1586 assert(strcmp(run->name, "run") == 0);
1587 dvmCallMethod(self, run, self->threadObj, &unused);
1588 LOGV("threadid=%d: exiting\n", self->threadId);
1589
1590 /*
1591 * Remove the thread from various lists, report its death, and free
1592 * its resources.
1593 */
1594 dvmDetachCurrentThread();
1595
1596 return NULL;
1597}
1598
1599/*
1600 * The current thread is exiting with an uncaught exception. The
1601 * Java programming language allows the application to provide a
1602 * thread-exit-uncaught-exception handler for the VM, for a specific
1603 * Thread, and for all threads in a ThreadGroup.
1604 *
1605 * Version 1.5 added the per-thread handler. We need to call
1606 * "uncaughtException" in the handler object, which is either the
1607 * ThreadGroup object or the Thread-specific handler.
1608 */
1609static void threadExitUncaughtException(Thread* self, Object* group)
1610{
1611 Object* exception;
1612 Object* handlerObj;
1613 ClassObject* throwable;
1614 Method* uncaughtHandler = NULL;
1615 InstField* threadHandler;
1616
1617 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1618 self->threadId, group);
1619 assert(group != NULL);
1620
1621 /*
1622 * Get a pointer to the exception, then clear out the one in the
1623 * thread. We don't want to have it set when executing interpreted code.
1624 */
1625 exception = dvmGetException(self);
1626 dvmAddTrackedAlloc(exception, self);
1627 dvmClearException(self);
1628
1629 /*
1630 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1631 * else use "group" (which is an instance of UncaughtExceptionHandler).
1632 */
1633 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1634 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1635 if (threadHandler == NULL) {
1636 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1637 goto bail;
1638 }
1639 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1640 if (handlerObj == NULL)
1641 handlerObj = group;
1642
1643 /*
1644 * Find the "uncaughtHandler" field in this object.
1645 */
1646 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1647 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1648
1649 if (uncaughtHandler != NULL) {
1650 //LOGI("+++ calling %s.uncaughtException\n",
1651 // handlerObj->clazz->descriptor);
1652 JValue unused;
1653 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1654 self->threadObj, exception);
1655 } else {
1656 /* restore it and dump a stack trace */
1657 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1658 handlerObj->clazz->descriptor);
1659 dvmSetException(self, exception);
1660 dvmLogExceptionStackTrace();
1661 }
1662
1663bail:
Bill Buzbee46cd5b62009-06-05 15:36:06 -07001664#if defined(WITH_JIT)
1665 /* Remove this thread's suspendCount from global suspendCount sum */
1666 lockThreadSuspendCount();
1667 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1668 unlockThreadSuspendCount();
1669#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001670 dvmReleaseTrackedAlloc(exception, self);
1671}
1672
1673
1674/*
1675 * Create an internal VM thread, for things like JDWP and finalizers.
1676 *
1677 * The easiest way to do this is create a new thread and then use the
1678 * JNI AttachCurrentThread implementation.
1679 *
1680 * This does not return until after the new thread has begun executing.
1681 */
1682bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1683 InternalThreadStart func, void* funcArg)
1684{
1685 InternalStartArgs* pArgs;
1686 Object* systemGroup;
1687 pthread_attr_t threadAttr;
1688 volatile Thread* newThread = NULL;
1689 volatile int createStatus = 0;
1690
1691 systemGroup = dvmGetSystemThreadGroup();
1692 if (systemGroup == NULL)
1693 return false;
1694
1695 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1696 pArgs->func = func;
1697 pArgs->funcArg = funcArg;
1698 pArgs->name = strdup(name); // storage will be owned by new thread
1699 pArgs->group = systemGroup;
1700 pArgs->isDaemon = true;
1701 pArgs->pThread = &newThread;
1702 pArgs->pCreateStatus = &createStatus;
1703
1704 pthread_attr_init(&threadAttr);
1705 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1706
1707 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1708 pArgs) != 0)
1709 {
1710 LOGE("internal thread creation failed\n");
1711 free(pArgs->name);
1712 free(pArgs);
1713 return false;
1714 }
1715
1716 /*
1717 * Wait for the child to start. This gives us an opportunity to make
1718 * sure that the thread started correctly, and allows our caller to
1719 * assume that the thread has started running.
1720 *
1721 * Because we aren't holding a lock across the thread creation, it's
1722 * possible that the child will already have completed its
1723 * initialization. Because the child only adjusts "createStatus" while
1724 * holding the thread list lock, the initial condition on the "while"
1725 * loop will correctly avoid the wait if this occurs.
1726 *
1727 * It's also possible that we'll have to wait for the thread to finish
1728 * being created, and as part of allocating a Thread object it might
1729 * need to initiate a GC. We switch to VMWAIT while we pause.
1730 */
1731 Thread* self = dvmThreadSelf();
1732 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1733 dvmLockThreadList(self);
1734 while (createStatus == 0)
1735 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1736
1737 if (newThread == NULL) {
1738 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1739 assert(createStatus < 0);
1740 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1741 dvmUnlockThreadList();
1742 dvmChangeStatus(self, oldStatus);
1743 return false;
1744 }
1745
1746 /* thread could be in any state now (except early init states) */
1747 //assert(newThread->status == THREAD_RUNNING);
1748
1749 dvmUnlockThreadList();
1750 dvmChangeStatus(self, oldStatus);
1751
1752 return true;
1753}
1754
1755/*
1756 * pthread entry function for internally-created threads.
1757 *
1758 * We are expected to free "arg" and its contents. If we're a daemon
1759 * thread, and we get cancelled abruptly when the VM shuts down, the
1760 * storage won't be freed. If this becomes a concern we can make a copy
1761 * on the stack.
1762 */
1763static void* internalThreadStart(void* arg)
1764{
1765 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1766 JavaVMAttachArgs jniArgs;
1767
1768 jniArgs.version = JNI_VERSION_1_2;
1769 jniArgs.name = pArgs->name;
1770 jniArgs.group = pArgs->group;
1771
1772 setThreadName(pArgs->name);
1773
1774 /* use local jniArgs as stack top */
1775 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1776 /*
1777 * Tell the parent of our success.
1778 *
1779 * threadListLock is the mutex for threadStartCond.
1780 */
1781 dvmLockThreadList(dvmThreadSelf());
1782 *pArgs->pCreateStatus = 1;
1783 *pArgs->pThread = dvmThreadSelf();
1784 pthread_cond_broadcast(&gDvm.threadStartCond);
1785 dvmUnlockThreadList();
1786
1787 LOG_THREAD("threadid=%d: internal '%s'\n",
1788 dvmThreadSelf()->threadId, pArgs->name);
1789
1790 /* execute */
1791 (*pArgs->func)(pArgs->funcArg);
1792
1793 /* detach ourselves */
1794 dvmDetachCurrentThread();
1795 } else {
1796 /*
1797 * Tell the parent of our failure. We don't have a Thread struct,
1798 * so we can't be suspended, so we don't need to enter a critical
1799 * section.
1800 */
1801 dvmLockThreadList(dvmThreadSelf());
1802 *pArgs->pCreateStatus = -1;
1803 assert(*pArgs->pThread == NULL);
1804 pthread_cond_broadcast(&gDvm.threadStartCond);
1805 dvmUnlockThreadList();
1806
1807 assert(*pArgs->pThread == NULL);
1808 }
1809
1810 free(pArgs->name);
1811 free(pArgs);
1812 return NULL;
1813}
1814
1815/*
1816 * Attach the current thread to the VM.
1817 *
1818 * Used for internally-created threads and JNI's AttachCurrentThread.
1819 */
1820bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1821{
1822 Thread* self = NULL;
1823 Object* threadObj = NULL;
1824 Object* vmThreadObj = NULL;
1825 StringObject* threadNameStr = NULL;
1826 Method* init;
1827 bool ok, ret;
1828
1829 /* establish a basic sense of self */
1830 self = allocThread(gDvm.stackSize);
1831 if (self == NULL)
1832 goto fail;
1833 setThreadSelf(self);
1834
1835 /*
1836 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1837 * because this thread is not yet visible to the VM. We could also
1838 * just grab the GC lock earlier, but that leaves us executing
1839 * interpreted code with the lock held, which is not prudent.
1840 *
1841 * The alloc calls will block if a GC is in progress, so we don't need
1842 * to check for global suspension here.
1843 *
1844 * It's also possible for the allocation calls to *cause* a GC.
1845 */
1846 //BUG: deadlock if a GC happens here during HeapWorker creation
1847 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1848 if (threadObj == NULL)
1849 goto fail;
1850 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1851 if (vmThreadObj == NULL)
1852 goto fail;
1853
1854 self->threadObj = threadObj;
1855 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1856
1857 /*
1858 * Do some java.lang.Thread constructor prep before we lock stuff down.
1859 */
1860 if (pArgs->name != NULL) {
1861 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1862 if (threadNameStr == NULL) {
1863 assert(dvmCheckException(dvmThreadSelf()));
1864 goto fail;
1865 }
1866 }
1867
1868 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1869 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1870 if (init == NULL) {
1871 assert(dvmCheckException(dvmThreadSelf()));
1872 goto fail;
1873 }
1874
1875 /*
1876 * Finish our thread prep. We need to do this before invoking any
1877 * interpreted code. prepareThread() requires that we hold the thread
1878 * list lock.
1879 */
1880 dvmLockThreadList(self);
1881 ok = prepareThread(self);
1882 dvmUnlockThreadList();
1883 if (!ok)
1884 goto fail;
1885
1886 self->jniEnv = dvmCreateJNIEnv(self);
1887 if (self->jniEnv == NULL)
1888 goto fail;
1889
1890 /*
1891 * Create a "fake" JNI frame at the top of the main thread interp stack.
1892 * It isn't really necessary for the internal threads, but it gives
1893 * the debugger something to show. It is essential for the JNI-attached
1894 * threads.
1895 */
1896 if (!createFakeRunFrame(self))
1897 goto fail;
1898
1899 /*
1900 * The native side of the thread is ready; add it to the list.
1901 */
1902 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1903
1904 /* Start off in VMWAIT, because we may be about to block
1905 * on the heap lock, and we don't want any suspensions
1906 * to wait for us.
1907 */
1908 self->status = THREAD_VMWAIT;
1909
1910 /*
1911 * Add ourselves to the thread list. Once we finish here we are
1912 * visible to the debugger and the GC.
1913 */
1914 dvmLockThreadList(self);
1915
1916 self->next = gDvm.threadList->next;
1917 if (self->next != NULL)
1918 self->next->prev = self;
1919 self->prev = gDvm.threadList;
1920 gDvm.threadList->next = self;
1921 if (!isDaemon)
1922 gDvm.nonDaemonThreadCount++;
1923
1924 dvmUnlockThreadList();
1925
1926 /*
1927 * It's possible that a GC is currently running. Our thread
1928 * wasn't in the list when the GC started, so it's not properly
1929 * suspended in that case. Synchronize on the heap lock (held
1930 * when a GC is happening) to guarantee that any GCs from here
1931 * on will see this thread in the list.
1932 */
1933 dvmLockMutex(&gDvm.gcHeapLock);
1934 dvmUnlockMutex(&gDvm.gcHeapLock);
1935
1936 /*
1937 * Switch to the running state now that we're ready for
1938 * suspensions. This call may suspend.
1939 */
1940 dvmChangeStatus(self, THREAD_RUNNING);
1941
1942 /*
1943 * Now we're ready to run some interpreted code.
1944 *
1945 * We need to construct the Thread object and set the VMThread field.
1946 * Setting VMThread tells interpreted code that we're alive.
1947 *
1948 * Call the (group, name, priority, daemon) constructor on the Thread.
1949 * This sets the thread's name and adds it to the specified group, and
1950 * provides values for priority and daemon (which are normally inherited
1951 * from the current thread).
1952 */
1953 JValue unused;
1954 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
1955 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
1956 if (dvmCheckException(self)) {
1957 LOGE("exception thrown while constructing attached thread object\n");
1958 goto fail_unlink;
1959 }
1960 //if (isDaemon)
1961 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
1962
1963 /*
1964 * Set the VMThread field, which tells interpreted code that we're alive.
1965 *
1966 * The risk of a thread start collision here is very low; somebody
1967 * would have to be deliberately polling the ThreadGroup list and
1968 * trying to start threads against anything it sees, which would
1969 * generally cause problems for all thread creation. However, for
1970 * correctness we test "vmThread" before setting it.
1971 */
1972 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1973 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1974 "thread has already been started");
1975 /* We don't want to free anything associated with the thread
1976 * because someone is obviously interested in it. Just let
1977 * it go and hope it will clean itself up when its finished.
1978 * This case should never happen anyway.
1979 *
1980 * Since we're letting it live, we need to finish setting it up.
1981 * We just have to let the caller know that the intended operation
1982 * has failed.
1983 *
1984 * [ This seems strange -- stepping on the vmThread object that's
1985 * already present seems like a bad idea. TODO: figure this out. ]
1986 */
1987 ret = false;
1988 } else
1989 ret = true;
1990 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1991
1992 /* These are now reachable from the thread groups. */
1993 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
1994 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
1995
1996 /*
1997 * The thread is ready to go; let the debugger see it.
1998 */
1999 self->threadObj = threadObj;
2000
2001 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2002 self->threadId, pArgs->name);
2003
2004 /* tell the debugger & DDM */
2005 if (gDvm.debuggerConnected)
2006 dvmDbgPostThreadStart(self);
2007
2008 return ret;
2009
2010fail_unlink:
2011 dvmLockThreadList(self);
2012 unlinkThread(self);
2013 if (!isDaemon)
2014 gDvm.nonDaemonThreadCount--;
2015 dvmUnlockThreadList();
2016 /* fall through to "fail" */
2017fail:
2018 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2019 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2020 if (self != NULL) {
2021 if (self->jniEnv != NULL) {
2022 dvmDestroyJNIEnv(self->jniEnv);
2023 self->jniEnv = NULL;
2024 }
2025 freeThread(self);
2026 }
2027 setThreadSelf(NULL);
2028 return false;
2029}
2030
2031/*
2032 * Detach the thread from the various data structures, notify other threads
2033 * that are waiting to "join" it, and free up all heap-allocated storage.
2034 *
2035 * Used for all threads.
2036 *
2037 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2038 * requires us to enforce this for the DetachCurrentThread call, probably
2039 * because it also says that DetachCurrentThread causes all monitors
2040 * associated with the thread to be released. (Because the stack is empty,
2041 * we only have to worry about explicit JNI calls to MonitorEnter.)
2042 *
2043 * THOUGHT:
2044 * We might want to avoid freeing our internal Thread structure until the
2045 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2046 * get to once the thread shuts down, but there is a small possibility of
2047 * an operation starting in another thread before this thread halts, and
2048 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2049 * We don't want something like Thread.isInterrupted() crawling through
2050 * freed storage. Can do with a Thread finalizer, or by creating a
2051 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2052 * state into that.
2053 */
2054void dvmDetachCurrentThread(void)
2055{
2056 Thread* self = dvmThreadSelf();
2057 Object* vmThread;
2058 Object* group;
2059
2060 /*
2061 * Make sure we're not detaching a thread that's still running. (This
2062 * could happen with an explicit JNI detach call.)
2063 *
2064 * A thread created by interpreted code will finish with a depth of
2065 * zero, while a JNI-attached thread will have the synthetic "stack
2066 * starter" native method at the top.
2067 */
2068 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2069 if (curDepth != 0) {
2070 bool topIsNative = false;
2071
2072 if (curDepth == 1) {
2073 /* not expecting a lingering break frame; just look at curFrame */
2074 assert(!dvmIsBreakFrame(self->curFrame));
2075 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2076 if (dvmIsNativeMethod(ssa->method))
2077 topIsNative = true;
2078 }
2079
2080 if (!topIsNative) {
2081 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2082 curDepth);
2083 dvmDumpThread(self, false);
2084 dvmAbort();
2085 }
2086 }
2087
2088 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2089 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2090
2091 /*
2092 * Release any held monitors. Since there are no interpreted stack
2093 * frames, the only thing left are the monitors held by JNI MonitorEnter
2094 * calls.
2095 */
2096 dvmReleaseJniMonitors(self);
2097
2098 /*
2099 * Do some thread-exit uncaught exception processing if necessary.
2100 */
2101 if (dvmCheckException(self))
2102 threadExitUncaughtException(self, group);
2103
2104 /*
2105 * Remove the thread from the thread group.
2106 */
2107 if (group != NULL) {
2108 Method* removeThread =
2109 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2110 JValue unused;
2111 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2112 }
2113
2114 /*
2115 * Clear the vmThread reference in the Thread object. Interpreted code
2116 * will now see that this Thread is not running. As this may be the
2117 * only reference to the VMThread object that the VM knows about, we
2118 * have to create an internal reference to it first.
2119 */
2120 vmThread = dvmGetFieldObject(self->threadObj,
2121 gDvm.offJavaLangThread_vmThread);
2122 dvmAddTrackedAlloc(vmThread, self);
2123 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2124
2125 /* clear out our struct Thread pointer, since it's going away */
2126 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2127
2128 /*
2129 * Tell the debugger & DDM. This may cause the current thread or all
2130 * threads to suspend.
2131 *
2132 * The JDWP spec is somewhat vague about when this happens, other than
2133 * that it's issued by the dying thread, which may still appear in
2134 * an "all threads" listing.
2135 */
2136 if (gDvm.debuggerConnected)
2137 dvmDbgPostThreadDeath(self);
2138
2139 /*
2140 * Thread.join() is implemented as an Object.wait() on the VMThread
2141 * object. Signal anyone who is waiting.
2142 */
2143 dvmLockObject(self, vmThread);
2144 dvmObjectNotifyAll(self, vmThread);
2145 dvmUnlockObject(self, vmThread);
2146
2147 dvmReleaseTrackedAlloc(vmThread, self);
2148 vmThread = NULL;
2149
2150 /*
2151 * We're done manipulating objects, so it's okay if the GC runs in
2152 * parallel with us from here out. It's important to do this if
2153 * profiling is enabled, since we can wait indefinitely.
2154 */
2155 self->status = THREAD_VMWAIT;
2156
2157#ifdef WITH_PROFILER
2158 /*
2159 * If we're doing method trace profiling, we don't want threads to exit,
2160 * because if they do we'll end up reusing thread IDs. This complicates
2161 * analysis and makes it impossible to have reasonable output in the
2162 * "threads" section of the "key" file.
2163 *
2164 * We need to do this after Thread.join() completes, or other threads
2165 * could get wedged. Since self->threadObj is still valid, the Thread
2166 * object will not get GCed even though we're no longer in the ThreadGroup
2167 * list (which is important since the profiling thread needs to get
2168 * the thread's name).
2169 */
2170 MethodTraceState* traceState = &gDvm.methodTrace;
2171
2172 dvmLockMutex(&traceState->startStopLock);
2173 if (traceState->traceEnabled) {
2174 LOGI("threadid=%d: waiting for method trace to finish\n",
2175 self->threadId);
2176 while (traceState->traceEnabled) {
2177 int cc;
2178 cc = pthread_cond_wait(&traceState->threadExitCond,
2179 &traceState->startStopLock);
2180 assert(cc == 0);
2181 }
2182 }
2183 dvmUnlockMutex(&traceState->startStopLock);
2184#endif
2185
2186 dvmLockThreadList(self);
2187
2188 /*
2189 * Lose the JNI context.
2190 */
2191 dvmDestroyJNIEnv(self->jniEnv);
2192 self->jniEnv = NULL;
2193
2194 self->status = THREAD_ZOMBIE;
2195
2196 /*
2197 * Remove ourselves from the internal thread list.
2198 */
2199 unlinkThread(self);
2200
2201 /*
2202 * If we're the last one standing, signal anybody waiting in
2203 * DestroyJavaVM that it's okay to exit.
2204 */
2205 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2206 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2207
2208 if (gDvm.nonDaemonThreadCount == 0) {
2209 int cc;
2210
2211 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2212 //dvmDumpAllThreads(false);
2213 // cond var guarded by threadListLock, which we already hold
2214 cc = pthread_cond_signal(&gDvm.vmExitCond);
2215 assert(cc == 0);
2216 }
2217 }
2218
2219 LOGV("threadid=%d: bye!\n", self->threadId);
2220 releaseThreadId(self);
2221 dvmUnlockThreadList();
2222
2223 setThreadSelf(NULL);
2224 freeThread(self);
2225}
2226
2227
2228/*
2229 * Suspend a single thread. Do not use to suspend yourself.
2230 *
2231 * This is used primarily for debugger/DDMS activity. Does not return
2232 * until the thread has suspended or is in a "safe" state (e.g. executing
2233 * native code outside the VM).
2234 *
2235 * The thread list lock should be held before calling here -- it's not
2236 * entirely safe to hang on to a Thread* from another thread otherwise.
2237 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2238 */
2239void dvmSuspendThread(Thread* thread)
2240{
2241 assert(thread != NULL);
2242 assert(thread != dvmThreadSelf());
2243 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2244
2245 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002246 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002247 thread->dbgSuspendCount++;
2248
2249 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2250 thread->threadId, thread->suspendCount);
2251 unlockThreadSuspendCount();
2252
2253 waitForThreadSuspend(dvmThreadSelf(), thread);
2254}
2255
2256/*
2257 * Reduce the suspend count of a thread. If it hits zero, tell it to
2258 * resume.
2259 *
2260 * Used primarily for debugger/DDMS activity. The thread in question
2261 * might have been suspended singly or as part of a suspend-all operation.
2262 *
2263 * The thread list lock should be held before calling here -- it's not
2264 * entirely safe to hang on to a Thread* from another thread otherwise.
2265 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2266 */
2267void dvmResumeThread(Thread* thread)
2268{
2269 assert(thread != NULL);
2270 assert(thread != dvmThreadSelf());
2271 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2272
2273 lockThreadSuspendCount();
2274 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002275 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002276 thread->dbgSuspendCount--;
2277 } else {
2278 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2279 thread->threadId);
2280 }
2281
2282 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2283 thread->threadId, thread->suspendCount);
2284
2285 if (thread->suspendCount == 0) {
2286 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2287 assert(cc == 0);
2288 }
2289
2290 unlockThreadSuspendCount();
2291}
2292
2293/*
2294 * Suspend yourself, as a result of debugger activity.
2295 */
2296void dvmSuspendSelf(bool jdwpActivity)
2297{
2298 Thread* self = dvmThreadSelf();
2299
2300 /* debugger thread may not suspend itself due to debugger activity! */
2301 assert(gDvm.jdwpState != NULL);
2302 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2303 assert(false);
2304 return;
2305 }
2306
2307 /*
2308 * Collisions with other suspends aren't really interesting. We want
2309 * to ensure that we're the only one fiddling with the suspend count
2310 * though.
2311 */
2312 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002313 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002314 self->dbgSuspendCount++;
2315
2316 /*
2317 * Suspend ourselves.
2318 */
2319 assert(self->suspendCount > 0);
2320 self->isSuspended = true;
2321 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2322
2323 /*
2324 * Tell JDWP that we've completed suspension. The JDWP thread can't
2325 * tell us to resume before we're fully asleep because we hold the
2326 * suspend count lock.
2327 *
2328 * If we got here via waitForDebugger(), don't do this part.
2329 */
2330 if (jdwpActivity) {
2331 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2332 // self->threadId, (int) self->handle);
2333 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2334 }
2335
2336 while (self->suspendCount != 0) {
2337 int cc;
2338 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2339 &gDvm.threadSuspendCountLock);
2340 assert(cc == 0);
2341 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002342 /*
2343 * The condition was signaled but we're still suspended. This
2344 * can happen if the debugger lets go while a SIGQUIT thread
2345 * dump event is pending (assuming SignalCatcher was resumed for
2346 * just long enough to try to grab the thread-suspend lock).
2347 */
2348 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2349 self->threadId, self->suspendCount, self->dbgSuspendCount,
2350 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002351 }
2352 }
2353 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2354 self->isSuspended = false;
2355 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2356 self->threadId, self->status);
2357
2358 unlockThreadSuspendCount();
2359}
2360
2361
2362#ifdef HAVE_GLIBC
2363# define NUM_FRAMES 20
2364# include <execinfo.h>
2365/*
2366 * glibc-only stack dump function. Requires link with "--export-dynamic".
2367 *
2368 * TODO: move this into libs/cutils and make it work for all platforms.
2369 */
2370static void printBackTrace(void)
2371{
2372 void* array[NUM_FRAMES];
2373 size_t size;
2374 char** strings;
2375 size_t i;
2376
2377 size = backtrace(array, NUM_FRAMES);
2378 strings = backtrace_symbols(array, size);
2379
2380 LOGW("Obtained %zd stack frames.\n", size);
2381
2382 for (i = 0; i < size; i++)
2383 LOGW("%s\n", strings[i]);
2384
2385 free(strings);
2386}
2387#else
2388static void printBackTrace(void) {}
2389#endif
2390
2391/*
2392 * Dump the state of the current thread and that of another thread that
2393 * we think is wedged.
2394 */
2395static void dumpWedgedThread(Thread* thread)
2396{
2397 char exePath[1024];
2398
2399 /*
2400 * The "executablepath" function in libutils is host-side only.
2401 */
2402 strcpy(exePath, "-");
2403#ifdef HAVE_GLIBC
2404 {
2405 char proc[100];
2406 sprintf(proc, "/proc/%d/exe", getpid());
2407 int len;
2408
2409 len = readlink(proc, exePath, sizeof(exePath)-1);
2410 exePath[len] = '\0';
2411 }
2412#endif
2413
2414 LOGW("dumping state: process %s %d\n", exePath, getpid());
2415 dvmDumpThread(dvmThreadSelf(), false);
2416 printBackTrace();
2417
2418 // dumping a running thread is risky, but could be useful
2419 dvmDumpThread(thread, true);
2420
2421
2422 // stop now and get a core dump
2423 //abort();
2424}
2425
2426
2427/*
2428 * Wait for another thread to see the pending suspension and stop running.
2429 * It can either suspend itself or go into a non-running state such as
2430 * VMWAIT or NATIVE in which it cannot interact with the GC.
2431 *
2432 * If we're running at a higher priority, sched_yield() may not do anything,
2433 * so we need to sleep for "long enough" to guarantee that the other
2434 * thread has a chance to finish what it's doing. Sleeping for too short
2435 * a period (e.g. less than the resolution of the sleep clock) might cause
2436 * the scheduler to return immediately, so we want to start with a
2437 * "reasonable" value and expand.
2438 *
2439 * This does not return until the other thread has stopped running.
2440 * Eventually we time out and the VM aborts.
2441 *
2442 * This does not try to detect the situation where two threads are
2443 * waiting for each other to suspend. In normal use this is part of a
2444 * suspend-all, which implies that the suspend-all lock is held, or as
2445 * part of a debugger action in which the JDWP thread is always the one
2446 * doing the suspending. (We may need to re-evaluate this now that
2447 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2448 *
2449 * TODO: track basic stats about time required to suspend VM.
2450 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002451#define FIRST_SLEEP (250*1000) /* 0.25s */
2452#define MORE_SLEEP (750*1000) /* 0.75s */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002453static void waitForThreadSuspend(Thread* self, Thread* thread)
2454{
2455 const int kMaxRetries = 10;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002456 int spinSleepTime = FIRST_SLEEP;
Andy McFadden2aa43612009-06-17 16:29:30 -07002457 bool complained = false;
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002458 bool needPriorityReset = false;
2459 int savedThreadPrio = -500;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002460
2461 int sleepIter = 0;
2462 int retryCount = 0;
2463 u8 startWhen = 0; // init req'd to placate gcc
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002464 u8 firstStartWhen = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002465
2466 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002467 if (sleepIter == 0) { // get current time on first iteration
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002468 startWhen = dvmGetRelativeTimeUsec();
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002469 if (firstStartWhen == 0) // first iteration of first attempt
2470 firstStartWhen = startWhen;
2471
2472 /*
2473 * After waiting for a bit, check to see if the target thread is
2474 * running at a reduced priority. If so, bump it up temporarily
2475 * to give it more CPU time.
2476 *
2477 * getpriority() returns the "nice" value, so larger numbers
2478 * indicate lower priority.
2479 *
2480 * (Not currently changing the cgroup. Wasn't necessary in some
2481 * simple experiments.)
2482 */
2483 if (retryCount == 2) {
2484 assert(thread->systemTid != 0);
2485 errno = 0;
2486 int threadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2487 if (errno == 0 && threadPrio > 0) {
2488 const int kHigher = 0;
2489 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) < 0)
2490 {
2491 LOGW("Couldn't raise priority on tid %d to %d\n",
2492 thread->systemTid, kHigher);
2493 } else {
2494 savedThreadPrio = threadPrio;
2495 needPriorityReset = true;
2496 LOGD("Temporarily raising priority on tid %d (%d -> %d)\n",
2497 thread->systemTid, threadPrio, kHigher);
2498 }
2499 }
2500 }
2501 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002502
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002503#if defined (WITH_JIT)
2504 /*
2505 * If we're still waiting after the first timeout,
2506 * unchain all translations.
2507 */
2508 if (gDvmJit.pJitEntryTable && retryCount > 0) {
2509 LOGD("JIT unchain all attempt #%d",retryCount);
2510 dvmJitUnchainAll();
2511 }
2512#endif
2513
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002514 /*
2515 * Sleep briefly. This returns false if we've exceeded the total
2516 * time limit for this round of sleeping.
2517 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002518 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002519 LOGW("threadid=%d: spin on suspend #%d threadid=%d (h=%d)\n",
2520 self->threadId, retryCount,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002521 thread->threadId, (int)thread->handle);
2522 dumpWedgedThread(thread);
Andy McFadden2aa43612009-06-17 16:29:30 -07002523 complained = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002524
2525 // keep going; could be slow due to valgrind
2526 sleepIter = 0;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002527 spinSleepTime = MORE_SLEEP;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002528
2529 if (retryCount++ == kMaxRetries) {
2530 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2531 self->threadId, thread->threadId);
2532 dvmDumpAllThreads(false);
2533 dvmAbort();
2534 }
2535 }
2536 }
Andy McFadden2aa43612009-06-17 16:29:30 -07002537
2538 if (complained) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002539 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2540 self->threadId,
2541 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
Andy McFadden2aa43612009-06-17 16:29:30 -07002542 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2543 }
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002544 if (needPriorityReset) {
2545 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) < 0) {
2546 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2547 thread->systemTid, savedThreadPrio);
2548 } else {
2549 LOGV("Restored priority on %d to %d\n",
2550 thread->systemTid, savedThreadPrio);
2551 }
2552 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002553}
2554
2555/*
2556 * Suspend all threads except the current one. This is used by the GC,
2557 * the debugger, and by any thread that hits a "suspend all threads"
2558 * debugger event (e.g. breakpoint or exception).
2559 *
2560 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2561 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2562 * create objects and even execute arbitrary code. The "why" argument
2563 * allows the caller to say why the suspension is taking place.
2564 *
2565 * This can be called when a global suspend has already happened, due to
2566 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2567 * doesn't work.
2568 *
2569 * DO NOT grab any locks before calling here. We grab & release the thread
2570 * lock and suspend lock here (and we're not using recursive threads), and
2571 * we might have to self-suspend if somebody else beats us here.
2572 *
2573 * The current thread may not be attached to the VM. This can happen if
2574 * we happen to GC as the result of an allocation of a Thread object.
2575 */
2576void dvmSuspendAllThreads(SuspendCause why)
2577{
2578 Thread* self = dvmThreadSelf();
2579 Thread* thread;
2580
2581 assert(why != 0);
2582
2583 /*
2584 * Start by grabbing the thread suspend lock. If we can't get it, most
2585 * likely somebody else is in the process of performing a suspend or
2586 * resume, so lockThreadSuspend() will cause us to self-suspend.
2587 *
2588 * We keep the lock until all other threads are suspended.
2589 */
2590 lockThreadSuspend("susp-all", why);
2591
2592 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2593
2594 /*
2595 * This is possible if the current thread was in VMWAIT mode when a
2596 * suspend-all happened, and then decided to do its own suspend-all.
2597 * This can happen when a couple of threads have simultaneous events
2598 * of interest to the debugger.
2599 */
2600 //assert(self->suspendCount == 0);
2601
2602 /*
2603 * Increment everybody's suspend count (except our own).
2604 */
2605 dvmLockThreadList(self);
2606
2607 lockThreadSuspendCount();
2608 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2609 if (thread == self)
2610 continue;
2611
2612 /* debugger events don't suspend JDWP thread */
2613 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2614 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2615 continue;
2616
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002617 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002618 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2619 thread->dbgSuspendCount++;
2620 }
2621 unlockThreadSuspendCount();
2622
2623 /*
2624 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2625 * indicate the code is either running natively or sleeping quietly.
2626 * Any attempt to transition back to THREAD_RUNNING will cause a check
2627 * for suspension, so it should be impossible for anything to execute
2628 * interpreted code or modify objects (assuming native code plays nicely).
2629 *
2630 * It's also okay if the thread transitions to a non-RUNNING state.
2631 *
2632 * Note we released the threadSuspendCountLock before getting here,
2633 * so if another thread is fiddling with its suspend count (perhaps
2634 * self-suspending for the debugger) it won't block while we're waiting
2635 * in here.
2636 */
2637 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2638 if (thread == self)
2639 continue;
2640
2641 /* debugger events don't suspend JDWP thread */
2642 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2643 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2644 continue;
2645
2646 /* wait for the other thread to see the pending suspend */
2647 waitForThreadSuspend(self, thread);
2648
2649 LOG_THREAD("threadid=%d: threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
2650 self->threadId,
2651 thread->threadId, thread->status, thread->suspendCount,
2652 thread->dbgSuspendCount, thread->isSuspended);
2653 }
2654
2655 dvmUnlockThreadList();
2656 unlockThreadSuspend();
2657
2658 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2659}
2660
2661/*
2662 * Resume all threads that are currently suspended.
2663 *
2664 * The "why" must match with the previous suspend.
2665 */
2666void dvmResumeAllThreads(SuspendCause why)
2667{
2668 Thread* self = dvmThreadSelf();
2669 Thread* thread;
2670 int cc;
2671
2672 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2673 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2674
2675 /*
2676 * Decrement the suspend counts for all threads. No need for atomic
2677 * writes, since nobody should be moving until we decrement the count.
2678 * We do need to hold the thread list because of JNI attaches.
2679 */
2680 dvmLockThreadList(self);
2681 lockThreadSuspendCount();
2682 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2683 if (thread == self)
2684 continue;
2685
2686 /* debugger events don't suspend JDWP thread */
2687 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2688 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
Andy McFadden2aa43612009-06-17 16:29:30 -07002689 {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002690 continue;
Andy McFadden2aa43612009-06-17 16:29:30 -07002691 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002692
2693 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002694 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002695 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2696 thread->dbgSuspendCount--;
2697 } else {
2698 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2699 thread->threadId);
2700 }
2701 }
2702 unlockThreadSuspendCount();
2703 dvmUnlockThreadList();
2704
2705 /*
Andy McFadden2aa43612009-06-17 16:29:30 -07002706 * In some ways it makes sense to continue to hold the thread-suspend
2707 * lock while we issue the wakeup broadcast. It allows us to complete
2708 * one operation before moving on to the next, which simplifies the
2709 * thread activity debug traces.
2710 *
2711 * This approach caused us some difficulty under Linux, because the
2712 * condition variable broadcast not only made the threads runnable,
2713 * but actually caused them to execute, and it was a while before
2714 * the thread performing the wakeup had an opportunity to release the
2715 * thread-suspend lock.
2716 *
2717 * This is a problem because, when a thread tries to acquire that
2718 * lock, it times out after 3 seconds. If at some point the thread
2719 * is told to suspend, the clock resets; but since the VM is still
2720 * theoretically mid-resume, there's no suspend pending. If, for
2721 * example, the GC was waking threads up while the SIGQUIT handler
2722 * was trying to acquire the lock, we would occasionally time out on
2723 * a busy system and SignalCatcher would abort.
2724 *
2725 * We now perform the unlock before the wakeup broadcast. The next
2726 * suspend can't actually start until the broadcast completes and
2727 * returns, because we're holding the thread-suspend-count lock, but the
2728 * suspending thread is now able to make progress and we avoid the abort.
2729 *
2730 * (Technically there is a narrow window between when we release
2731 * the thread-suspend lock and grab the thread-suspend-count lock.
2732 * This could cause us to send a broadcast to threads with nonzero
2733 * suspend counts, but this is expected and they'll all just fall
2734 * right back to sleep. It's probably safe to grab the suspend-count
2735 * lock before releasing thread-suspend, since we're still following
2736 * the correct order of acquisition, but it feels weird.)
2737 */
2738
2739 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2740 unlockThreadSuspend();
2741
2742 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002743 * Broadcast a notification to all suspended threads, some or all of
2744 * which may choose to wake up. No need to wait for them.
2745 */
2746 lockThreadSuspendCount();
2747 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2748 assert(cc == 0);
2749 unlockThreadSuspendCount();
2750
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002751 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2752}
2753
2754/*
2755 * Undo any debugger suspensions. This is called when the debugger
2756 * disconnects.
2757 */
2758void dvmUndoDebuggerSuspensions(void)
2759{
2760 Thread* self = dvmThreadSelf();
2761 Thread* thread;
2762 int cc;
2763
2764 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2765 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2766
2767 /*
2768 * Decrement the suspend counts for all threads. No need for atomic
2769 * writes, since nobody should be moving until we decrement the count.
2770 * We do need to hold the thread list because of JNI attaches.
2771 */
2772 dvmLockThreadList(self);
2773 lockThreadSuspendCount();
2774 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2775 if (thread == self)
2776 continue;
2777
2778 /* debugger events don't suspend JDWP thread */
2779 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2780 assert(thread->dbgSuspendCount == 0);
2781 continue;
2782 }
2783
2784 assert(thread->suspendCount >= thread->dbgSuspendCount);
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002785 dvmAddToThreadSuspendCount(&thread->suspendCount,
2786 -thread->dbgSuspendCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002787 thread->dbgSuspendCount = 0;
2788 }
2789 unlockThreadSuspendCount();
2790 dvmUnlockThreadList();
2791
2792 /*
2793 * Broadcast a notification to all suspended threads, some or all of
2794 * which may choose to wake up. No need to wait for them.
2795 */
2796 lockThreadSuspendCount();
2797 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2798 assert(cc == 0);
2799 unlockThreadSuspendCount();
2800
2801 unlockThreadSuspend();
2802
2803 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2804}
2805
2806/*
2807 * Determine if a thread is suspended.
2808 *
2809 * As with all operations on foreign threads, the caller should hold
2810 * the thread list lock before calling.
2811 */
2812bool dvmIsSuspended(Thread* thread)
2813{
2814 /*
2815 * The thread could be:
2816 * (1) Running happily. status is RUNNING, isSuspended is false,
2817 * suspendCount is zero. Return "false".
2818 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2819 * suspendCount is nonzero. Return "false".
2820 * (3) Suspended. suspendCount is nonzero, and either (status is
2821 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2822 * Return "true".
2823 * (4) Waking up. suspendCount is zero, status is RUNNING and
2824 * isSuspended is true. Return "false" (since it could change
2825 * out from under us, unless we hold suspendCountLock).
2826 */
2827
2828 return (thread->suspendCount != 0 &&
2829 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2830 (thread->status != THREAD_RUNNING)));
2831}
2832
2833/*
2834 * Wait until another thread self-suspends. This is specifically for
2835 * synchronization between the JDWP thread and a thread that has decided
2836 * to suspend itself after sending an event to the debugger.
2837 *
2838 * Threads that encounter "suspend all" events work as well -- the thread
2839 * in question suspends everybody else and then itself.
2840 *
2841 * We can't hold a thread lock here or in the caller, because we could
2842 * get here just before the to-be-waited-for-thread issues a "suspend all".
2843 * There's an opportunity for badness if the thread we're waiting for exits
2844 * and gets cleaned up, but since the thread in question is processing a
2845 * debugger event, that's not really a possibility. (To avoid deadlock,
2846 * it's important that we not be in THREAD_RUNNING while we wait.)
2847 */
2848void dvmWaitForSuspend(Thread* thread)
2849{
2850 Thread* self = dvmThreadSelf();
2851
2852 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2853 self->threadId, thread->threadId);
2854
2855 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2856 assert(thread != self);
2857 assert(self->status != THREAD_RUNNING);
2858
2859 waitForThreadSuspend(self, thread);
2860
2861 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2862 self->threadId, thread->threadId);
2863}
2864
2865/*
2866 * Check to see if we need to suspend ourselves. If so, go to sleep on
2867 * a condition variable.
2868 *
2869 * Takes "self" as an argument as an optimization. Pass in NULL to have
2870 * it do the lookup.
2871 *
2872 * Returns "true" if we suspended ourselves.
2873 */
2874bool dvmCheckSuspendPending(Thread* self)
2875{
2876 bool didSuspend;
2877
2878 if (self == NULL)
2879 self = dvmThreadSelf();
2880
2881 /* fast path: if count is zero, bail immediately */
2882 if (self->suspendCount == 0)
2883 return false;
2884
2885 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2886
2887 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2888
2889 didSuspend = (self->suspendCount != 0);
2890 self->isSuspended = true;
2891 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2892 while (self->suspendCount != 0) {
2893 /* wait for wakeup signal; releases lock */
2894 int cc;
2895 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2896 &gDvm.threadSuspendCountLock);
2897 assert(cc == 0);
2898 }
2899 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2900 self->isSuspended = false;
2901 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2902 self->threadId, self->status);
2903
2904 unlockThreadSuspendCount();
2905
2906 return didSuspend;
2907}
2908
2909/*
2910 * Update our status.
2911 *
2912 * The "self" argument, which may be NULL, is accepted as an optimization.
2913 *
2914 * Returns the old status.
2915 */
2916ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
2917{
2918 ThreadStatus oldStatus;
2919
2920 if (self == NULL)
2921 self = dvmThreadSelf();
2922
2923 LOGVV("threadid=%d: (status %d -> %d)\n",
2924 self->threadId, self->status, newStatus);
2925
2926 oldStatus = self->status;
2927
2928 if (newStatus == THREAD_RUNNING) {
2929 /*
2930 * Change our status to THREAD_RUNNING. The transition requires
2931 * that we check for pending suspension, because the VM considers
2932 * us to be "asleep" in all other states.
2933 *
2934 * We need to do the "suspend pending" check FIRST, because it grabs
2935 * a lock that could be held by something that wants us to suspend.
2936 * If we're in RUNNING it will wait for us, and we'll be waiting
2937 * for the lock it holds.
2938 */
2939 assert(self->status != THREAD_RUNNING);
2940
2941 dvmCheckSuspendPending(self);
2942 self->status = THREAD_RUNNING;
2943 } else {
2944 /*
2945 * Change from one state to another, neither of which is
2946 * THREAD_RUNNING. This is most common during system or thread
2947 * initialization.
2948 */
2949 self->status = newStatus;
2950 }
2951
2952 return oldStatus;
2953}
2954
2955/*
2956 * Get a statically defined thread group from a field in the ThreadGroup
2957 * Class object. Expected arguments are "mMain" and "mSystem".
2958 */
2959static Object* getStaticThreadGroup(const char* fieldName)
2960{
2961 StaticField* groupField;
2962 Object* groupObj;
2963
2964 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
2965 fieldName, "Ljava/lang/ThreadGroup;");
2966 if (groupField == NULL) {
2967 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
2968 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
2969 return NULL;
2970 }
2971 groupObj = dvmGetStaticFieldObject(groupField);
2972 if (groupObj == NULL) {
2973 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
2974 dvmThrowException("Ljava/lang/InternalError;", NULL);
2975 return NULL;
2976 }
2977
2978 return groupObj;
2979}
2980Object* dvmGetSystemThreadGroup(void)
2981{
2982 return getStaticThreadGroup("mSystem");
2983}
2984Object* dvmGetMainThreadGroup(void)
2985{
2986 return getStaticThreadGroup("mMain");
2987}
2988
2989/*
2990 * Given a VMThread object, return the associated Thread*.
2991 *
2992 * NOTE: if the thread detaches, the struct Thread will disappear, and
2993 * we will be touching invalid data. For safety, lock the thread list
2994 * before calling this.
2995 */
2996Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
2997{
2998 int vmData;
2999
3000 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
Andy McFadden44860362009-08-06 17:56:14 -07003001
3002 if (false) {
3003 Thread* thread = gDvm.threadList;
3004 while (thread != NULL) {
3005 if ((Thread*)vmData == thread)
3006 break;
3007
3008 thread = thread->next;
3009 }
3010
3011 if (thread == NULL) {
3012 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3013 vmThreadObj, (Thread*)vmData);
3014 vmData = 0;
3015 }
3016 }
3017
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003018 return (Thread*) vmData;
3019}
3020
3021
3022/*
3023 * Conversion map for "nice" values.
3024 *
3025 * We use Android thread priority constants to be consistent with the rest
3026 * of the system. In some cases adjacent entries may overlap.
3027 */
3028static const int kNiceValues[10] = {
3029 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3030 ANDROID_PRIORITY_BACKGROUND + 6,
3031 ANDROID_PRIORITY_BACKGROUND + 3,
3032 ANDROID_PRIORITY_BACKGROUND,
3033 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3034 ANDROID_PRIORITY_NORMAL - 2,
3035 ANDROID_PRIORITY_NORMAL - 4,
3036 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3037 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3038 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3039};
3040
3041/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003042 * Change the scheduler cgroup of the current thread.
3043 *
3044 * Returns 0 on success.
San Mehat256fc152009-04-21 14:03:06 -07003045 */
3046int dvmChangeThreadSchedulerGroup(const char *cgroup)
3047{
3048#ifdef HAVE_ANDROID_OS
Andy McFaddend62c0b52009-08-04 15:02:12 -07003049 int fd;
San Mehat256fc152009-04-21 14:03:06 -07003050 char path[255];
San Mehat256fc152009-04-21 14:03:06 -07003051
Andy McFaddend62c0b52009-08-04 15:02:12 -07003052 snprintf(path, sizeof(path), "/dev/cpuctl/%s/tasks", (cgroup ? cgroup :""));
San Mehat256fc152009-04-21 14:03:06 -07003053
Andy McFaddend62c0b52009-08-04 15:02:12 -07003054 if ((fd = open(path, O_WRONLY)) < 0) {
3055 int err = errno;
San Mehat256fc152009-04-21 14:03:06 -07003056#if ENABLE_CGROUP_ERR_LOGGING
Andy McFaddend62c0b52009-08-04 15:02:12 -07003057 LOGW("Unable to open %s (%s)\n", path, strerror(err));
San Mehat256fc152009-04-21 14:03:06 -07003058#endif
Andy McFaddend62c0b52009-08-04 15:02:12 -07003059 return -err;
San Mehat256fc152009-04-21 14:03:06 -07003060 }
3061
Andy McFaddend62c0b52009-08-04 15:02:12 -07003062 if (write(fd, "0", 1) < 0) {
3063 int err = errno;
San Mehat256fc152009-04-21 14:03:06 -07003064#if ENABLE_CGROUP_ERR_LOGGING
Andy McFaddend62c0b52009-08-04 15:02:12 -07003065 LOGW("Unable to move tid %d to cgroup %s (%s)\n",
3066 dvmThreadSelf()->systemTid,
3067 (cgroup ? cgroup : "<default>"), strerror(err));
San Mehat256fc152009-04-21 14:03:06 -07003068#endif
Andy McFaddend62c0b52009-08-04 15:02:12 -07003069 close(fd);
3070 return -err;
San Mehat256fc152009-04-21 14:03:06 -07003071 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003072 close(fd);
San Mehat256fc152009-04-21 14:03:06 -07003073
Andy McFaddend62c0b52009-08-04 15:02:12 -07003074 return 0;
3075
San Mehat256fc152009-04-21 14:03:06 -07003076#else // HAVE_ANDROID_OS
3077 return 0;
3078#endif
3079}
3080
3081/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003082 * Change the priority of a system thread to match that of the Thread object.
3083 *
3084 * We map a priority value from 1-10 to Linux "nice" values, where lower
3085 * numbers indicate higher priority.
3086 */
3087void dvmChangeThreadPriority(Thread* thread, int newPriority)
3088{
3089 pid_t pid = thread->systemTid;
3090 int newNice;
3091
3092 if (newPriority < 1 || newPriority > 10) {
3093 LOGW("bad priority %d\n", newPriority);
3094 newPriority = 5;
3095 }
3096 newNice = kNiceValues[newPriority-1];
3097
Andy McFaddend62c0b52009-08-04 15:02:12 -07003098 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat256fc152009-04-21 14:03:06 -07003099 dvmChangeThreadSchedulerGroup("bg_non_interactive");
San Mehat3e371e22009-06-26 08:36:16 -07003100 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat256fc152009-04-21 14:03:06 -07003101 dvmChangeThreadSchedulerGroup(NULL);
3102 }
3103
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003104 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3105 char* str = dvmGetThreadName(thread);
3106 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3107 pid, str, newPriority, newNice, strerror(errno));
3108 free(str);
3109 } else {
3110 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3111 pid, newPriority, newNice);
3112 }
3113}
3114
3115/*
3116 * Get the thread priority for the current thread by querying the system.
3117 * This is useful when attaching a thread through JNI.
3118 *
3119 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3120 */
3121static int getThreadPriorityFromSystem(void)
3122{
3123 int i, sysprio, jprio;
3124
3125 errno = 0;
3126 sysprio = getpriority(PRIO_PROCESS, 0);
3127 if (sysprio == -1 && errno != 0) {
3128 LOGW("getpriority() failed: %s\n", strerror(errno));
3129 return THREAD_NORM_PRIORITY;
3130 }
3131
3132 jprio = THREAD_MIN_PRIORITY;
3133 for (i = 0; i < NELEM(kNiceValues); i++) {
3134 if (sysprio >= kNiceValues[i])
3135 break;
3136 jprio++;
3137 }
3138 if (jprio > THREAD_MAX_PRIORITY)
3139 jprio = THREAD_MAX_PRIORITY;
3140
3141 return jprio;
3142}
3143
3144
3145/*
3146 * Return true if the thread is on gDvm.threadList.
3147 * Caller should not hold gDvm.threadListLock.
3148 */
3149bool dvmIsOnThreadList(const Thread* thread)
3150{
3151 bool ret = false;
3152
3153 dvmLockThreadList(NULL);
3154 if (thread == gDvm.threadList) {
3155 ret = true;
3156 } else {
3157 ret = thread->prev != NULL || thread->next != NULL;
3158 }
3159 dvmUnlockThreadList();
3160
3161 return ret;
3162}
3163
3164/*
3165 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3166 * output target.
3167 */
3168void dvmDumpThread(Thread* thread, bool isRunning)
3169{
3170 DebugOutputTarget target;
3171
3172 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3173 dvmDumpThreadEx(&target, thread, isRunning);
3174}
3175
3176/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003177 * Try to get the scheduler group.
3178 *
3179 * The data from /proc/<pid>/cgroup looks like:
3180 * 2:cpu:/bg_non_interactive
3181 *
3182 * We return the part after the "/", which will be an empty string for
3183 * the default cgroup. If the string is longer than "bufLen", the string
3184 * will be truncated.
3185 */
3186static bool getSchedulerGroup(Thread* thread, char* buf, size_t bufLen)
3187{
3188#ifdef HAVE_ANDROID_OS
3189 char pathBuf[32];
3190 char readBuf[256];
3191 ssize_t count;
3192 int fd;
3193
3194 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", thread->systemTid);
3195 if ((fd = open(pathBuf, O_RDONLY)) < 0) {
3196 LOGV("open(%s) failed: %s\n", pathBuf, strerror(errno));
3197 return false;
3198 }
3199
3200 count = read(fd, readBuf, sizeof(readBuf));
3201 if (count <= 0) {
3202 LOGV("read(%s) failed (%d): %s\n",
3203 pathBuf, (int) count, strerror(errno));
3204 close(fd);
3205 return false;
3206 }
3207 close(fd);
3208
3209 readBuf[--count] = '\0'; /* remove the '\n', now count==strlen */
3210
3211 char* cp = strchr(readBuf, '/');
3212 if (cp == NULL) {
3213 readBuf[sizeof(readBuf)-1] = '\0';
3214 LOGV("no '/' in '%s' (file=%s count=%d)\n",
3215 readBuf, pathBuf, (int) count);
3216 return false;
3217 }
3218
3219 memcpy(buf, cp+1, count); /* count-1 for cp+1, count+1 for NUL */
3220 return true;
3221#else
3222 return false;
3223#endif
3224}
3225
3226/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003227 * Print information about the specified thread.
3228 *
3229 * Works best when the thread in question is "self" or has been suspended.
3230 * When dumping a separate thread that's still running, set "isRunning" to
3231 * use a more cautious thread dump function.
3232 */
3233void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3234 bool isRunning)
3235{
3236 /* tied to ThreadStatus enum */
3237 static const char* kStatusNames[] = {
3238 "ZOMBIE", "RUNNABLE", "TIMED_WAIT", "MONITOR", "WAIT",
3239 "INITIALIZING", "STARTING", "NATIVE", "VMWAIT"
3240 };
3241 Object* threadObj;
3242 Object* groupObj;
3243 StringObject* nameStr;
3244 char* threadName = NULL;
3245 char* groupName = NULL;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003246 char schedulerGroupBuf[32];
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003247 bool isDaemon;
3248 int priority; // java.lang.Thread priority
3249 int policy; // pthread policy
3250 struct sched_param sp; // pthread scheduling parameters
3251
3252 threadObj = thread->threadObj;
3253 if (threadObj == NULL) {
3254 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
3255 return;
3256 }
3257 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3258 gDvm.offJavaLangThread_name);
3259 threadName = dvmCreateCstrFromString(nameStr);
3260
3261 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3262 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3263
3264 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3265 LOGW("Warning: pthread_getschedparam failed\n");
3266 policy = -1;
3267 sp.sched_priority = -1;
3268 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003269 if (!getSchedulerGroup(thread, schedulerGroupBuf,sizeof(schedulerGroupBuf)))
3270 {
3271 strcpy(schedulerGroupBuf, "unknown");
3272 } else if (schedulerGroupBuf[0] == '\0') {
3273 strcpy(schedulerGroupBuf, "default");
3274 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003275
3276 /* a null value for group is not expected, but deal with it anyway */
3277 groupObj = (Object*) dvmGetFieldObject(threadObj,
3278 gDvm.offJavaLangThread_group);
3279 if (groupObj != NULL) {
3280 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3281 "name", "Ljava/lang/String;");
3282 if (offset < 0) {
3283 LOGW("Unable to find 'name' field in ThreadGroup\n");
3284 } else {
3285 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3286 groupName = dvmCreateCstrFromString(nameStr);
3287 }
3288 }
3289 if (groupName == NULL)
3290 groupName = strdup("(BOGUS GROUP)");
3291
3292 assert(thread->status < NELEM(kStatusNames));
3293 dvmPrintDebugMessage(target,
3294 "\"%s\"%s prio=%d tid=%d %s\n",
3295 threadName, isDaemon ? " daemon" : "",
3296 priority, thread->threadId, kStatusNames[thread->status]);
3297 dvmPrintDebugMessage(target,
Andy McFadden2aa43612009-06-17 16:29:30 -07003298 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p self=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003299 groupName, thread->suspendCount, thread->dbgSuspendCount,
Andy McFadden2aa43612009-06-17 16:29:30 -07003300 thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003301 dvmPrintDebugMessage(target,
Andy McFaddend62c0b52009-08-04 15:02:12 -07003302 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003303 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
Andy McFaddend62c0b52009-08-04 15:02:12 -07003304 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003305
3306#ifdef WITH_MONITOR_TRACKING
3307 if (!isRunning) {
3308 LockedObjectData* lod = thread->pLockedObjects;
3309 if (lod != NULL)
3310 dvmPrintDebugMessage(target, " | monitors held:\n");
3311 else
3312 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3313 while (lod != NULL) {
3314 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3315 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
3316 lod = lod->next;
3317 }
3318 }
3319#endif
3320
3321 if (isRunning)
3322 dvmDumpRunningThreadStack(target, thread);
3323 else
3324 dvmDumpThreadStack(target, thread);
3325
3326 free(threadName);
3327 free(groupName);
3328
3329}
3330
3331/*
3332 * Get the name of a thread.
3333 *
3334 * For correctness, the caller should hold the thread list lock to ensure
3335 * that the thread doesn't go away mid-call.
3336 *
3337 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3338 */
3339char* dvmGetThreadName(Thread* thread)
3340{
3341 StringObject* nameObj;
3342
3343 if (thread->threadObj == NULL) {
3344 LOGW("threadObj is NULL, name not available\n");
3345 return strdup("-unknown-");
3346 }
3347
3348 nameObj = (StringObject*)
3349 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3350 return dvmCreateCstrFromString(nameObj);
3351}
3352
3353/*
3354 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3355 * an output target.
3356 */
3357void dvmDumpAllThreads(bool grabLock)
3358{
3359 DebugOutputTarget target;
3360
3361 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3362 dvmDumpAllThreadsEx(&target, grabLock);
3363}
3364
3365/*
3366 * Print information about all known threads. Assumes they have been
3367 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3368 *
3369 * If "grabLock" is true, we grab the thread lock list. This is important
3370 * to do unless the caller already holds the lock.
3371 */
3372void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3373{
3374 Thread* thread;
3375
3376 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3377
3378 if (grabLock)
3379 dvmLockThreadList(dvmThreadSelf());
3380
3381 thread = gDvm.threadList;
3382 while (thread != NULL) {
3383 dvmDumpThreadEx(target, thread, false);
3384
3385 /* verify link */
3386 assert(thread->next == NULL || thread->next->prev == thread);
3387
3388 thread = thread->next;
3389 }
3390
3391 if (grabLock)
3392 dvmUnlockThreadList();
3393}
3394
3395#ifdef WITH_MONITOR_TRACKING
3396/*
3397 * Count up the #of locked objects in the current thread.
3398 */
3399static int getThreadObjectCount(const Thread* self)
3400{
3401 LockedObjectData* lod;
3402 int count = 0;
3403
3404 lod = self->pLockedObjects;
3405 while (lod != NULL) {
3406 count++;
3407 lod = lod->next;
3408 }
3409 return count;
3410}
3411
3412/*
3413 * Add the object to the thread's locked object list if it doesn't already
3414 * exist. The most recently added object is the most likely to be released
3415 * next, so we insert at the head of the list.
3416 *
3417 * If it already exists, we increase the recursive lock count.
3418 *
3419 * The object's lock may be thin or fat.
3420 */
3421void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3422{
3423 LockedObjectData* newLod;
3424 LockedObjectData* lod;
3425 int* trace;
3426 int depth;
3427
3428 lod = self->pLockedObjects;
3429 while (lod != NULL) {
3430 if (lod->obj == obj) {
3431 lod->recursionCount++;
3432 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3433 return;
3434 }
3435 lod = lod->next;
3436 }
3437
3438 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3439 if (newLod == NULL) {
3440 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3441 return;
3442 }
3443 newLod->obj = obj;
3444 newLod->recursionCount = 0;
3445
3446 if (withTrace) {
3447 trace = dvmFillInStackTraceRaw(self, &depth);
3448 newLod->rawStackTrace = trace;
3449 newLod->stackDepth = depth;
3450 }
3451
3452 newLod->next = self->pLockedObjects;
3453 self->pLockedObjects = newLod;
3454
3455 LOGV("+++ threadid=%d: added %p, now %d\n",
3456 self->threadId, newLod, getThreadObjectCount(self));
3457}
3458
3459/*
3460 * Remove the object from the thread's locked object list. If the entry
3461 * has a nonzero recursion count, we just decrement the count instead.
3462 */
3463void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3464{
3465 LockedObjectData* lod;
3466 LockedObjectData* prevLod;
3467
3468 lod = self->pLockedObjects;
3469 prevLod = NULL;
3470 while (lod != NULL) {
3471 if (lod->obj == obj) {
3472 if (lod->recursionCount > 0) {
3473 lod->recursionCount--;
3474 LOGV("+++ -recursive lock %p -> %d\n",
3475 obj, lod->recursionCount);
3476 return;
3477 } else {
3478 break;
3479 }
3480 }
3481 prevLod = lod;
3482 lod = lod->next;
3483 }
3484
3485 if (lod == NULL) {
3486 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3487 return;
3488 }
3489 if (prevLod == NULL) {
3490 /* first item in list */
3491 assert(self->pLockedObjects == lod);
3492 self->pLockedObjects = lod->next;
3493 } else {
3494 /* middle/end of list */
3495 prevLod->next = lod->next;
3496 }
3497
3498 LOGV("+++ threadid=%d: removed %p, now %d\n",
3499 self->threadId, lod, getThreadObjectCount(self));
3500 free(lod->rawStackTrace);
3501 free(lod);
3502}
3503
3504/*
3505 * If the specified object is already in the thread's locked object list,
3506 * return the LockedObjectData struct. Otherwise return NULL.
3507 */
3508LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3509{
3510 LockedObjectData* lod;
3511
3512 lod = self->pLockedObjects;
3513 while (lod != NULL) {
3514 if (lod->obj == obj)
3515 return lod;
3516 lod = lod->next;
3517 }
3518 return NULL;
3519}
3520#endif /*WITH_MONITOR_TRACKING*/
3521
3522
3523/*
3524 * GC helper functions
3525 */
3526
The Android Open Source Project99409882009-03-18 22:20:24 -07003527/*
3528 * Add the contents of the registers from the interpreted call stack.
3529 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003530static void gcScanInterpStackReferences(Thread *thread)
3531{
3532 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003533#if WITH_EXTRA_GC_CHECKS > 1
3534 bool first = true;
3535#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003536
3537 framePtr = (const u4 *)thread->curFrame;
3538 while (framePtr != NULL) {
3539 const StackSaveArea *saveArea;
3540 const Method *method;
3541
3542 saveArea = SAVEAREA_FROM_FP(framePtr);
3543 method = saveArea->method;
The Android Open Source Project99409882009-03-18 22:20:24 -07003544 if (method != NULL && !dvmIsNativeMethod(method)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003545#ifdef COUNT_PRECISE_METHODS
3546 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003547 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3548 LOGI("PGC: added %s.%s %p\n",
3549 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003550#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003551#if WITH_EXTRA_GC_CHECKS > 1
3552 /*
3553 * May also want to enable the memset() in the "invokeMethod"
3554 * goto target in the portable interpreter. That sets the stack
3555 * to a pattern that makes referring to uninitialized data
3556 * very obvious.
3557 */
3558
3559 if (first) {
3560 /*
3561 * First frame, isn't native, check the "alternate" saved PC
3562 * as a sanity check.
3563 *
3564 * It seems like we could check the second frame if the first
3565 * is native, since the PCs should be the same. It turns out
3566 * this doesn't always work. The problem is that we could
3567 * have calls in the sequence:
3568 * interp method #2
3569 * native method
3570 * interp method #1
3571 *
3572 * and then GC while in the native method after returning
3573 * from interp method #2. The currentPc on the stack is
3574 * for interp method #1, but thread->currentPc2 is still
3575 * set for the last thing interp method #2 did.
3576 *
3577 * This can also happen in normal execution:
3578 * - sget-object on not-yet-loaded class
3579 * - class init updates currentPc2
3580 * - static field init is handled by parsing annotations;
3581 * static String init requires creation of a String object,
3582 * which can cause a GC
3583 *
3584 * Essentially, any pattern that involves executing
3585 * interpreted code and then causes an allocation without
3586 * executing instructions in the original method will hit
3587 * this. These are rare enough that the test still has
3588 * some value.
3589 */
3590 if (saveArea->xtra.currentPc != thread->currentPc2) {
3591 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3592 saveArea->xtra.currentPc, thread->currentPc2,
3593 method->clazz->descriptor, method->name, method->insns);
3594 if (saveArea->xtra.currentPc != NULL)
3595 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3596 if (thread->currentPc2 != NULL)
3597 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3598 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003599 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003600 } else {
3601 /*
3602 * It's unusual, but not impossible, for a non-first frame
3603 * to be at something other than a method invocation. For
3604 * example, if we do a new-instance on a nonexistent class,
3605 * we'll have a lot of class loader activity on the stack
3606 * above the frame with the "new" operation. Could also
3607 * happen while we initialize a Throwable when an instruction
3608 * fails.
3609 *
3610 * So there's not much we can do here to verify the PC,
3611 * except to verify that it's a GC point.
3612 */
3613 }
3614 assert(saveArea->xtra.currentPc != NULL);
3615#endif
3616
3617 const RegisterMap* pMap;
3618 const u1* regVector;
3619 int i;
3620
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003621 Method* nonConstMethod = (Method*) method; // quiet gcc
3622 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003623 if (pMap != NULL) {
3624 /* found map, get registers for this address */
3625 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003626 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003627 if (regVector == NULL) {
3628 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3629 method->clazz->descriptor, method->name, addr);
3630 } else {
3631 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3632 method->clazz->descriptor, method->name, addr,
3633 thread->threadId);
3634 }
3635 } else {
3636 /*
3637 * No map found. If precise GC is disabled this is
3638 * expected -- we don't create pointers to the map data even
3639 * if it's present -- but if it's enabled it means we're
3640 * unexpectedly falling back on a conservative scan, so it's
3641 * worth yelling a little.
The Android Open Source Project99409882009-03-18 22:20:24 -07003642 */
3643 if (gDvm.preciseGc) {
Andy McFaddena66a01a2009-08-18 15:11:35 -07003644 LOGVV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003645 method->clazz->descriptor, method->name);
3646 }
3647 regVector = NULL;
3648 }
3649
3650 if (regVector == NULL) {
3651 /* conservative scan */
3652 for (i = method->registersSize - 1; i >= 0; i--) {
3653 u4 rval = *framePtr++;
3654 if (rval != 0 && (rval & 0x3) == 0) {
3655 dvmMarkIfObject((Object *)rval);
3656 }
3657 }
3658 } else {
3659 /*
3660 * Precise scan. v0 is at the lowest address on the
3661 * interpreted stack, and is the first bit in the register
3662 * vector, so we can walk through the register map and
3663 * memory in the same direction.
3664 *
3665 * A '1' bit indicates a live reference.
3666 */
3667 u2 bits = 1 << 1;
3668 for (i = method->registersSize - 1; i >= 0; i--) {
3669 u4 rval = *framePtr++;
3670
3671 bits >>= 1;
3672 if (bits == 1) {
3673 /* set bit 9 so we can tell when we're empty */
3674 bits = *regVector++ | 0x0100;
3675 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3676 }
3677
3678 if (rval != 0 && (bits & 0x01) != 0) {
3679 /*
3680 * Non-null, register marked as live reference. This
3681 * should always be a valid object.
3682 */
3683#if WITH_EXTRA_GC_CHECKS > 0
3684 if ((rval & 0x3) != 0 ||
3685 !dvmIsValidObject((Object*) rval))
3686 {
3687 /* this is very bad */
3688 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3689 method->registersSize-1 - i, rval);
3690 } else
3691#endif
3692 {
3693 dvmMarkObjectNonNull((Object *)rval);
3694 }
3695 } else {
3696 /*
3697 * Null or non-reference, do nothing at all.
3698 */
3699#if WITH_EXTRA_GC_CHECKS > 1
3700 if (dvmIsValidObject((Object*) rval)) {
3701 /* this is normal, but we feel chatty */
3702 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3703 method->registersSize-1 - i, rval);
3704 }
3705#endif
3706 }
3707 }
3708 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003709 }
3710 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003711 /* else this is a break frame and there is nothing to mark, or
3712 * this is a native method and the registers are just the "ins",
3713 * copied from various registers in the caller's set.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003714 */
3715
The Android Open Source Project99409882009-03-18 22:20:24 -07003716#if WITH_EXTRA_GC_CHECKS > 1
3717 first = false;
3718#endif
3719
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003720 /* Don't fall into an infinite loop if things get corrupted.
3721 */
3722 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3723 saveArea->prevFrame == NULL);
3724 framePtr = saveArea->prevFrame;
3725 }
3726}
3727
3728static void gcScanReferenceTable(ReferenceTable *refTable)
3729{
3730 Object **op;
3731
3732 //TODO: these asserts are overkill; turn them off when things stablize.
3733 assert(refTable != NULL);
3734 assert(refTable->table != NULL);
3735 assert(refTable->nextEntry != NULL);
3736 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3737 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3738
3739 op = refTable->table;
3740 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3741 dvmMarkObjectNonNull(*(op++));
3742 }
3743}
3744
3745/*
3746 * Scan a Thread and mark any objects it references.
3747 */
3748static void gcScanThread(Thread *thread)
3749{
3750 assert(thread != NULL);
3751
3752 /*
3753 * The target thread must be suspended or in a state where it can't do
3754 * any harm (e.g. in Object.wait()). The only exception is the current
3755 * thread, which will still be active and in the "running" state.
3756 *
3757 * (Newly-created threads shouldn't be able to shift themselves to
3758 * RUNNING without a suspend-pending check, so this shouldn't cause
3759 * a false-positive.)
3760 */
3761 assert(thread->status != THREAD_RUNNING || thread->isSuspended ||
3762 thread == dvmThreadSelf());
3763
3764 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3765
3766 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3767
3768 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3769
3770 dvmMarkObject(thread->exception); // usually NULL
3771 gcScanReferenceTable(&thread->internalLocalRefTable);
3772
3773 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3774
3775 gcScanReferenceTable(&thread->jniLocalRefTable);
3776
3777 if (thread->jniMonitorRefTable.table != NULL) {
3778 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3779
3780 gcScanReferenceTable(&thread->jniMonitorRefTable);
3781 }
3782
3783 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3784
3785 gcScanInterpStackReferences(thread);
3786
3787 HPROF_CLEAR_GC_SCAN_STATE();
3788}
3789
3790static void gcScanAllThreads()
3791{
3792 Thread *thread;
3793
3794 /* Lock the thread list so we can safely use the
3795 * next/prev pointers.
3796 */
3797 dvmLockThreadList(dvmThreadSelf());
3798
3799 for (thread = gDvm.threadList; thread != NULL;
3800 thread = thread->next)
3801 {
3802 /* We need to scan our own stack, so don't special-case
3803 * the current thread.
3804 */
3805 gcScanThread(thread);
3806 }
3807
3808 dvmUnlockThreadList();
3809}
3810
3811void dvmGcScanRootThreadGroups()
3812{
3813 /* We scan the VM's list of threads instead of going
3814 * through the actual ThreadGroups, but it should be
3815 * equivalent.
3816 *
3817 * This assumes that the ThreadGroup class object is in
3818 * the root set, which should always be true; it's
3819 * loaded by the built-in class loader, which is part
3820 * of the root set.
3821 */
3822 gcScanAllThreads();
3823}