📄 thread.c
字号:
if (!(thisThread->state & THREAD_SUSPENDED) && !(thisThread->state & THREAD_JUST_BORN)) { thisThread->state |= THREAD_SUSPENDED; resumeThread(thisThread); } }}#endif /* ENABLE_JAVA_DEBUGGER *//*========================================================================= * FUNCTION: activeThreadCount * TYPE: public global operations * OVERVIEW: Returns the number of threads ready to run. * INTERFACE: * parameters: <none> * returns: int *=======================================================================*/int activeThreadCount() { return (CurrentThread ? 1 : 0) + queueLength(RunnableThreads);}/*========================================================================= * FUNCTION: isActivated() * TYPE: public instance-level operation * OVERVIEW: Check if a thread is active * INTERFACE: * parameters: thread pointer * returns: TRUE if the task is active, FALSE otherwise. *=======================================================================*/int isActivated(THREAD thread){ if (thread == NIL) { return FALSE; } else { int state = thread->state; return (state & THREAD_ACTIVE) || (state & THREAD_SUSPENDED); }}/*========================================================================= * FUNCTION: removeFirstRunnableThread() * OVERVIEW: Return (and remove) the first runnable * thread of the queue. * INTERFACE: * parameters: <none> * returns: A THREAD object. *=======================================================================*/#if ENABLE_JAVA_DEBUGGERTHREAD removeFirstRunnableThread(){ return removeQueueStart(&RunnableThreads);}#endif /* ENABLE_JAVA_DEBUGGER *//*========================================================================= * Asynchronous threading operations (optional) *=======================================================================*//*========================================================================= * FUNCTION: asyncFunctionProlog() * TYPE: Public link routine for asynchronous native methods * OVERVIEW: Call an asynchronous native method * INTERFACE: * parameters: thread pointer, native function pointer * returns: <nothing> * * Note: This is just an example implementation for demonstration purposes. * and does not actually work very well because eventually the WIN32 * program seems to run out of thread resources and no new threads * seem to run. Typically no error code is ever returned! * *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSstatic int AsyncThreadCount = 0; /* Number of asynchronously */ /* running I/O threads */static int collectorIsRunning = FALSE; /* Flag to show the GC is active */void asyncFunctionProlog() { /* * The garbage collector cannot be running because the calling thread is * the main system thread and the GC is only ever run on this thread * so the following is just a safety check. */ if (collectorIsRunning) { fatalError(KVM_MSG_COLLECTOR_IS_RUNNING_ON_ENTRY_TO_ASYNCFUNCTIONPROLOG); } suspendThread(); /* Suspend the current thread */ START_CRITICAL_SECTION AsyncThreadCount++; END_CRITICAL_SECTION}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * FUNCTION: asyncFunctionEpilog() * TYPE: Public link routine for asynchronous native methods * OVERVIEW: Spin until all asynchronous I/O is finished * INTERFACE: * parameters: A THREAD * returns: <nothing> *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSvoid asyncFunctionEpilog(THREAD thisThread) { resumeThread(thisThread); START_CRITICAL_SECTION --AsyncThreadCount; NATIVE_FUNCTION_COMPLETED(); END_CRITICAL_SECTION}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * FUNCTION: decrementAsyncCount() * TYPE: Public link routine for asynchronous native methods * OVERVIEW: Allow the garbage collector to run during async I/O * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSvoid decrementAsyncCount() { START_CRITICAL_SECTION --AsyncThreadCount; END_CRITICAL_SECTION}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * FUNCTION: incrementAsyncCount() * TYPE: Public link routine for asynchronous native methods * OVERVIEW: Disallow the garbage collector to run during async I/O * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSvoid incrementAsyncCount() { bool_t yield = TRUE; while (yield) { START_CRITICAL_SECTION if(!collectorIsRunning) { ++AsyncThreadCount; yield = FALSE; } END_CRITICAL_SECTION if(yield) { Yield_md(); } }}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * FUNCTION: RundownAsynchronousFunctions() * TYPE: Public routine for garbage collector * OVERVIEW: Spin until all asynchronous I/O is finished * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSvoid RundownAsynchronousFunctions(void) { for (;;) { if (collectorIsRunning) { fatalError(KVM_MSG_COLLECTOR_RUNNING_IN_RUNDOWNASYNCHRONOUSFUNCTIONS); } START_CRITICAL_SECTION if (AsyncThreadCount == 0) { collectorIsRunning = TRUE; } END_CRITICAL_SECTION if (collectorIsRunning) { break; } /* Wait */ Yield_md(); }}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * FUNCTION: RestartAsynchronousFunctions() * TYPE: Public routine for garbage collector * OVERVIEW: Allow asynchronous I/O to continue * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/#if ASYNCHRONOUS_NATIVE_FUNCTIONSvoid RestartAsynchronousFunctions(void) { if (!collectorIsRunning) { fatalError(KVM_MSG_COLLECTOR_NOT_RUNNING_ON_ENTRY_TO_RESTARTASYNCHRONOUSFUNCTIONS); } collectorIsRunning = FALSE;}#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS *//*========================================================================= * Thread debugging operations *=======================================================================*/#if INCLUDEDEBUGCODE/*========================================================================= * FUNCTION: printThreadStatus() * TYPE: public thread instance-level operation * OVERVIEW: Print the status of given thread for debugging purposes. * INTERFACE: * parameters: thread pointer * returns: <nothing> *=======================================================================*/static voidprintThreadStatus(THREAD thisThread){ fprintf(stdout, "Thread %lx status:\n", (long)thisThread); if (thisThread == CurrentThread) { fprintf(stdout, "ACTIVE (CurrentThread)\n"); /* To print most up-to-date information we need to do this */ storeExecutionEnvironment(CurrentThread); } else { fprintf(stdout, "%s\n", isActivated(thisThread) ? "ACTIVE (DORMANT)" : "SUSPENDED"); } fprintf(stdout, "Timeslice: %ld, Priority: %ld\n", thisThread->timeslice, thisThread->javaThread->priority); fprintf(stdout, "Instruction pointer: %lx\n", (long)thisThread->ipStore); fprintf(stdout, "Execution stack location: %lx\n", (long)thisThread->stack); fprintf(stdout, "Execution stack pointer: %lx \n", (long)(thisThread->spStore)); fprintf(stdout, "Frame pointer: %lx \n", (long)(thisThread->fpStore)); fprintf(stdout, "JavaThread: %lx VMthread: %lx\n", (long)thisThread->javaThread, (long)thisThread->javaThread->VMthread); if (thisThread->monitor != NULL) { fprintf(stdout, "Waiting on monitor %lx %lx\n", (long)thisThread->monitor, (long)thisThread->monitor->object); } if (inTimerQueue(thisThread)) { fprintf(stdout, "In timer queue\n"); } fprintf(stdout, "\n\n");}/*========================================================================= * FUNCTION: printFullThreadStatus() * TYPE: public thread instance-level operation * OVERVIEW: Print the status of all the active threads in the system. * INTERFACE: * parameters: <none> * returns: <nothing> *=======================================================================*/void printFullThreadStatus(void){ THREAD thisThread; int threadCount = 0; for (thisThread = AllThreads; thisThread != NULL; thisThread = thisThread->nextAliveThread) { fprintf(stdout, "Thread #%d\n", ++threadCount); printThreadStatus(thisThread); }}#endif /* INCLUDEDEBUGCODE *//*========================================================================= * Timer implementation *=======================================================================*//* Threads waiting for a timer interrupt */THREAD TimerQueue;/*========================================================================= * Timer operations *=======================================================================*//*========================================================================= * FUNCTION: registerAlarm() * TYPE: timer queue * OVERVIEW: Perform a callback on this thread * INTERFACE: * parameters: The thread pointer * The time in the future at which the callback should be called * The callback function * returns: no value *=======================================================================*/voidregisterAlarm(THREAD thread, long64 delta, void (*wakeupCall)(THREAD)){#if NEED_LONG_ALIGNMENT Java8 tdub;#endif THREAD q, prev_q; ulong64 wakeupTime; /* * First see if this thread is on the queue already. This can happen * if the thread was suspended by the debugger code, and there was a * wakeup pending. Then if the user resumes this thread it could try to * register another wakeup before this one happens. This is rather * simple minded since what if the second call is registering a different * callback? This whole subsystem should be re-written slightly to * handle a list of callbacks I suppose. */ q = TimerQueue; while (q != NULL) { if (q == thread) return; /* already on the queue so leave */ q = q->nextAlarmThread; } /* set wakeupTime to now + delta. Save this value in the thread */ wakeupTime = CurrentTime_md(); ll_inc(wakeupTime, delta); /* wakeUp += delta */ SET_ULONG(thread->wakeupTime, wakeupTime);#if INCLUDEDEBUGCODE if (tracethreading) { TraceThread(thread, "Adding to timer queue"); }#endif /* Save the callback function in the thread */ thread->wakeupCall = wakeupCall; /* insert this value into the clock queue, which is sorted by wakeup time.*/ q = TimerQueue; prev_q = NULL; while (q != NULL) { ulong64 qtime = GET_ULONG(q->wakeupTime); if (ll_compare_ge(qtime, wakeupTime)) { break; } prev_q = q; q = q->nextAlarmThread; } if (prev_q != NULL) { /* This is the first item in the queue. */ prev_q->nextAlarmThread = thread;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -