vmthread.java
来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 712 行 · 第 1/2 页
JAVA
712 行
/**
* $Id: VmThread.java,v 1.5 2004/02/24 08:04:48 epr Exp $
*/
package org.jnode.vm;
import org.jnode.vm.classmgr.ObjectFlags;
/**
* VM thread implementation
*
* @author Ewout Prangsma (epr@users.sourceforge.net)
*/
public abstract class VmThread extends VmSystemObject {
/**
* If the stackpointer grows to this distance from the size of the stack, a stack overflow
* exception is raised.
*/
public static final int STACK_OVERFLOW_LIMIT = 1024;
public static final int DEFAULT_STACK_SIZE = 48 * 1024;
/** A link to my java.lang.Thread */
private Thread javaThread;
/** Next pointer used in queues */
protected final VmThreadQueueEntry queueEntry = new VmThreadQueueEntry(this);
protected final VmThreadQueueEntry sleepQueueEntry = new VmThreadQueueEntry(this);
/** The size (in bytes) of the stack of this thread */
private int stackSize;
/** The pointer to the stack */
private Object stack;
/** The pointer to end of the stack (used by native code) */
volatile Address stackEnd;
/** Has this thread had a stackoverflow? */
private boolean stackOverflow;
/** The current state of this thread */
private int threadState = CREATED;
/** When to wakeup (if sleeping) */
protected long wakeupTime;
/** The monitor i'm waiting for */
private Monitor waitForMonitor;
/** My priority */
protected int priority = Thread.NORM_PRIORITY;
/** Identifier of this thread */
private final int id;
/** Identifier of the last created thread */
private static int lastId;
/** Has this thread been interrupted? */
private boolean interrupted;
/** Is this thread in an exception initialization? */
boolean inException;
/** Is this thread in the process of being stopped? */
private boolean stopping;
/**
* State is set to CREATED by the static initializer. Once set to other than CREATED, it should
* never go back. Alternates between RUNNING and SUSPENDED/WAITING as suspend()/wait() and
* reseume() are called.
* <p>
* Can be set to INTERRUPTED if ASLEEP, or WAITING. Can be set to DESTROYED at any time. Can be
* set to STOPPED at any time.
* <p>
* If a Thread blocks in a wait(), its state stays as RUNNING. This might need to change.
* <p>
* Can sleep if RUNNING. <blockquote>
*
* <pre>
* /--------------------\ V | CREATED -> RUNNING -> SUSPENDED /
* </blockquote></pre>
*/
private final static int CREATED = 0;
private final static int ASLEEP = 3;
private final static int DESTROYED = 5;
private final static int RUNNING = 1;
private final static int STOPPED = 4;
private final static int SUSPENDED = 2;
private final static int WAITING = 6;
private final static int YIELDING = 7;
final static int MAXSTATE = YIELDING;
final static String[] STATE_NAMES = { "CREATED", "RUNNING", "SUSPENDED", "ASLEEP", "STOPPED", "DESTROYED", "WAITING", "YIELDING" };
/**
* Create a new instance. This constructor can only be called during the bootstrap phase.
*/
public VmThread() {
this.threadState = RUNNING;
this.stackSize = DEFAULT_STACK_SIZE;
this.id = (1 << ObjectFlags.THREAD_ID_SHIFT);
}
/**
* Create a new instance.
*
* @param javaThread
*/
public VmThread(Thread javaThread) {
this.javaThread = javaThread;
this.threadState = CREATED;
this.stackSize = DEFAULT_STACK_SIZE;
this.id = createId();
}
/**
* Return the current thread
* @return The current thread
*/
public static VmThread currentThread() {
return Unsafe.getCurrentProcessor().getCurrentThread();
}
/**
* Initialize the threading system.
*/
static void initialize() {
// Ensure that we have a java.lang.Thread object for the root thread.
final VmThread currentThread = currentThread();
currentThread.asThread();
lastId = currentThread.id;
}
/**
* Count the number of stackframes in this thread.
*
* @return int
*/
public final int countStackFrames() {
final VmProcessor proc = Unsafe.getCurrentProcessor();
final VmStackReader reader = proc.getArchitecture().getStackReader();
return reader.countStackFrames(Unsafe.getCurrentFrame());
}
/**
* Get the Thread to which this VmThread belongs
* @return The java thread
*/
public final Thread asThread() {
if (javaThread == null) {
javaThread = new Thread(this);
}
return javaThread;
}
/**
* Has this object already a reference to a java.lang.Thread object?
* @return boolean
*/
public final boolean hasJavaThread() {
return (javaThread != null);
}
final void checkAccess() {
asThread().checkAccess();
}
public final void start() {
switch (threadState) {
case CREATED :
{
//Screen.debug("thread.start");
stack = VmSystem.allocStack(stackSize);
Unsafe.initThread(this, stack, stackSize);
stackEnd = getStackEnd(stack, stackSize);
threadState = RUNNING;
final VmProcessor proc = Unsafe.getCurrentProcessor();
proc.addToReadyQueue(this, false, "thread.start");
}
break;
case RUNNING :
case SUSPENDED :
case WAITING :
case ASLEEP :
throw new IllegalThreadStateException("already started");
case STOPPED :
/* XXX */
break;
case DESTROYED :
throw new IllegalThreadStateException("destroyed");
default :
throw new IllegalThreadStateException("Unknown thread state");
}
}
/**
* Stop the thread permanently.
*
* @param ex
* @throws PragmaUninterruptible
*/
public final void stop(Throwable ex) throws PragmaUninterruptible {
this.stopping = true;
if (javaThread != null) {
javaThread.onExit();
}
final VmProcessor proc = Unsafe.getCurrentProcessor();
final VmThread current = proc.getCurrentThread();
proc.disableReschedule();
this.threadState = STOPPED;
if (current == this) {
proc.suspend();
} else {
proc.enableReschedule();
}
}
/**
* Destroys this thread, without any cleanup. Any monitors it has locked remain locked. (This
* method is not implemented.)
*/
public final void destroy() {
}
/**
* Interrupt this thread.
* @throws PragmaUninterruptible
*/
public final void interrupt() throws PragmaUninterruptible {
final VmProcessor proc = Unsafe.getCurrentProcessor();
proc.disableReschedule();
try {
switch (threadState) {
case ASLEEP :
case WAITING :
{
// Set interrupted state
this.interrupted = true;
// Remove from queues
wakeUpByScheduler();
// Add to ready queue
proc.addToReadyQueue(this, false, "thread.interrupt");
}
break;
}
} finally {
proc.enableReschedule();
}
}
/**
* Test the interruption status. If interrupted, the interrupted status is cleared and an
* InterruptedException is thrown, otherwise this method returns without any change in state.
*
* @throws PragmaUninterruptible
* @throws InterruptedException
*/
final void testAndClearInterruptStatus() throws PragmaUninterruptible, InterruptedException {
final boolean throwIE = this.interrupted;
if (throwIE) {
this.interrupted = false;
throw new InterruptedException();
}
}
/**
* Resume this thread.
*/
public final void resume() {
checkAccess();
if (threadState != SUSPENDED) {
throw new IllegalThreadStateException("Not suspended");
} else {
final VmProcessor proc = Unsafe.getCurrentProcessor();
threadState = RUNNING;
proc.addToReadyQueue(this, false, "thread.resume");
}
}
/**
* Suspend this thread.
* @throws PragmaUninterruptible
*/
public final void suspend() throws PragmaUninterruptible {
checkAccess();
if (threadState != RUNNING) {
throw new IllegalThreadStateException("Not running");
} else {
final VmProcessor proc = Unsafe.getCurrentProcessor();
proc.disableReschedule();
this.threadState = SUSPENDED;
proc.suspend();
}
}
/**
* Give up the CPU.
*/
public static void yield() {
final VmProcessor proc = Unsafe.getCurrentProcessor();
proc.yield(false);
}
/**
* Set the state to YIELDING.
* @throws PragmaUninterruptible
*/
final void setYieldingState() throws PragmaUninterruptible {
if (threadState == RUNNING) {
threadState = YIELDING;
}
}
/**
* Go to sleep for the given period.
* @param millis
* @param nanos
* @throws InterruptedException
* @throws PragmaUninterruptible
*/
public final void sleep(long millis, int nanos) throws InterruptedException, PragmaUninterruptible {
if (currentThread() != this) {
return;
}
if (threadState != RUNNING) {
return;
}
final VmProcessor proc = Unsafe.getCurrentProcessor();
proc.disableReschedule();
this.wakeupTime = VmSystem.currentKernelMillis() + millis;
this.threadState = ASLEEP;
proc.addToSleepQueue(this);
/* Now un-schedule myself */
proc.suspend();
/* We're back alive */
testAndClearInterruptStatus();
}
/**
* Returns <code>true</code> if the thread represented by this object is running (including
* suspended, asleep, or interrupted). Returns <code>false</code> if the thread hasn't be
* started yet, is stopped or destroyed.
*
* @return <code>true</code> if thread is alive, <code>false</code> if not.
* @see #start()
* @see #stop(Throwable)
* @see #suspend()
* @see #interrupt()
*/
public final boolean isAlive() {
switch (threadState) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?