📄 thread.h
字号:
/* * Copyright (c) 1998-2002 Sun Microsystems, Inc. All Rights Reserved. * * This software is the confidential and proprietary information of Sun * Microsystems, Inc. ("Confidential Information"). You shall not * disclose such Confidential Information and shall use it only in * accordance with the terms of the license agreement you entered into * with Sun. * * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING * THIS SOFTWARE OR ITS DERIVATIVES. * * Use is subject to license terms. *//*========================================================================= * SYSTEM: KVM * SUBSYSTEM: Thread (concurrency) management * FILE: thread.h * OVERVIEW: This file defines the structures that are needed * for Java-style multithreading. * AUTHOR: Antero Taivalsaari, Sun Labs, 1998 * Edited by Doug Simon 11/1998 * Edited by Nik Shaylor 09/1999 to allow asynchronous I/O * Frank Yellin (new monitors), Bill Pittore (debugging) *=======================================================================*//*========================================================================= * ORIGINAL COMMENTS (PRE-KVM 1.0) * * KVM has a machine-independent, portable, pre-emptive * threading model that is capable of operating independently * of the Java language. * * A simple round-robin style scheduling model is used, in which * all the active threads in the system are stored in a circular * linked list. * * Threads in the list are given execution time one after each other * based on the Java-level priority of each task. At the implementation * level thread priority is simply an integer that tells to the * interpreter how many primitives the thread may execute until the * next thread switch takes place. After each bytecode execution, * the "timeslice" counter of the thread is decremented. When * timeslice becomes zero, a thread switch is forced. Some I/O * primitives may also initiate a thread switch. *=======================================================================*//*========================================================================= * NEW COMMENTS (KVM 1.0) * ====================== * * The thread model described above has been changed a little to allow * asynchronous (non-blocking) I/O to be supported by the VM. * * An additional goal was to introduce the ability to easily implement * alternative scheduling mechanisms, but without changing the existing * system too radically. * * In the original system context switching occurred in a number of places. * Now it is only ever done at the top of the interpreter dispatch loop. * In the original version, runnable threads were kept in a circular list * with the currently executing one. Now each thread is removed from the * circular list of runnable threads when the thread starts executing and * is returned there when it is blocked. * * The variable UP has been renamed CurrentThread and it points to the * currently executing thread. A new variable RunnableThreads points to * the circular list of runnable threads. * * NOTE: RunnableThreads points to the >>last<< item on the circular queue. * This makes it easy to add items to either the front or back of the queue. * * Important routine changes: * * suspendThread() * --------------- * * This used to have a parameter of which thread to suspend, but there is no * case in which it cannot be UP so the parameter has been removed. This * routine used to perform a context switch, but now it just zeros * CurrentThread and calls a new function called signalTimeToReschedule() * which signals to the interpreter that it should reschedule the VM before * the next bytecode is executed. * * A new function isTimeToReshedule() is provided for the interpreter to * test this condition, and a new function reschedule() is called to do * this. The code at the top of the interpreter bytecode dispatch loop is now: * * if (isTimeToReshedule()) { * reschedule(); * } * * Because of the time critical nature of this part of the VM these two * functions are implemented as macros. The current version of * isTimeToReshedule() expands to "Timeslice-- == 0" which is identical * to the code in the original threading system. The function * signalTimeToReschedule() simply sets Timeslice to zero. * * startThread() * ------------- * * This makes a thread alive, but suspended (ie. doesn't start * execution immediately). * * resumeThread() * --------------- * * This function places a thread back on the runnable thread list * (RunnableThreads) and will also call signalTimeToReschedule() if the * priority of the activated thread is higher than the priority of * currently executing thread. * * The new thread is put in the RunnableThreads list in a position where * it will be the next one to be executed. Unlike the earlier thread * scheduling mechanism, this will allow higher priority threads to * get switched to immediately in an interrupt driven environment. * * The intention of this change is to implement a more conventional * event driven priority scheduling mechanism. This was the primary * motivation for removing the active thread from the runnable queue * when it is executing. We can now completely change the format of * the runnable queue without affecting the rest of the system. * * BuildThread() * ------------- * * This now adds all new threads to another list of all alive threads called * AllThreads. This list is used by the garbage collector. * * DismantleThread() * ----------------- * * Removes the thread from the AllThreads list. * * stopThread() * ------------ * * This function is the logical opposite to BuildThread(). It suspends the * thread and calls DismantleThread(). * * resumeThread() * --------------- * * This replaces the use of activateThread() to restart a suspended thread. * * isActivated() * ------------- * * It used to be necessary to test that CurrentThread was non-null before * calling this routine. * * HandleEvent() * ------------- * * Because the original HandleEvent routine called activateThread it did * not require any changes (except for the calling convention for * isActivated()). However, the meaning of the return parameter is * now slightly different in that is indicates that a new thread was * added to RunnableThreads and not that it just switched context. * * SwitchThread() * --------------- * * SwitchThread is now only called from reschedule(). CurrentThread may or * may not point to a thread. If it does we rotate the thread through the * RunnableThreads list as before. If it is null and the RunnableThreads * list is empty then the function returns FALSE and reschedule() must * decide what to do. On the Palm it does a wait forever for the next event. * * JLT_Yield() * ----------- * * Now only has to call signalTimeToReschedule() * * * Asynchronous I/O (optional feature) * =================================== * * The basic thread management strategy of KVM is unchanged in that * all the Java code is executed by the same native thread, and all * Java thread context switching is done internally using the * original 'green thread' concept. This is generally the preferred * multithreading mechanism for KVM. * * Asynchronous I/O is an optional KVM feature that can be used * if the underlying operating system provides the necessary * support, e.g., in the form of interrupts, callback routines, * or native threads. However, be aware that the use of * asynchronous I/O involves a substantial amount of additional * work and complexity. * * When the author of a Java native function wants to allow the * interpreter to execute while the I/O is being performed, he * should call suspendThread(), then set up the appropriate * platform dependent mechanism to be notified of the I/O * completion, and then return. >>> It is very important that * the call to suspendThread() occurs before the callback * routine is run. <<< * * When the callback routine executes, it will almost always wants * to push some result on the stack of the suspended thread, and * then call resumeThread(). * * When a native function is called in KVM, it is generally running * in the context of the calling thread. This is not the case when * a callback routine (or whatever mechanism you are using to * report the results of an asynchronous call) is called. Therefore, * the normal stack access functions and macros (popStack() etc.) * cannot be used when writing callback routines. To solve this * problem, special new versions of these stack manipulation * functions are provided. These new routines all have an additional * "FromThread" parameter to indicate the requested context. For * instance, popStack() becomes popStackFromThread(THREAD* FromThread). * Using these new, alternative macros, the thread's stack can * be set up with the appropriate parameters prior to calling * activateThread(). * * An additional problem with asynchronous I/O is the possibility * of a race condition. To prevent a race condition corrupting the * RunnableThreads queue, which links asynchronous world outside * the VM with its internal rescheduling functions, all accesses * to this queue much be interlocked with a critical section. * Therefore, two new platform dependent functions have been * defined: * * enterSystemCriticalSection() * * and * * exitSystemCriticalSection() * *=======================================================================*//*========================================================================= * NEW COMMENTS (KVM 1.0.3) * ======================== * * KVM 1.0.3 has a new monitor/synchronization implementation. * Read the description later in this file. Otherwise, there * are no significant multithreading changes between KVM 1.0 * and KVM 1.0.3. *=======================================================================*//*========================================================================= * Global definitions and variables needed for multitasking *=======================================================================*/#ifndef __THREAD_H__#define __THREAD_H__extern THREAD CurrentThread; /* Current thread */extern THREAD MainThread; /* For debugger code to access */extern THREAD AllThreads; /* List of all threads */extern THREAD RunnableThreads; /* Queue of all threads that can be run */extern int AliveThreadCount; /* Number of alive threads */extern int Timeslice; /* Time slice counter for multitasking */#define areActiveThreads() (CurrentThread != NULL || RunnableThreads != NULL)#define areAliveThreads() (AliveThreadCount > 0)#define MAX_PRIORITY 10 /* These constants must be the same */#define NORM_PRIORITY 5 /* as those defined in Thread.java */#define MIN_PRIORITY 1/*========================================================================= * Global multitasking operations *=======================================================================*/void storeExecutionEnvironment(THREAD thisThread); /* Context save */void loadExecutionEnvironment(THREAD thisThread); /* Context restore */bool_t SwitchThread(void);/*========================================================================= * Thread data structures and operations *=======================================================================*//*========================================================================= * Thread instance data structures: * * One of the structures below is instantiated * for every thread (task) in the system: * * - THREAD is an internal (VM-level) structure that is used for storing
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -