📄 thread.h
字号:
/*0001*//*
/*0002./ * Copyright (c) 1998-2001 Sun Microsystems, Inc. All Rights Reserved.
/*0003./ *
/*0004./ * This software is the confidential and proprietary information of Sun
/*0005./ * Microsystems, Inc. ("Confidential Information"). You shall not
/*0006./ * disclose such Confidential Information and shall use it only in
/*0007./ * accordance with the terms of the license agreement you entered into
/*0008./ * with Sun.
/*0009./ *
/*0010./ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
/*0011./ * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
/*0012./ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
/*0013./ * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
/*0014./ * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
/*0015./ * THIS SOFTWARE OR ITS DERIVATIVES.
/*0016./ *
/*0017./ */
/*0018*/
/*0019*//*=========================================================================
/*0020./ * SYSTEM: KVM
/*0021./ * SUBSYSTEM: Thread (concurrency) management
/*0022./ * FILE: thread.h
/*0023./ * OVERVIEW: This file defines the structures that are needed
/*0024./ * for Java-style multithreading.
/*0025./ * AUTHOR: Antero Taivalsaari, Sun Labs
/*0026./ * Edited by Doug Simon 11/1998
/*0027./ * Edited by Nik Shaylor 09/1999 to allow asynchronous I/O
/*0028./ * Frank Yellin (new monitors), Bill Pittore (debugging)
/*0029./ *=======================================================================*/
/*0030*/
/*0031*//*=========================================================================
/*0032./ * ORIGINAL COMMENTS (PRE-KVM 1.0)
/*0033./ *
/*0034./ * KVM has a machine-independent, portable, pre-emptive
/*0035./ * threading model that is capable of operating independently
/*0036./ * of the Java language.
/*0037./ *
/*0038./ * A simple round-robin style scheduling model is used, in which
/*0039./ * all the active threads in the system are stored in a circular
/*0040./ * linked list.
/*0041./ *
/*0042./ * Threads in the list are given execution time one after each other
/*0043./ * based on the Java-level priority of each task. At the implementation
/*0044./ * level thread priority is simply an integer that tells to the
/*0045./ * interpreter how many primitives the thread may execute until the
/*0046./ * next thread switch takes place. After each bytecode execution,
/*0047./ * the "timeslice" counter of the thread is decremented. When
/*0048./ * timeslice becomes zero, a thread switch is forced. Some I/O
/*0049./ * primitives may also initiate a thread switch.
/*0050./ *=======================================================================*/
/*0051*/
/*0052*//*=========================================================================
/*0053./ * NEW COMMENTS (KVM 1.0)
/*0054./ * ======================
/*0055./ *
/*0056./ * The thread model described above has been changed a little to allow
/*0057./ * asynchronous (non-blocking) I/O to be supported by the VM.
/*0058./ *
/*0059./ * An additional goal was to introduce the ability to easily implement
/*0060./ * alternative scheduling mechanisms, but without changing the existing
/*0061./ * system too radically.
/*0062./ *
/*0063./ * In the original system context switching occurred in a number of places.
/*0064./ * Now it is only ever done at the top of the interpreter dispatch loop.
/*0065./ * In the original version, runnable threads were kept in a circular list
/*0066./ * with the currently executing one. Now each thread is removed from the
/*0067./ * circular list of runnable threads when the thread starts executing and
/*0068./ * is returned there when it is blocked.
/*0069./ *
/*0070./ * The variable UP has been renamed CurrentThread and it points to the
/*0071./ * currently executing thread. A new variable RunnableThreads points to
/*0072./ * the circular list of runnable threads.
/*0073./ *
/*0074./ * NOTE: RunnableThreads points to the >>last<< item on the circular queue.
/*0075./ * This makes it easy to add items to either the front or back of the queue.
/*0076./ *
/*0077./ * Important routine changes:
/*0078./ *
/*0079./ * suspendThread()
/*0080./ * ---------------
/*0081./ *
/*0082./ * This used to have a parameter of which thread to suspend, but there is no
/*0083./ * case in which it cannot be UP so the parameter has been removed. This
/*0084./ * routine used to perform a context switch, but now it just zeros
/*0085./ * CurrentThread and calls a new function called signalTimeToReschedule()
/*0086./ * which signals to the interpreter that it should reschedule the VM before
/*0087./ * the next bytecode is executed.
/*0088./ *
/*0089./ * A new function isTimeToReshedule() is provided for the interpreter to
/*0090./ * test this condition, and a new function reschedule() is called to do
/*0091./ * this. The code at the top of the interpreter bytecode dispatch loop is now:
/*0092./ *
/*0093./ * if (isTimeToReshedule()) {
/*0094./ * reschedule();
/*0095./ * }
/*0096./ *
/*0097./ * Because of the time critical nature of this part of the VM these two
/*0098./ * functions are implemented as macros. The current version of
/*0099./ * isTimeToReshedule() expands to "Timeslice-- == 0" which is identical
/*0100./ * to the code in the original threading system. The function
/*0101./ * signalTimeToReschedule() simply sets Timeslice to zero.
/*0102./ *
/*0103./ * startThread()
/*0104./ * -------------
/*0105./ *
/*0106./ * This makes a thread alive, but suspended (ie. doesn't start
/*0107./ * execution immediately).
/*0108./ *
/*0109./ * resumeThread()
/*0110./ * ---------------
/*0111./ *
/*0112./ * This function places a thread back on the runnable thread list
/*0113./ * (RunnableThreads) and will also call signalTimeToReschedule() if the
/*0114./ * priority of the activated thread is higher than the priority of
/*0115./ * currently executing thread.
/*0116./ *
/*0117./ * The new thread is put in the RunnableThreads list in a position where
/*0118./ * it will be the next one to be executed. Unlike the earlier thread
/*0119./ * scheduling mechanism, this will allow higher priority threads to
/*0120./ * get switched to immediately in an interrupt driven environment.
/*0121./ *
/*0122./ * The intention of this change is to implement a more conventional
/*0123./ * event driven priority scheduling mechanism. This was the primary
/*0124./ * motivation for removing the active thread from the runnable queue
/*0125./ * when it is executing. We can now completely change the format of
/*0126./ * the runnable queue without affecting the rest of the system.
/*0127./ *
/*0128./ * BuildThread()
/*0129./ * -------------
/*0130./ *
/*0131./ * This now adds all new threads to another list of all alive threads called
/*0132./ * AllThreads. This list is used by the garbage collector.
/*0133./ *
/*0134./ * DismantleThread()
/*0135./ * -----------------
/*0136./ *
/*0137./ * Removes the thread from the AllThreads list.
/*0138./ *
/*0139./ * stopThread()
/*0140./ * ------------
/*0141./ *
/*0142./ * This function is the logical opposite to BuildThread(). It suspends the
/*0143./ * thread and calls DismantleThread().
/*0144./ *
/*0145./ * resumeThread()
/*0146./ * ---------------
/*0147./ *
/*0148./ * This replaces the use of activateThread() to restart a suspended thread.
/*0149./ *
/*0150./ * isActivated()
/*0151./ * -------------
/*0152./ *
/*0153./ * It used to be necessary to test that CurrentThread was non-null before
/*0154./ * calling this routine.
/*0155./ *
/*0156./ * HandleEvent()
/*0157./ * -------------
/*0158./ *
/*0159./ * Because the original HandleEvent routine called activateThread it did
/*0160./ * not require any changes (except for the calling convention for
/*0161./ * isActivated()). However, the meaning of the return parameter is
/*0162./ * now slightly different in that is indicates that a new thread was
/*0163./ * added to RunnableThreads and not that it just switched context.
/*0164./ *
/*0165./ * SwitchThread()
/*0166./ * ---------------
/*0167./ *
/*0168./ * SwitchThread is now only called from reschedule(). CurrentThread may or
/*0169./ * may not point to a thread. If it does we rotate the thread through the
/*0170./ * RunnableThreads list as before. If it is null and the RunnableThreads
/*0171./ * list is empty then the function returns FALSE and reschedule() must
/*0172./ * decide what to do. On the Palm it does a wait forever for the next event.
/*0173./ *
/*0174./ * JLT_Yield()
/*0175./ * -----------
/*0176./ *
/*0177./ * Now only has to call signalTimeToReschedule()
/*0178./ *
/*0179./ *
/*0180./ * Asynchronous I/O (optional feature)
/*0181./ * ===================================
/*0182./ *
/*0183./ * The basic thread management strategy of KVM is unchanged in that
/*0184./ * all the Java code is executed by the same native thread, and all
/*0185./ * Java thread context switching is done internally using the
/*0186./ * original 'green thread' concept. This is generally the preferred
/*0187./ * multithreading mechanism for KVM.
/*0188./ *
/*0189./ * Asynchronous I/O is an optional KVM feature that can be used
/*0190./ * if the underlying operating system provides the necessary
/*0191./ * support, e.g., in the form of interrupts, callback routines,
/*0192./ * or native threads. However, be aware that the use of
/*0193./ * asynchronous I/O involves a substantial amount of additional
/*0194./ * work and complexity.
/*0195./ *
/*0196./ * When the author of a Java native function wants to allow the
/*0197./ * interpreter to execute while the I/O is being performed, he
/*0198./ * should call suspendThread(), then set up the appropriate
/*0199./ * platform dependent mechanism to be notified of the I/O
/*0200./ * completion, and then return. >>> It is very important that
/*0201./ * the call to suspendThread() occurs before the callback
/*0202./ * routine is run. <<<
/*0203./ *
/*0204./ * When the callback routine executes, it will almost always wants
/*0205./ * to push some result on the stack of the suspended thread, and
/*0206./ * then call resumeThread().
/*0207./ *
/*0208./ * When a native function is called in KVM, it is generally running
/*0209./ * in the context of the calling thread. This is not the case when
/*0210./ * a callback routine (or whatever mechanism you are using to
/*0211./ * report the results of an asynchronous call) is called. Therefore,
/*0212./ * the normal stack access functions and macros (popStack() etc.)
/*0213./ * cannot be used when writing callback routines. To solve this
/*0214./ * problem, special new versions of these stack manipulation
/*0215./ * functions are provided. These new routines all have an additional
/*0216./ * "FromThread" parameter to indicate the requested context. For
/*0217./ * instance, popStack() becomes popStackFromThread(THREAD* FromThread).
/*0218./ * Using these new, alternative macros, the thread's stack can
/*0219./ * be set up with the appropriate parameters prior to calling
/*0220./ * activateThread().
/*0221./ *
/*0222./ * An additional problem with asynchronous I/O is the possibility
/*0223./ * of a race condition. To prevent a race condition corrupting the
/*0224./ * RunnableThreads queue, which links asynchronous world outside
/*0225./ * the VM with its internal rescheduling functions, all accesses
/*0226./ * to this queue much be interlocked with a critical section.
/*0227./ * Therefore, two new platform dependent functions have been
/*0228./ * defined:
/*0229./ *
/*0230./ * enterSystemCriticalSection()
/*0231./ *
/*0232./ * and
/*0233./ *
/*0234./ * exitSystemCriticalSection()
/*0235./ *
/*0236./ *=======================================================================*/
/*0237*/
/*0238*//*=========================================================================
/*0239./ * NEW COMMENTS (KVM 1.0.3)
/*0240./ * ========================
/*0241./ *
/*0242./ * KVM 1.0.3 has a new monitor/synchronization implementation.
/*0243./ * Read the description later in this file. Otherwise, there
/*0244./ * are no significant multithreading changes between KVM 1.0
/*0245./ * and KVM 1.0.3.
/*0246./ *=======================================================================*/
/*0247*/
/*0248*//*=========================================================================
/*0249./ * Global definitions and variables needed for multitasking
/*0250./ *=======================================================================*/
/*0251*/
/*0252*/#ifndef __THREAD_H__
/*0253*/#define __THREAD_H__
/*0254*/
//\\
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -