Home | History | Annotate | Download | only in vm

Lines Matching refs:Thread

18  * Thread support.
57 // change this to LOGV/LOGD to debug thread activity
64 thread, are visible to code running in the VM and to the debugger. (We
65 don't want the debugger to try to manipulate the thread that listens for
80 Internal native VM threads, such as the finalizer thread, must explicitly
85 thread. The debugger may suspend or resume individual threads, while the
86 GC always suspends all threads. Each thread has a "suspend count" that
88 When the count is zero, the thread is runnable. This allows us to fulfill
89 a debugger requirement: if the debugger suspends a thread, the thread is
94 Certain "slow" VM operations, such as starting up a new thread, will be
114 The debugger may choose to suspend or resume a single thread, which can
117 active (the java.lang.Thread calls for this are deprecated and hence are
118 not supported). Resumption of a single thread is handled by decrementing
119 the thread's suspend count and sending a broadcast signal to the condition
126 (the JDWP thread is suspended during GC).
128 The VM maintains a Thread struct for every pthread known to the VM. There
129 is a java/lang/Thread object associated with every Thread. At present,
130 there is no safe way to go from a Thread object to a Thread struct except by
142 The trouble with using signals to suspend threads is that it means a thread
147 Critical sections temporarily block suspension for a given thread.
148 The thread must move to a non-blocked state (and self-suspend) after
149 finishing its current task. If the thread blocks on a resource held
150 by a suspended thread, we're hosed.
154 This is too limiting. For example, if thread A gets suspended while
155 holding the thread list lock, it will prevent the GC or debugger from
156 being able to safely access the thread list. We need to wrap the critical
161 within critical sections. A thread that enters a critical section and
162 then gets blocked on the thread list lock knows that the thread it is
229 static Thread* allocThread(int interpStackSize);
230 static bool prepareThread(Thread* thread);
231 static void setThreadSelf(Thread* thread);
232 static void unlinkThread(Thread* thread);
233 static void freeThread(Thread* thread);
234 static void assignThreadId(Thread* thread);
235 static bool createFakeEntryFrame(Thread* thread);
236 static bool createFakeRunFrame(Thread* thread);
239 static void threadExitUncaughtException(Thread* thread, Object* group);
241 static void waitForThreadSuspend(Thread* self, Thread* thread);
244 * Initialize thread list and main thread's environment. We need to set
250 Thread* thread;
262 /* prep thread-related locks and conditions */
271 * Dedicated monitor for Thread.sleep().
275 * thread prep) or until first use.
281 thread = allocThread(gDvm.stackSize);
282 if (thread == NULL)
286 thread->status = THREAD_RUNNING;
292 prepareThread(thread);
293 gDvm.threadList = thread;
303 * All threads should be stopped by now. Clean up some thread globals.
309 * If we walk through the thread list and try to free the
310 * lingering thread structures (which should only be for daemon
351 * Grab the thread list global lock.
356 * thread not be in RUNNING mode.
359 * the lock. Nobody can suspend all threads without holding the thread list
364 * are required to grab the thread list lock before the thread suspend
372 void dvmLockThreadList(Thread* self)
394 * Try to lock the thread list.
397 * current thread holds the lock this will fail.
405 * Release the thread list global lock.
436 * Grab the "thread suspend" lock. This is required to prevent the
453 Thread* self = dvmThreadSelf();
458 * grabbed the CPU when the wakeup was broadcast. The thread
460 * thread suspend lock. (We release before the broadcast,
467 * Could be an unusual JNI thread-attach thing.
475 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
487 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
490 /* threads are not suspended, thread dump could crash */
500 * Release the "thread suspend" lock.
510 * stopped, so these should be Thread objects or JNI-attached threads
517 * Waiting for the thread to suspend may be unwise at this point, but
524 * This will be called from whatever thread calls DestroyJavaVM, usually
525 * but not necessarily the main thread. It's likely, but not guaranteed,
526 * that the current thread has already been cleaned up.
530 Thread* self = dvmThreadSelf(); // may be null
531 Thread* target;
571 * Unlock the thread list, relocking it later if necessary. It's
572 * possible a thread is in VMWAIT after calling dvmLockThreadList,
637 Thread* nextTarget = target->next;
649 * Finish preparing the parts of the Thread struct required to support
654 Thread* self;
656 /* main thread is always first in list at this point */
660 /* create a "fake" JNI frame at the top of the main thread interp stack */
673 * Finish preparing the main thread, allocating some objects to represent
674 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
679 Thread* thread;
687 LOGV("+++ finishing prep on main VM thread");
689 /* main thread is always first in list at this point */
690 thread = gDvm.threadList;
691 assert(thread->threadId == kMainThreadId);
705 LOGE("thread classes failed to initialize");
714 * Allocate and construct a Thread with the internal-creation
719 LOGE("unable to allocate main thread object");
732 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
734 if (dvmCheckException(thread)) {
735 LOGE("exception thrown while constructing main thread object");
750 "(Ljava/lang/Thread;)V");
751 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
752 if (dvmCheckException(thread)) {
757 /* set the VMThread.vmData field to our Thread struct */
759 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
762 * Stuff the VMThread back into the Thread. From this point on, other
763 * Threads will see that this Thread is running (at least, they would,
769 thread->threadObj = threadObj;
776 * Thread.currentThread(), so we want the Thread to be fully configured
797 * Alloc and initialize a Thread struct.
801 static Thread* allocThread(int interpStackSize)
803 Thread* thread;
806 thread = (Thread*) calloc(1, sizeof(Thread));
807 if (thread == NULL)
811 assert((((uintptr_t)&thread->interpBreak.all) & 0x7) == 0);
812 assert(sizeof(thread->interpBreak) == sizeof(thread->interpBreak.all));
816 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
822 thread->status = THREAD_INITIALIZING;
835 dvmSelfVerificationShadowSpaceFree(thread);
837 free(thread);
846 dvmSelfVerificationShadowSpaceFree(thread);
848 free(thread);
854 thread->interpStackSize = interpStackSize;
855 thread->interpStackStart = stackBottom + interpStackSize;
856 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
859 thread->mainHandlerTable = dvmAsmInstructionStart;
860 thread->altHandlerTable = dvmAsmAltInstructionStart;
861 thread->interpBreak.ctl.curHandlerTable = thread->mainHandlerTable;
864 /* give the thread code a chance to set things up */
865 dvmInitInterpStack(thread, interpStackSize);
868 dvmInitInterpreterState(thread);
870 return thread;
874 * Get a meaningful thread ID. At present this only has meaning under Linux,
876 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
888 * Finish initialization of a Thread struct.
890 * This must be called while executing in the new thread, but before the
891 * thread is added to the thread list.
896 static bool prepareThread(Thread* thread)
898 assignThreadId(thread);
899 thread->handle = pthread_self();
900 thread->systemTid = dvmGetSysThreadId();
902 //LOGI("SYSTEM TID IS %d (pid is %d)", (int) thread->systemTid,
906 * already correctly established as "thread".
908 setThreadSelf(thread);
911 thread->threadId, thread->interpStackStart - thread->interpStackSize);
916 dvmInitMutex(&thread->invokeReq.lock);
917 pthread_cond_init(&thread->invokeReq.cv, NULL);
925 if (!thread
929 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
933 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
935 pthread_cond_init(&thread->waitCond, NULL);
936 dvmInitMutex(&thread->waitMutex);
939 dvmInitMutex(&thread->callbackMutex);
945 * Remove a thread from the internal list.
946 * Clear out the links to make it obvious that the thread is
949 static void unlinkThread(Thread* thread)
951 LOG_THREAD("threadid=%d: removing from list", thread->threadId);
952 if (thread == gDvm.threadList) {
953 assert(thread->prev == NULL);
954 gDvm.threadList = thread->next;
956 assert(thread->prev != NULL);
957 thread->prev->next = thread->next;
959 if (thread->next != NULL)
960 thread->next->prev = thread->prev;
961 thread->prev = thread->next = NULL;
965 * Free a Thread struct, and all the stuff allocated within.
967 static void freeThread(Thread* thread)
969 if (thread == NULL)
972 /* thread->threadId is zero at this point */
973 LOGVV("threadid=%d: freeing", thread->threadId);
975 if (thread->interpStackStart != NULL) {
978 interpStackBottom = thread->interpStackStart;
979 interpStackBottom -= thread->interpStackSize;
983 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
984 LOGW("munmap(thread stack) failed");
988 thread->jniLocalRefTable.destroy();
989 dvmClearReferenceTable(&thread->internalLocalRefTable);
990 if (&thread->jniMonitorRefTable.table != NULL)
991 dvmClearReferenceTable(&thread->jniMonitorRefTable);
994 dvmSelfVerificationShadowSpaceFree(thread);
996 free(thread);
1000 * Like pthread_self(), but on a Thread*.
1002 Thread* dvmThreadSelf()
1004 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1008 * Explore our sense of self. Stuffs the thread pointer into TLS.
1010 static void setThreadSelf(Thread* thread)
1014 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1018 * This can happen if the timing is just right, e.g. a thread
1022 if (thread != NULL) {
1023 LOGE("pthread_setspecific(%p) failed, err=%d", thread, cc);
1031 * pthread library when a thread is exiting and the "self" pointer in TLS
1036 * example, a thread attaches itself to us with AttachCurrentThread and
1041 * will simply be unaware that the thread has exited, leading to resource
1042 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1053 Thread* self = (Thread*) arg;
1069 LOGD("threadid=%d: thread exiting, not yet detached (count=%d)",
1074 LOGE("threadid=%d: unable to re-add thread to TLS",
1079 LOGE("threadid=%d: native thread exited without detaching",
1094 static void assignThreadId(Thread* thread)
1103 LOGE("Ran out of thread IDs");
1107 thread->threadId = num + 1;
1109 assert(thread->threadId != 0);
1113 * Give back the thread ID.
1115 static void releaseThreadId(Thread* thread)
1117 assert(thread->threadId > 0);
1118 dvmClearBit(gDvm.threadIdMap, thread->threadId - 1);
1119 thread->threadId = 0;
1125 * thread was originally invoked from interpreted code. This gives us a
1130 static bool createFakeEntryFrame(Thread* thread)
1148 assert(thread->threadId == kMainThreadId); /* main thread only */
1150 if (!dvmPushJNIFrame(thread, gDvm.methDalvikSystemNativeStart_main))
1157 u4* framePtr = (u4*) thread->interpSave.curFrame;
1165 * Add a stack frame that makes it look like the native thread has been
1169 static bool createFakeRunFrame(Thread* thread)
1171 return dvmPushJNIFrame(thread, gDvm.methDalvikSystemNativeStart_run);
1175 * Helper function to set the name of the current thread
1200 LOGW("Unable to set the name of current thread to '%s': %s",
1206 LOGD("No way to set current thread's name (%s)", s);
1211 * Create a thread as a result of java.lang.Thread.start().
1214 * that try to call Thread.start() on the same object from multiple threads.
1219 * Thread vs. VMThread class decomposition we inherited. We've been given
1220 * a Thread, and now we need to create a VMThread and then populate both
1221 * objects. We also need to create one of our internal Thread objects.
1232 Thread* self = dvmThreadSelf();
1255 Thread* newThread = allocThread(stackSize);
1267 * "vmThread" field in java.lang.Thread, because we use that to determine
1268 * if this thread has been started before. We use the thread list lock
1277 "thread has already been started");
1283 * There are actually three data structures: Thread (object), VMThread
1284 * (object), and Thread (C struct). All of them point to at least one
1294 * Thread creation might take a while, so release the lock.
1310 LOGE("Thread creation failed (err=%s)", strerror(errno));
1314 dvmThrowOutOfMemoryError("thread creation failed");
1319 * We need to wait for the thread to start. Otherwise, depending on
1321 * thread could try to do operations on the new thread before it had
1324 * The new thread will lock the thread list, change its state to
1326 * on gDvm.threadStartCond (which uses the thread list lock). This
1327 * thread (the parent) will either see that the thread is already ready
1328 * after we grab the thread list lock, or will be awakened from the
1331 * We don't want to stall the rest of the VM while the new thread
1334 * necessary after we finish adding the new thread.
1338 * mechanism when creating a new thread. The information about whether
1339 * or not a thread should be suspended is contained entirely within
1340 * the Thread struct; this is usually cleaner to deal with than having
1342 * we could create the thread while the VM is trying to suspend all
1343 * threads. The suspend-count won't be nonzero for the new thread,
1346 * The easiest way to deal with this is to prevent the new thread from
1349 * (where '-' is us, 'o' is the child, and '+' is some other thread):
1352 * - lock thread list
1354 * - sleep on condition var (mutex = thread list lock) until child starts
1355 * + GC triggered by another thread
1356 * + thread list locked; suspend counts updated; thread list unlocked
1359 * o child thread wakes, signals condition var to wake parent
1361 * - we wake up, locking thread list
1362 * - add child to thread list
1363 * - unlock thread list
1365 * + GC finishes; all threads in thread list are resumed
1366 * - lock thread list
1368 * - unlock thread list
1372 * The above shows the GC starting up during thread creation, but if
1376 * Once the child is in the thread list, it will be suspended and
1377 * resumed like any other thread. In the above scenario the resume-all
1378 * code will try to resume the new thread, which was never actually
1379 * suspended, and try to decrement the child's thread suspend count to -1.
1383 * of scheduler overhead to thread startup.
1388 * thread
1392 * We could also have a global "new thread suspend count" that gets
1394 * This would be protected by the thread list lock and set by a
1414 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1422 * Tell the new thread to start.
1424 * We must hold the thread list lock before messing with another thread.
1426 * still in the thread list, but in our case the thread has not started
1454 Thread* self = (Thread*) arg;
1460 * Finish initializing the Thread struct.
1469 * thread list and advance our state to VMWAIT.
1483 * signaled, and suspend-all will grab the thread list lock and then
1505 * us to suspend ourselves (and others). The thread state may change
1512 * Set the system thread priority according to the Thread object's
1514 * Thread object and system thread priorities inherit from parents. The
1515 * tricky case is when somebody creates a Thread object, calls
1516 * setPriority(), and then starts the thread. We could manage this with
1538 * Remove the thread from various lists, report its death, and free
1547 * The current thread is exiting with an uncaught exception. The
1549 * thread-exit-uncaught-exception handler for the VM, for a specific
1550 * Thread, and for all threads in a ThreadGroup.
1552 * Version 1.5 added the per-thread handler. We need to call
1554 * ThreadGroup object or the Thread-specific handler.
1559 static void threadExitUncaughtException(Thread* self, Object* group)
1565 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)",
1571 * thread. We don't want to have it set when executing interpreted code.
1579 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1591 * was declared in the Thread.UncaughtExceptionHandler interface.
1594 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1615 /* Remove this thread's suspendCount from global suspendCount sum */
1623 * Create an internal VM thread, for things like JDWP and finalizers.
1625 * The easiest way to do this is create a new thread and then use the
1628 * This does not return until after the new thread has begun executing.
1636 volatile Thread* newThread = NULL;
1646 pArgs->name = strdup(name); // storage will be owned by new thread
1658 LOGE("internal thread creation failed");
1666 * sure that the thread started correctly, and allows our caller to
1667 * assume that the thread has started running.
1669 * Because we aren't holding a lock across the thread creation, it's
1672 * holding the thread list lock, the initial condition on the "while"
1675 * It's also possible that we'll have to wait for the thread to finish
1676 * being created, and as part of allocating a Thread object it might
1679 Thread* self = dvmThreadSelf();
1686 LOGW("internal thread create failed (createStatus=%d)", createStatus);
1694 /* thread could be in any state now (except early init states) */
1707 * thread, and we get cancelled abruptly when the VM shuts down, the
1745 * Tell the parent of our failure. We don't have a Thread struct,
1764 * Attach the current thread to the VM.
1770 Thread* self = NULL;
1777 /* allocate thread struct, and establish a basic sense of self */
1784 * Finish our thread prep. We need to do this before adding ourselves
1785 * to the thread list or invoking any interpreted code. prepareThread()
1786 * requires that we hold the thread list lock.
1799 * Create a "fake" JNI frame at the top of the main thread interp stack.
1808 * The native side of the thread is ready; add it to the list. Once
1809 * it's on the list the thread is visible to the JDWP code and the GC.
1829 * to the thread list, and is still going. That means our thread
1835 * Once we're in RUNNING, we're like any other thread in the VM (except
1846 * Create Thread and VMThread objects.
1861 * Create a string for the thread name.
1881 * We need to construct the Thread object and set the VMThread field.
1884 * Call the (group, name, priority, daemon) constructor on the Thread.
1885 * This sets the thread's name and adds it to the specified group, and
1887 * from the current thread).
1893 LOGE("exception thrown while constructing attached thread object");
1900 * The risk of a thread start collision here is very low; somebody
1903 * generally cause problems for all thread creation. However, for
1908 * fiddling with the field, or maybe initialize the Thread object in a
1909 * way that ensures another thread can't call start() on it.
1912 LOGW("WOW: thread start hijack");
1914 "thread has already been started");
1915 /* We don't want to free anything associated with the thread
1970 * Detach the thread from the various data structures, notify other threads
1978 * associated with the thread to be released. (Because the stack is empty,
1982 * We might want to avoid freeing our internal Thread structure until the
1983 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
1984 * get to once the thread shuts down, but there is a small possibility of
1985 * an operation starting in another thread before this thread halts, and
1986 * finishing much later (perhaps the thread got stalled by a weird OS bug).
1987 * We don't want something like Thread.isInterrupted() crawling through
1988 * freed storage. Can do with a Thread finalizer, or by creating a
1989 * dedicated ThreadObject class for java/lang/Thread and moving all of our
1994 Thread* self = dvmThreadSelf();
1999 * Make sure we're not detaching a thread that's still running. (This
2002 * A thread created by interpreted code will finish with a depth of
2003 * zero, while a JNI-attached thread will have the synthetic "stack
2019 LOGE("ERROR: detaching thread with interp frames (count=%d)",
2037 * Do some thread-exit uncaught exception processing if necessary.
2043 * Remove the thread from the thread group.
2053 * Clear the vmThread reference in the Thread object. Interpreted code
2054 * will now see that this Thread is not running. As this may be the
2063 /* clear out our struct Thread pointer, since it's going away */
2067 * Tell the debugger & DDM. This may cause the current thread or all
2071 * that it's issued by the dying thread, which may still appear in
2078 * Thread.join() is implemented as an Object.wait() on the VMThread
2099 * because if they do we'll end up reusing thread IDs. This complicates
2103 * We need to do this after Thread.join() completes, or other threads
2104 * could get wedged. Since self->threadObj is still valid, the Thread
2106 * list (which is important since the profiling thread needs to get
2107 * the thread's name).
2133 * Remove ourselves from the internal thread list.
2142 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2147 LOGV("threadid=%d: last non-daemon thread", self->threadId);
2166 * Suspend a single thread. Do not use to suspend yourself.
2169 * until the thread has suspended or is in a "safe" state (e.g. executing
2172 * The thread list lock should be held before calling here -- it's not
2173 * entirely safe to hang on to a Thread* from another thread otherwise.
2176 void dvmSuspendThread(Thread* thread)
2178 assert(thread != NULL);
2179 assert(thread != dvmThreadSelf());
2180 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2183 dvmAddToSuspendCounts(thread, 1, 1);
2186 thread->threadId, thread->suspendCount);
2189 waitForThreadSuspend(dvmThreadSelf(), thread);
2193 * Reduce the suspend count of a thread. If it hits zero, tell it to
2196 * Used primarily for debugger/DDMS activity. The thread in question
2199 * The thread list lock should be held before calling here -- it's not
2200 * entirely safe to hang on to a Thread* from another thread otherwise.
2203 void dvmResumeThread(Thread* thread)
2205 assert(thread != NULL);
2206 assert(thread != dvmThreadSelf());
2207 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2210 if (thread->suspendCount > 0) {
2211 dvmAddToSuspendCounts(thread, -1, -1);
2214 thread->threadId);
2218 thread->threadId, thread->suspendCount);
2220 if (thread->suspendCount == 0) {
2232 Thread* self = dvmThreadSelf();
2234 /* debugger thread must not suspend itself due to debugger activity! */
2257 * Tell JDWP that we've completed suspension. The JDWP thread can't
2275 * can happen if the debugger lets go while a SIGQUIT thread
2277 * just long enough to try to grab the thread-suspend lock).
2292 * Dump the state of the current thread and that of another thread that
2295 static void dumpWedgedThread(Thread* thread)
2300 // dumping a running thread is risky, but could be useful
2301 dvmDumpThread(thread, true);
2308 * If the thread is running at below-normal priority, temporarily elevate
2315 int dvmRaiseThreadPriorityIfNeeded(Thread* thread, int* pSavedThreadPrio,
2319 *pSavedThreadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2322 thread->threadId, thread->systemTid);
2325 if (get_sched_policy(thread->systemTid, pSavedThreadPolicy) != 0) {
2327 thread->threadId, thread->systemTid);
2337 if (set_sched_policy(thread->systemTid, SP_FOREGROUND) != 0) {
2338 LOGW("Couldn't set fg policy on tid %d", thread->systemTid);
2342 thread->systemTid, *pSavedThreadPolicy);
2352 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) != 0) {
2354 thread->systemTid, kHigher);
2358 thread->systemTid, *pSavedThreadPrio, kHigher);
2366 * Reset the priority values for the thread in question.
2368 void dvmResetThreadPriority(Thread* thread, int changeFlags,
2372 if (set_sched_policy(thread->systemTid, savedThreadPolicy) != 0) {
2374 thread->systemTid, savedThreadPolicy);
2377 thread->systemTid, savedThreadPolicy);
2382 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) != 0)
2384 LOGW("NOTE: couldn't reset priority on thread %d to %d",
2385 thread->systemTid, savedThreadPrio);
2388 thread->systemTid, savedThreadPrio);
2394 * Wait for another thread to see the pending suspension and stop running.
2400 * thread has a chance to finish what it's doing. Sleeping for too short
2405 * This does not return until the other thread has stopped running.
2411 * part of a debugger action in which the JDWP thread is always the one
2419 static void waitForThreadSuspend(Thread* self, Thread* thread)
2433 while (thread->status == THREAD_RUNNING) {
2440 * After waiting for a bit, check to see if the target thread is
2445 assert(thread->systemTid != 0);
2446 priChangeFlags = dvmRaiseThreadPriorityIfNeeded(thread,
2456 * 2) The top VM frame of the running thread is running JIT'ed code
2459 gDvmJit.hasNewChain && thread->inJitCodeCache) {
2460 LOGD("JIT unchain all for threadid=%d", thread->threadId);
2473 thread->threadId, priChangeFlags);
2476 dumpWedgedThread(thread);
2491 self->threadId, thread->threadId);
2493 /* try to get a debuggerd dump from the spinning thread */
2494 dvmNukeThread(thread);
2505 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2508 dvmResetThreadPriority(thread, priChangeFlags, savedThreadPrio,
2515 * the debugger, and by any thread that hits a "suspend all threads"
2518 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2519 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2527 * DO NOT grab any locks before calling here. We grab & release the thread
2531 * We know the current thread is in the thread list, because we attach the
2532 * thread before doing anything that could cause VM suspension (like object
2537 Thread* self = dvmThreadSelf();
2538 Thread* thread;
2543 * Start by grabbing the thread suspend lock. If we can't get it, most
2554 * This is possible if the current thread was in VMWAIT mode when a
2567 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2568 if (thread == self)
2571 /* debugger events don't suspend JDWP thread */
2573 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2576 dvmAddToSuspendCounts(thread, 1,
2590 * It's also okay if the thread transitions to a non-RUNNING state.
2593 * so if another thread is fiddling with its suspend count (perhaps
2597 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2598 if (thread == self)
2601 /* debugger events don't suspend JDWP thread */
2603 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2606 /* wait for the other thread to see the pending suspend */
2607 waitForThreadSuspend(self, thread);
2610 self->threadId, thread->threadId, thread->status,
2611 thread->suspendCount, thread->dbgSuspendCount);
2627 Thread* self = dvmThreadSelf();
2628 Thread* thread;
2637 * We do need to hold the thread list because of JNI attaches.
2641 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2642 if (thread == self)
2645 /* debugger events don't suspend JDWP thread */
2647 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2652 if (thread->suspendCount > 0) {
2653 dvmAddToSuspendCounts(thread, -1,
2659 thread->threadId);
2666 * In some ways it makes sense to continue to hold the thread-suspend
2669 * thread activity debug traces.
2674 * the thread performing the wakeup had an opportunity to release the
2675 * thread-suspend lock.
2677 * This is a problem because, when a thread tries to acquire that
2678 * lock, it times out after 3 seconds. If at some point the thread
2687 * returns, because we're holding the thread-suspend-count lock, but the
2688 * suspending thread is now able to make progress and we avoid the abort.
2691 * the thread-suspend lock and grab the thread-suspend-count lock.
2695 * lock before releasing thread-suspend, since we're still following
2720 Thread* self = dvmThreadSelf();
2721 Thread* thread;
2730 * We do need to hold the thread list because of JNI attaches.
2734 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2735 if (thread == self)
2738 /* debugger events don't suspend JDWP thread */
2739 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2740 assert(thread->dbgSuspendCount == 0);
2744 assert(thread->suspendCount >= thread->dbgSuspendCount);
2745 dvmAddToSuspendCounts(thread, -thread->dbgSuspendCount,
2746 -thread->dbgSuspendCount);
2766 * Determine if a thread is suspended.
2769 * the thread list lock before calling.
2771 * If the thread is suspending or waking, these fields could be changing
2772 * out from under us (or the thread
2776 bool dvmIsSuspended(const Thread* thread)
2779 * The thread could be:
2791 return (thread->suspendCount != 0 &&
2792 thread->status != THREAD_RUNNING);
2796 * Wait until another thread self-suspends. This is specifically for
2797 * synchronization between the JDWP thread and a thread that has decided
2800 * Threads that encounter "suspend all" events work as well -- the thread
2803 * We can't hold a thread lock here or in the caller, because we could
2804 * get here just before the to-be-waited-for-thread issues a "suspend all".
2805 * There's an opportunity for badness if the thread we're waiting for exits
2806 * and gets cleaned up, but since the thread in question is processing a
2810 void dvmWaitForSuspend(Thread* thread)
2812 Thread* self = dvmThreadSelf();
2815 self->threadId, thread->threadId);
2817 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2818 assert(thread != self);
2821 waitForThreadSuspend(self, thread);
2824 self->threadId, thread->threadId);
2833 static bool fullSuspendCheck(Thread* self)
2872 * thread, and return "true" after we have been resumed.
2874 bool dvmCheckSuspendPending(Thread* self)
2891 ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
2909 * us to be "asleep" in all other states, and another thread could
2915 * GCing thread Our thread (in NATIVE)
2922 * check thread state (== NATIVE)
2940 * progress could observe what appears to be a running thread (if
2943 * and thread logging. (We could work around it with some sort
2951 * accesses to status or the thread count require bit-fiddling).
2953 * the thread is supposed to be suspended. This is possibly faster
2980 * Get a statically defined thread group from a field in the ThreadGroup
3014 * Given a VMThread object, return the associated Thread*.
3016 * NOTE: if the thread detaches, the struct Thread will disappear, and
3017 * we will be touching invalid data. For safety, lock the thread list
3020 Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3027 Thread* thread = gDvm.threadList;
3028 while (thread != NULL) {
3029 if ((Thread*)vmData == thread)
3032 thread = thread->next;
3035 if (thread == NULL) {
3036 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list",
3037 vmThreadObj, (Thread*)vmData);
3042 return (Thread*) vmData;
3046 * Given a pthread handle, return the associated Thread*.
3047 * Caller must hold the thread list lock.
3049 * Returns NULL if the thread was not found.
3051 Thread* dvmGetThreadByHandle(pthread_t handle)
3053 Thread* thread;
3054 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
3055 if (thread->handle == handle)
3058 return thread;
3062 * Given a threadId, return the associated Thread*.
3063 * Caller must hold the thread list lock.
3065 * Returns NULL if the thread was not found.
3067 Thread* dvmGetThreadByThreadId(u4 threadId)
3069 Thread* thread;
3070 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
3071 if (thread->threadId == threadId)
3074 return thread;
3077 void dvmChangeThreadPriority(Thread* thread, int newPriority)
3079 os_changeThreadPriority(thread, newPriority);
3083 * Return true if the thread is on gDvm.threadList.
3086 bool dvmIsOnThreadList(const Thread* thread)
3091 if (thread == gDvm.threadList) {
3094 ret = thread->prev != NULL || thread->next != NULL;
3102 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3105 void dvmDumpThread(Thread* thread, bool isRunning)
3110 dvmDumpThreadEx(&target, thread, isRunning);
3211 * Print information about the specified thread.
3213 * Works best when the thread in question is "self" or has been suspended.
3214 * When dumping a separate thread that's still running, set "isRunning" to
3215 * use a more cautious thread dump function.
3217 void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3227 int priority; // java.lang.Thread priority
3233 * Get the java.lang.Thread object. This function gets called from
3235 * progress on some other thread. To decrease the chances of the
3236 * thread object being moved out from under us, we add the reference
3239 * If threadObj is NULL, the thread is still in the process of being
3243 threadObj = thread->threadObj;
3245 LOGI("Can't dump thread %d: threadObj not set", thread->threadId);
3262 if (getSchedulerGroup(thread->systemTid, schedulerGroupBuf,
3282 priority, thread->threadId, dvmGetThreadStatusStr(thread->status),
3284 thread->inJitCodeCache ? " JIT" : ""
3291 groupName, thread->suspendCount, thread->dbgSuspendCount,
3292 thread->threadObj, thread);
3295 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
3296 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
3300 if (!dvmGetThreadStats(&procStatData, thread->systemTid)) {
3305 /* grab the scheduler stats for this thread */
3307 thread->systemTid);
3326 dvmDumpRunningThreadStack(target, thread);
3328 dvmDumpThreadStack(target, thread);
3335 std::string dvmGetThreadName(Thread* thread) {
3336 if (thread->threadObj == NULL) {
3342 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3362 * If "grabLock" is true, we grab the thread lock list. This is important
3367 Thread* thread;
3383 thread = gDvm.threadList;
3384 while (thread != NULL) {
3385 dvmDumpThreadEx(target, thread, false);
3388 assert(thread->next == NULL || thread->next->prev == thread);
3390 thread = thread->next;
3398 * Nuke the target thread from orbit.
3400 * The idea is to send a "crash" signal to the target thread so that
3406 * thread has been nuked the rest of the system is likely to be unstable.
3409 * (This is NOT a way to simply cancel a thread.)
3411 void dvmNukeThread(Thread* thread)
3425 * thread and then the thread that calls dvmAbort. With SIGSEGV,
3428 * to just kill the process. The position in the current thread is
3431 * The target thread can continue to execute between the two signals.
3436 dvmThreadSelf()->threadId, thread->threadId, thread->systemTid);
3437 killResult = pthread_kill(thread->handle, SIGSTKFLT);
3442 killResult = pthread_kill(thread->handle, SIGSTKFLT);