vmthread.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 712 行 · 第 1/2 页

JAVA
712
字号
			case CREATED :
				return false;
			case RUNNING :
			case SUSPENDED :
			case WAITING :
			case ASLEEP :
			case YIELDING :
				return true;
			case STOPPED :
			case DESTROYED :
				return false;
			default :
				throw new RuntimeException("reality failure");
		}
	}

	/**
	 * Is this thread in the running state?
	 * @return boolean
	 * @throws PragmaUninterruptible
	 */
	public final boolean isRunning() throws PragmaUninterruptible {
		return (threadState == RUNNING);
	}

	/**
	 * Is this thread in the yielding state?
	 * @return boolean
	 * @throws PragmaUninterruptible
	 */
	public final boolean isYielding() throws PragmaUninterruptible {
		return (threadState == YIELDING);
	}

	/**
	 * Is this thread in the process of being stopped?
	 * @return boolean
	 */
	public final boolean isStopping() {
		return stopping;
	}

	/**
	 * Has this thread been interrupted?
	 * 
	 * @return boolean
	 */
	public final boolean isInterrupted() {
		return interrupted;
	}

	/**
	 * Is this thread waiting in a monitor?
	 * 
	 * @return boolean
	 */
	public final boolean isWaiting() {
		return (threadState == WAITING);
	}

	final int getThreadState() {
		return threadState;
	}
	
	public final String getThreadStateName() {
		return STATE_NAMES[threadState];
	}

	/**
	 * Call the run method of the (java version of) the given thread and when run returns, kill the
	 * given thread. This method is called by the native code that is setup by Unsafe.initThread.
	 * 
	 * @param thread
	 */
	protected static final void runThread(VmThread thread) 
	throws PragmaLoadStatics {
		try {
			thread.asThread().run();
		} catch (Throwable ex) {
			try {
				ex.printStackTrace();
			} catch (Throwable ex2) {
				/* Ignore */
			}
		} finally {
			try {
				thread.stop(new ThreadDeath());
			} catch (Throwable ex) {
				/* Ignore */
				while (true) {
					Unsafe.idle();
				}
			}
		}
	}

	/**
	 * Is it already time for me to wakeup?
	 * 
	 * @param curTime
	 * @return boolean
	 * @throws PragmaUninterruptible
	 */
	final boolean canWakeup(long curTime) throws PragmaUninterruptible {
		return (curTime >= wakeupTime);
	}

	/**
	 * Setup this thread to wait for the given monitor
	 * 
	 * @param monitor
	 * @throws PragmaUninterruptible
	 */
	final void prepareWait(Monitor monitor) throws PragmaUninterruptible {
		// Keep this order of assignments!
		this.waitForMonitor = monitor;
		this.threadState = WAITING;
	}

	/**
	 * Wake this thread up after being locked in the given monitor.
	 * 
	 * @param monitor
	 * @throws PragmaUninterruptible
	 */
	final void wakeupAfterMonitor(Monitor monitor) throws PragmaUninterruptible {
		if (this.threadState == WAITING) {
			final VmProcessor proc = Unsafe.getCurrentProcessor();
			proc.disableReschedule();
			try {
				this.threadState = RUNNING;
				proc.addToReadyQueue(this, false, "thread.wakeupAfterMonitor");
			} finally {
				proc.enableReschedule();
			}
		} else {
			Unsafe.debug("Oops thread was not waiting? threadState=" + threadState);
		}
	}

	/**
	 * This thread is selected as new thread by the scheduler. Set the thread state to running.
	 * @throws PragmaUninterruptible
	 */
	final void wakeUpByScheduler() throws PragmaUninterruptible {
		switch (threadState) {
			case ASLEEP :
			case RUNNING :
			case YIELDING :
				{
					// Do nothing
				}
				break;
			case WAITING :
				{
					final Monitor mon = this.waitForMonitor;
					mon.removeThreadFromQueues(this);
				}
				break;
			default :
				{
					Unsafe.debug("Incorrect threadState in wakeUpByScheduler ");
					Unsafe.debug(threadState);
				}
		}
		threadState = RUNNING;
	}

	/**
	 * @return int
	 */
	public final int getPriority() {
		return priority;
	}

	/**
	 * Sets the priority.
	 * 
	 * @param priority
	 *            The priority to set
	 */
	public void setPriority(int priority) {
		checkAccess();
		if ((priority < Thread.MIN_PRIORITY) || (priority > Thread.MAX_PRIORITY)) {
			throw new IllegalArgumentException("Invalid priority");
		}
		this.priority = priority;
	}

	/**
	 * Gets the stack of this thread
	 * @return The stack
	 */
	protected final Object getStack() {
		return stack;
	}

	/**
	 * Gets the size of the stack (of this thread) in bytes.
	 * @return The stack size
	 */
	public int getStackSize() {
		return stackSize;
	}

	/**
	 * Create a new (unique) thread identifier.
	 * @return The id
	 */
	private static synchronized int createId() {
		if (lastId == 0) {
			lastId = 8;
		}
		final int id = ++lastId;
		return id << ObjectFlags.THREAD_ID_SHIFT;
	}

	/**
	 * Gets the identifier of this thread. This identifier has already been shifted by
	 * THREAD_ID_SHIFT.
	 * 
	 * @see ObjectFlags#THREAD_ID_SHIFT
	 * @return The id
	 */
	public int getId() {
		return id;
	}
	
	/**
	 * @return
	 */
	boolean isStackOverflow() {
		return this.stackOverflow;
	}

	/**
	 * Verify the state of this thread.
	 * 
	 * @throws PragmaUninterruptible
	 */
	final void verifyState() throws PragmaUninterruptible {
		switch (threadState) {
			case CREATED :
				if (queueEntry.isInUse()) {
					throw new Error("Created thread cannot have an inuse queueEntry");
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Created thread cannot have an inuse sleepQueueEntry");
				}
				break;
			case ASLEEP :
				if (queueEntry.isInUse()) {
					throw new Error("Sleeping thread cannot have an inuse queueEntry");
				}
				if (!sleepQueueEntry.isInUse()) {
					throw new Error("Sleeping thread must have an inuse sleepQueueEntry");
				}
				break;
			case DESTROYED :
				if (queueEntry.isInUse()) {
					throw new Error("Destroyed thread cannot have an inuse queueEntry");
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Destroyed thread cannot have an inuse sleepQueueEntry");
				}
				break;
			case RUNNING :
				if (!queueEntry.isInUse()) {
					if (Unsafe.getCurrentProcessor().getCurrentThread() != this) {
						throw new Error("Running thread must be inuse on ready queue or current thread");
					}
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Running thread cannot have an inuse sleepQueueEntry");
				}
				break;
			case STOPPED :
				if (queueEntry.isInUse()) {
					throw new Error("Stopped thread cannot have an inuse queueEntry");
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Stopped thread cannot have an inuse sleepQueueEntry");
				}
				break;
			case SUSPENDED :
				if (queueEntry.isInUse()) {
					throw new Error("Suspended thread cannot have an inuse queueEntry");
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Suspended thread cannot have an inuse sleepQueueEntry");
				}
				break;
			case WAITING :
				if (waitForMonitor == null) {
					throw new Error("Waiting thread must have a waitForMonitor");
				}
				if (!queueEntry.isInUse()) {
					throw new Error("Waiting thread must have an inuse queueEntry");
				}
				break;
			case YIELDING :
				if (!queueEntry.isInUse()) {
					throw new Error("Yielding thread must have an inuse queueEntry");
				}
				if (sleepQueueEntry.isInUse()) {
					throw new Error("Yielding thread cannot have an inuse sleepQueueEntry");
				}
				break;
			default :
				throw new Error("Unknown thread state " + threadState);
		}
	}

	/**
	 * Convert to a String representation.
	 * 
	 * @see java.lang.Object#toString()
	 * @return String
	 */
	public String toString() {
		if (javaThread != null) {
			return "%" + javaThread.getName() + ", st" + STATE_NAMES[threadState] + "%";
		} else {
			return "%@null@, st" + threadState + "%";
		}
	}
	
	/**
	 * Gets the most current stackframe of this thread.
	 * This method is only valid when this thread is not running.
	 * @return The stack frame
	 */
	protected abstract Address getStackFrame();
	
	/**
	 * Gets the most current instruction pointer of this thread.
	 * This method is only valid when this thread is not running.
	 * @return The instruction pointer
	 */
	protected abstract Address getInstructionPointer();

	/**
	 * Calculate the end of the stack. 
	 * @param stack
	 * @param stackSize
	 * @return End address of the stack
	 */
	protected abstract Address getStackEnd(Object stack, int stackSize);
	
	/**
	 * Gets a human readable representation of the system exception state.
	 * @return String
	 */
	public abstract String getReadableErrorState();
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?