📄 thread.h
字号:
/*
* Copyright (c) 1998-2001 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.
*
*/
/*=========================================================================
* 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
* 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
* the necessary information for implementing preemptive task
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -