Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

threadstate.c

Go to the documentation of this file.
00001 /*!
00002  * @file threadstate.c
00003  *
00004  * @brief Validate and perform state transitions, and process each
00005  * state of the JVM thread state machin.
00006  *
00007  * This implementation of the JVM state machine using both stable and
00008  * transient states.  The thread system operates as a state machine
00009  * based on the JVM spec requirements.  The states for this
00010  * implementation are shown below.  Those marked @b (+) are
00011  * transient states and will move forward to the next stable
00012  * state as soon as possible:
00013  *
00014  * <ul>
00015  * <li>
00016  * @b THREAD_STATE_NEW          Thread is brand new and ready to run.
00017  *                              Before now, the
00018  *                              @link #THREAD_STATUS_INUSE
00019                                 THREAD_STATUS_INUSE@endlink bit was
00020  *                              clear.
00021  * </li>
00022  * <li>
00023  * @b THREAD_STATE_START @b (+)
00024  *                              The thread.start() operation was
00025  *                              requested to start execution of thread's
00026  *                              java.lang.Thread.run() method.
00027  * </li>
00028  * <li>
00029  * @b THREAD_STATE_RUNNABLE     The a started thread may run when its
00030  *                              turn arrives in the arbitration
00031  *                              sequence.
00032  * </li>
00033  * <li>
00034  * @b THREAD_STATE_RUNNING      This thread is currently running.
00035  * </li>
00036  * <li>
00037  * @b THREAD_STATE_BLOCKEVENT @b (+)
00038  *                              Blocking event occurred (such as sleep()
00039  *                              or I/O operation).
00040  * </li>
00041  * <li>
00042  * @b THREAD_STATE_BLOCKED      This thread is blocked on blocking
00043  *                              event.
00044  * </li>
00045  * <li>
00046  * @b THREAD_STATE_UNBLOCKED @b (+)
00047  *                             Blocking event has expired (eg, sleep()
00048  *                             was called) that put the thread into a
00049  *                             blocked state.
00050  * </li>
00051  * <li>
00052  * @b THREAD_STATE_SYNCHRONIZED @b (+)
00053  *                             Another thread has engaged an object's
00054  *                             monitor lock.
00055  * </li>
00056  * <li>
00057  * @b THREAD_STATE_RELEASE @b (+)
00058  *                             This thread DOES have an object's monitor
00059  *                             lock and has called wait() to disengage
00060  *                             it and prepare to wait.
00061  * </li>
00062  * <li>
00063  * @b THREAD_STATE_WAIT        Waiting on one of
00064  *                             notify()/notifyAll()/interrupt()
00065  * </li>
00066  * <li>
00067  * @b THREAD_STATE_NOTIFY @b (+)
00068  *                             This waiting thread has been awakened
00069  *                             by notify()/notifyAll() or interrupt().
00070  * </li>
00071  * <li>
00072  * @b THREAD_STATE_LOC         This thread is waiting on an object's
00073  *                             monitor lock to be released by another
00074  *                             thread.
00075  * </li>
00076  * <li>
00077  * @b THREAD_STATE_ACQUIRE @b (+)
00078  *                             This thread now has an object's monitor
00079  *                             lock after it was released by another
00080  *                             thread.
00081  * </li>
00082  * <li>
00083  * @b THREAD_STATE_COMPLETE @b (+)
00084  *                             This thread has completed its run()
00085  *                             method and is ready to terminate because
00086  *                             it has had some other event occur to
00087  *                             finish its execution.
00088  * </li>
00089  * <li>
00090  * @b THREAD_STATE_DEAD        This thread has been shut down and does
00091  *                             is ready to have its thread slot
00092  *                             deallocated by clearing the @link
00093                                #THREAD_STATUS_INUSE
00094                                THREAD_STATUS_INUSE@endlink bit.
00095  * </li>
00096  * <li>
00097  * @b THREAD_STATE_BADLOGIC (sometimes @b (+) )
00098  *                             Diagnostic state, sometimes transient,
00099  *                             sometimes stable, depending on what
00100  *                             it is being used for.  See state diagram
00101  *                             below for details.
00102  * </li>
00103  * </ul>
00104  *
00105  * The state transitions are:
00106  *
00107  * <ul>
00108  * <li>
00109  * <b>(a) Simple execution</b>:
00110  *
00111  *         not used -> NEW -> START @b (+) -> RUNNABLE -> RUNNING
00112  *         -> COMPLETE @b (+) -> DEAD -> not used
00113  *
00114  * </li>
00115  * <li>
00116  * <b>(b) java.lang.Thread.yield()</b>:
00117  *
00118  *         RUNNING -> RUNNABLE -> RUNNING
00119  *
00120  * </li>
00121  * <li>
00122  * <b>(c) java.lang.Thread.sleep(), java.lang.Thread.join(),
00123  * java.lang.Thread.interrupt(), interruptible I/O</b>:
00124  *
00125  *         RUNNING -> BLOCKINGEVENT @b (+) -> BLOCKED
00126  *         -> UNBLOCKED @b (+) -> RUNNABLE
00127  *
00128  * </li>
00129  * <li>
00130  *
00131  * <b>(d) synchronized(Object)</b>:
00132  *
00133  *         RUNNING -> SYNCHRONIZED @b (+) -> LOCK
00134  *         -> ACQUIRE @b (+) -> RUNNABLE
00135  *
00136  * </li>
00137  * <li>
00138  * <b>(e) Object.wait()</b>:
00139  *
00140  *         RUNNING -> RELEASE @b (+) -> WAIT -> NOTIFY @b (+)
00141  *         -> LOCK -> ACQUIRE @b (+) -> RUNNABLE 
00142  *
00143  * </li>
00144  * <li>
00145  * <b>(f) Stillborn thread</b>:
00146  *
00147  *         NEW -> BADLOGIC @b (+) -> COMPLETE @b (+) -> DEAD
00148  *
00149  * </li>
00150  * <li>
00151  * <b>(g) java.lang.Thread.destroy(), java.lang.Thread.stop()-- both
00152  * deprecated</b>:
00153  *
00154  *         anywhere -> BADLOGIC @b (+) -> COMPLETE @b (+) -> DEAD
00155  *
00156  * </li>
00157  * <li>
00158  * <b>(h) java.lang.Thread.suspend()-- deprecated</b>:
00159  *
00160  *         anywhere -> BADLOGIC -> BLOCKINGEVENT @b (+) -> BLOCKED
00161  *
00162  * </li>
00163  * <li>
00164  * <b>(i) java.lang.Thread.resume()-- deprecated</b>:
00165  *
00166  *         BLOCKED -> UNBLOCKED @b (+) -> RUNNABLE
00167  *
00168  * </li>
00169  * <li>
00170  * <b>(j) Somebody GOOFED!  Programmatic suspend</b>:
00171  *
00172  *         anywhere-> BADLOGIC
00173  *
00174  * </li>
00175  * </ul>
00176  *
00177  * The first line <b>(line a)</b> is the main flow of control.
00178  *
00179  * <b>(line b)</b> depend on various programmatic events such as
00180  * java.lang.Thread.yield() invocation and normal JVM thread
00181  * arbitration.
00182  *
00183  * <b>(line c)</b> involves scheduled programmatic events like
00184  * java.lang.Thread.sleep() and java.lang.Thread.join(),
00185  * java.lang.Thread.interrupt() events (line c),
00186  * or interruptible I/O operations.
00187  *
00188  * <b>(line d)</b> depicts @c @b synchronized() requests (line d)
00189  *
00190  * <b>(line e)</b> involives java.lang.Object.wait() requests (after
00191  * object lock acquired) via java.lang.Object.notify() or
00192  * java.lang.Object.notifyAll() or java.lang.Thread.interrupt()
00193  * events.
00194  *
00195  * <b>(line f)</b>, shows the so-called "stillborn" thread that dies
00196  * before it has a chance to java.lang.Thread.start().
00197  *
00198  * <b>(lines g, h, i)</b>, demonstrates how this implementation
00199  * gracefully minimizes the damage of the deprecated
00200  * java.lang.Thread.destroy(), java.lang.Thread.stop(), 
00201  * java.lang.Thread.suspend(), and java.lang.Thread.resume().
00202  *
00203  * <b>(line j)</b>, shows a state that has been added to handle errors,
00204  * typically from development and testing.  This provides a valid
00205  * state transition that may be done programmatically to sideline
00206  * any desired thread.
00207  *
00208  * Notice that there are more states here than in the classic model
00209  * for the JVM.  Part of the reason for this is that a finer granularity
00210  * of control provides the state model with an insertion point for
00211  * diagnostics of the state model, especially in the transient states
00212  * (namely @b START, @b RELEASE, @b SYNCHRONIZED, @b NOTIFY, @b ACQUIRE,
00213  * and @b COMPLETE).  This is complementary to the definition of each
00214  * state.  The implementation of this model includes three groups of
00215  * functions named after each of three phases of state change and
00216  * processing and after each state name:
00217  *
00218  * <ul>
00219  * <li>
00220  * @link #threadstate_request_new() threadstate_request_XXX()@endlink:
00221  * Request that a thread move from the current state to
00222  * the @b XXX state.
00223  * </li>
00224  *
00225  * <li>
00226  * @link #threadstate_activate_new() threadstate_activate_XXX()@endlink:
00227  * Move a thread from the current state to the @b XXX state after
00228  * it was requested by the related function
00229  * @link #threadstate_request_new() threadstate_request_XXX()@endlink.
00230  * </li>
00231  *
00232  * <li>
00233  * @link #threadstate_process_new() threadstate_process_XXX()@endlink:
00234  * Perform normal actions appropriate for this state.  If this is a
00235  * stable state like @b RUNNING, run the next time slice of virtual
00236  * instructions.  If it is a transient state like @b START, request
00237  * transition on to the next state (in this case, @b RUNNABLE would
00238  * be next).
00239  * </li>
00240  * </ul>
00241  *
00242  * These three stages in the JVM outer loop provide immediate
00243  * diagnostics in case of problems with state transitions, which is,
00244  * of course, useful during development, but can also provide
00245  * safeguards during normal runtime.  The processing overhead is
00246  * negligible since it is in the @e outer loop.
00247  * All groups of routines return a boolean describing whether or not
00248  * the activities for that phase of that state succeeded. For example,
00249  * thread_request_runnable() attempts to take a thread from its current
00250  * state into
00251  * @link #THREAD_STATE_RUNNABLE THREAD_STATE_RUNNABLE@endlink.
00252  * If it succeeds, it returns @link #rtrue rtrue@endlink, otherwise
00253  * @link #rfalse rfalse@endlink.
00254  *
00255  * All transition requests work @e exactly the same way.  The actual
00256  * performance of that change may require doing some work, depending
00257  * on the particular state being requested, but most require only a
00258  * simple state transition.  For example, the beginning of the world is
00259  * threadstate_request_start(), which is equivalent to the
00260  * java.lang.Thread method java.lang.Thread.start().
00261  * At various times during development, it had some work to perform
00262  * as the thread state model was integrated into the JVM, such as
00263  * loading the JVM's PC with the entry point of the correct method.
00264  * But in the case of threadstate_request_unblocked(), a state
00265  * transition will also be requested since it is a transitory state in
00266  * addition to any other work it may perform.
00267  *
00268  * All logic for each state change is found within its respective
00269  * @b threadstate_[@link #threadstate_request_new() request@endlink|
00270    @link #threadstate_activate_new() activate@endlink
00271    @link #threadstate_process_new() process@endlink]<b>_XXX()</b>
00272  * function below.
00273  *
00274  *
00275  * @attention: Only a @b NEW thread may be moved into the @b START
00276  *             state.  Only an @link #THREAD_STATUS_EMPTY
00277                THREAD_STATUS_EMPTY@endlink thread may be moved into
00278  *             @link #THREAD_STATUS_INUSE THREAD_STATUS_INUSE@endlink
00279  *             status and hence the @b NEW state.  Only the
00280  *             @link #JVMCFG_NULL_THREAD JVMCFG_NULL_THREAD@endlink
00281  *             may be permanently marked as being
00282  *             @link #THREAD_STATUS_NULL THREAD_STATUS_NULL@endlink.
00283  *             These two conditions must @e never be manipulated
00284  *             by thread_new() and thread_die().
00285  *
00286  *
00287  * @section Control
00288  *
00289  * \$URL: https://svn.apache.org/path/name/threadstate.c $ \$Id: threadstate.c 0 09/28/2005 dlydick $
00290  *
00291  * Copyright 2005 The Apache Software Foundation
00292  * or its licensors, as applicable.
00293  *
00294  * Licensed under the Apache License, Version 2.0 ("the License");
00295  * you may not use this file except in compliance with the License.
00296  * You may obtain a copy of the License at
00297  *
00298  *     http://www.apache.org/licenses/LICENSE-2.0
00299  *
00300  * Unless required by applicable law or agreed to in writing,
00301  * software distributed under the License is distributed on an
00302  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00303  * either express or implied.
00304  *
00305  * See the License for the specific language governing permissions
00306  * and limitations under the License.
00307  *
00308  * @version \$LastChangedRevision: 0 $
00309  *
00310  * @date \$LastChangedDate: 09/28/2005 $
00311  *
00312  * @author \$LastChangedBy: dlydick $
00313  *         Original code contributed by Daniel Lydick on 09/28/2005.
00314  *
00315  * @section Reference
00316  *
00317  */
00318 
00319 #include "arch.h"
00320 ARCH_COPYRIGHT_APACHE(threadstate, c, "$URL: https://svn.apache.org/path/name/threadstate.c $ $Id: threadstate.c 0 09/28/2005 dlydick $");
00321 
00322 
00323 #include "jvmcfg.h"
00324 #include "classfile.h"
00325 #include "jvm.h"
00326 #include "opcode.h"
00327 
00328 
00329 /*!
00330  * @name State phase macros
00331  *
00332  * @brief Macros to support the three phases of moving from one
00333  * thread state to another.
00334  *
00335  * See section on the JVM thread model state machine for an explanation
00336  * as to @e why these functions exist.  Concerning @e how they operate,
00337  * an example of their usage in the @b START state functions will
00338  * provide clear guidance of how to use them generally.  The first state
00339  * transition request is always from @b NEW to @b START.  The macro
00340  * expansion of the macros inside of @link #threadstate_request_start()
00341    threadstate_request_start()@endlink demonstrate syntax for how
00342  * this accomplihed.  Following that is the syntax for @link
00343     #threadstate_activate_start() threadstate_activate_start()@endlink
00344  * and @link #threadstate_process_start()
00345    threadstate_process_start()@endlink.  The declaration of these
00346  * three functions follows later.  For good form when using these
00347  * functions with these state phase macros, <em>be sure</em> to place
00348  * the whole of the second parameter expression of STATE_REQUEST()
00349  * in (parentheses).
00350  *
00351  * Transition is shown from @b NEW to @b START to show a more
00352  * normal example than from "not in use" to @b NEW.
00353  *
00354  * The expansion of the macros inside of the three @b START functions
00355  * produces the following code:
00356  *
00357  * @verbatim
00358    rboolean threadstate_request_start(jvm_thread_index thridx)
00359    {
00360        if (THREAD_STATE_NEW == THREAD(thridx).this_state)
00361        {
00362            THREAD(thridx).next_state = THREAD_STATE_START;
00363    
00364            ** use (rtrue) if nothing else needed **
00365            return((rtrue) ? rtrue : rfalse);
00366        }
00367        else
00368        {
00369            return(rfalse);
00370        };
00371    }
00372    
00373    rboolean threadstate_activate_start(jvm_thread_index thridx)
00374    {
00375        if (THREAD_STATE_START == THREAD(thridx).next_state)
00376        {
00377          ** Record previous state when changing to next one **
00378            THREAD(thridx).prev_state = THREAD(thridx).this_state;
00379            THREAD(thridx).this_state = THREAD(thridx).next_state;
00380        }
00381        if (THREAD_STATE_START == THREAD(thridx).this_state)
00382        {
00383            return((rtrue) ? rtrue : rfalse);
00384        }
00385        else
00386        {
00387            return(rfalse);
00388        };
00389    }
00390    
00391    rboolean threadstate_process_start(jvm_thread_index thridx)
00392    {
00393        if (THREAD_STATE_START == THREAD(thridx).this_state)
00394        {
00395     
00396           ** ... Process activities for this thread state here ... **
00397    
00398           ** use (rtrue) if nothing else needed **
00399           return((threadstate_request_runnable(thridx)) ? rtrue:rfalse);
00400        }
00401        else
00402        {
00403            return(rfalse);
00404        };
00405   }
00406   
00407    @endverbatim
00408  *
00409  */
00410 
00411 /*@{ */ /* Begin grouped definitions */
00412 
00413 /*!
00414  * @def STATE_REQUEST()
00415  *
00416  * @brief Request a state change from this state to another state.
00417  *
00418  *
00419  * @param upper             New state name in UPPER CASE (for macro
00420  *                          expansion purposes)
00421  *
00422  * @param unique_state_test <em>BE SURE</em> to put put this parameter
00423  *                          in (parentheses) for proper macro expansion!
00424  *                          Permit state change into requested state
00425  *                          @e only if this expression evaluates to
00426  *                          @link #rtrue rtrue@endlink, which may be
00427  *                          explicitly stated if this state change is
00428  *                          unconditional.
00429  *
00430  * @returns @link #rtrue rtrue@endlink if state change was permitted,
00431  *          otherwise @link #rfalse rfalse@endlink.
00432  *
00433  */
00434 #define STATE_REQUEST(upper, unique_state_test)               \
00435     if (unique_state_test)                                    \
00436     {                                                         \
00437         NEXT_STATE(thridx) = THREAD_STATE_##upper
00438 
00439 /*  } ignore-- keeps text editors happy */
00440 
00441 /*!
00442  * @def STATE_ACTIVATE()
00443  *
00444  * @brief Activate a state change that was validated by
00445  * @link #STATE_REQUEST() STATE_REQUEST()@endlink.
00446  *
00447  *
00448  * @param upper             New state name in UPPER CASE (for macro
00449  *                          expansion purposes)
00450  *
00451  *
00452  * @returns @link #rtrue rtrue@endlink if state change was permitted,
00453  *          otherwise @link #rfalse rfalse@endlink.
00454  *
00455  */
00456 #define STATE_ACTIVATE(upper)                                 \
00457     if (THREAD_STATE_##upper == NEXT_STATE(thridx))           \
00458     {                                                         \
00459         /* Record previous state when changing to next one */ \
00460         PREV_STATE(thridx) = THIS_STATE(thridx);              \
00461         THIS_STATE(thridx) = NEXT_STATE(thridx);              \
00462     }                                                         \
00463                                                               \
00464     if (THREAD_STATE_##upper == THIS_STATE(thridx))           \
00465     {
00466 
00467 /*  } ignore-- keeps text editors happy */
00468 
00469 /*!
00470  * @def STATE_PROCESS()
00471  *
00472  * @brief Process a state change that was activated by
00473  * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink.
00474  *
00475  *
00476  * @param upper             New state name in UPPER CASE (for macro
00477  *                          expansion purposes)
00478  *
00479  *
00480  * @returns @link #rtrue rtrue@endlink if state change was permitted,
00481  *          otherwise @link #rfalse rfalse@endlink.
00482  *
00483  */
00484 #define STATE_PROCESS(upper)                                  \
00485     if (THREAD_STATE_##upper == THIS_STATE(thridx))           \
00486     {
00487 
00488 /*  } ignore-- keeps text editors happy */
00489 
00490 /*  { ignore-- keeps text editors happy */
00491 
00492 /*!
00493  * @def STATE_END()
00494  *
00495  * @brief Terminate the code fragment initiated by
00496  * @link #STATE_REQUEST() STATE_REQUEST()@endlink or
00497  * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink or
00498  * @link #STATE_PROCESS() STATE_PROCESS()@endlink.
00499  *
00500  * In between the @link #STATE_REQUEST() STATE_REQUEST()@endlink and
00501  * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink and
00502  * @link #STATE_PROCESS() STATE_PROCESS()@endlink macro instance and 
00503  * this macro, any phase-specific, state-specific code may be inserted.
00504  * Although most states do not do so, <em>pay particular attention</em>
00505  * to those that do, also any comments that may be present in lieu of
00506  * code.
00507  *
00508  */
00509 #define STATE_END(expr)                                       \
00510         /* use (rtrue) if nothing else needed */              \
00511         return((expr) ? rtrue : rfalse);                      \
00512     }                                                         \
00513     else                                                      \
00514     {                                                         \
00515         return(rfalse);                                       \
00516     }
00517 
00518 /*@} */ /* End of grouped definitions */
00519 
00520 
00521 /*!
00522  * @name JVM thread model state machine
00523  *
00524  * @brief Implement the JVM state machine using both stable and
00525  * transient states.
00526  *
00527  * See tables above for full description.
00528  *
00529  * 
00530  * @todo  Need to find a way (per spec section 5.3.5) to throw
00531  *        a java.lang.LinkageError and/or java.lang.ClassFormatError
00532  *        for bad classfile representations.  Also major/minor versions
00533  *        mismatch should throw
00534  *        java/class/UnsupportedClassVersion error.
00535  *
00536  *
00537  * @param thridx thread index of thread whose state is to be changed.
00538  *
00539  *
00540  * @returns @link #rtrue rtrue@endlink if all activities were
00541  * successful, else @link #rfalse rfalse@endlink.
00542  *
00543  */
00544 
00545 /*@{ */ /* Begin grouped definitions */
00546 
00547 
00548 /*****************************************************************/
00549 
00550 /*!
00551  * @brief Request the @b NEW thread state.
00552  *
00553  * The @b NEW state starts the whole state machine for a thread.
00554  *
00555  */
00556 rboolean threadstate_request_new(jvm_thread_index thridx)
00557 {
00558     STATE_REQUEST(NEW, (rtrue));
00559     STATE_END(rtrue);
00560 }
00561 
00562 
00563 /*!
00564  * @brief Activate the @b NEW thread state for a new thread.
00565  *
00566  */
00567 rboolean threadstate_activate_new(jvm_thread_index thridx)
00568 {
00569     STATE_ACTIVATE(NEW);
00570     STATE_END(rtrue);
00571 }
00572 
00573 
00574 /*!
00575  * @brief Process the @b NEW thread state.
00576  *
00577  * The @b NEW state idles until the @b START state is requested.
00578  *
00579  */
00580 rboolean threadstate_process_new(jvm_thread_index thridx)
00581 {
00582     STATE_PROCESS(NEW);
00583     STATE_END(rtrue);
00584 }
00585 
00586 /*****************************************************************/
00587 
00588 /*!
00589  * @brief Request the @b START state.
00590  *
00591  * The @b START state can only be entered from @b NEW.
00592  *
00593  */
00594 
00595 rboolean threadstate_request_start(jvm_thread_index thridx)
00596 {
00597     STATE_REQUEST(START, (THREAD_STATE_NEW == THIS_STATE(thridx)));
00598     STATE_END(rtrue);
00599 }
00600 
00601 /*!
00602  * @brief Activate the @b START thread state of a thread known
00603  * to be coming from a valid previous state.
00604  *
00605  */
00606 rboolean threadstate_activate_start(jvm_thread_index thridx)
00607 {
00608     STATE_ACTIVATE(START);
00609     STATE_END(rtrue);
00610 }
00611 
00612 /*!
00613  * @brief Process the @b START thread state.
00614  *
00615  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00616  * from @b START to @b RUNNABLE is requested here.
00617  *
00618  */
00619 rboolean threadstate_process_start(jvm_thread_index thridx)
00620 {
00621     STATE_PROCESS(START);
00622 
00623     /* ... Process activities for this thread state here ... */
00624 
00625     STATE_END(threadstate_request_runnable(thridx));
00626 }
00627 
00628 /*****************************************************************/
00629 
00630 /*!
00631  * @brief Request the @b RUNNABLE state.
00632  *
00633  * The @b RUNNABLE state can be entered from @b START, @b RUNNING,
00634  * @b UNBLOCKED, or @b ACQUIRE.
00635  *
00636  */
00637 rboolean threadstate_request_runnable(jvm_thread_index thridx)
00638 {
00639     STATE_REQUEST(RUNNABLE, 
00640                   ((THREAD_STATE_START     == THIS_STATE(thridx)) ||
00641                    (THREAD_STATE_RUNNING   == THIS_STATE(thridx)) ||
00642                    (THREAD_STATE_UNBLOCKED == THIS_STATE(thridx)) ||
00643                    (THREAD_STATE_ACQUIRE   == THIS_STATE(thridx))    ));
00644     STATE_END(rtrue);
00645 }
00646 
00647 /*!
00648  * @brief Activate the @b RUNNABLE thread state of a thread known
00649  * to be coming from a valid previous state.
00650  *
00651  */
00652 rboolean threadstate_activate_runnable(jvm_thread_index thridx)
00653 {
00654     STATE_ACTIVATE(RUNNABLE);
00655     STATE_END(rtrue);
00656 }
00657 
00658 /*!
00659  * @brief Process the @b RUNNABLE thread state.
00660  *
00661  * Always try to keep @b RUNNABLE thread in the @b RUNNING state.
00662  * Although not formally a transient state, @b RUNNABLE indicates
00663  * that a thread is @e potentially one that could be @b RUNNING,
00664  * thus the attempt to keep it there.
00665  *
00666  */
00667 rboolean threadstate_process_runnable(jvm_thread_index thridx)
00668 {
00669     STATE_PROCESS(RUNNABLE);
00670     STATE_END(rtrue);
00671 }
00672 
00673 
00674 /*****************************************************************/
00675 
00676 /*!
00677  * @brief Request the @b RUNNING state.
00678  *
00679  * The @b RUNNING state can only be entered from @b RUNNABLE.
00680  *
00681  * The JVM inner execution loop is called from
00682  * threadstate_process_running(), causing any thread in the
00683  * @b RUNNING state to normally keep executing its code
00684  * from where it left off last time.
00685  *
00686  */
00687 rboolean threadstate_request_running(jvm_thread_index thridx)
00688 {
00689     STATE_REQUEST(RUNNING,
00690                   (THREAD_STATE_RUNNABLE == THIS_STATE(thridx)));
00691     STATE_END(rtrue);
00692 }
00693 
00694 /*!
00695  * @brief Activate the @b RUNNING thread state of a thread known
00696  * to be coming from a valid previous state.
00697  *
00698  */
00699 rboolean threadstate_activate_running(jvm_thread_index thridx)
00700 {
00701     STATE_ACTIVATE(RUNNING);
00702     STATE_END(rtrue);
00703 }
00704 
00705 /*!
00706  * @brief Process the @b RUNNING thread state.
00707  *
00708  * Run the next virtual instruction engine on the
00709  * current thread from where it left off last time.
00710  *
00711  * @attention Notice that the normal way to invoke
00712  *            opcode_run() is in this location, as
00713  *            driven by the JVM outer loop in jvm_run().
00714  *
00715  */
00716 rboolean threadstate_process_running(jvm_thread_index thridx)
00717 {
00718     STATE_PROCESS(RUNNING);
00719 
00720    STATE_END(opcode_run(CURRENT_THREAD, rtrue));
00721 }
00722 
00723 
00724 /*****************************************************************/
00725 
00726 /*!
00727  * @brief Request the @b COMPLETE state.
00728  *
00729  * The @b COMPLETE state can be entered from @b NEW or @b RUNNING
00730  * or @b BADLOGIC.
00731  *
00732  * When entered from @b NEW, it is a so-called "stillborn" thread that
00733  * was created but never used.
00734  *
00735  * When entered from @b BADLOGIC, java.lang.Thread.destroy() or
00736  * java.lang.Thread.stop() was invoked, both of which are
00737  * dangerous, deprecated methods.
00738  *
00739  */
00740 rboolean threadstate_request_complete(jvm_thread_index thridx)
00741 {
00742     STATE_REQUEST(COMPLETE,
00743                   ((THREAD_STATE_NEW      == THIS_STATE(thridx)) ||
00744                    (THREAD_STATE_RUNNING  == THIS_STATE(thridx)) ||
00745                    (THREAD_STATE_BADLOGIC == THIS_STATE(thridx))));
00746 
00747     STATE_END(rtrue);
00748 }
00749 
00750 /*!
00751  * @brief Activate the @b COMPLETE thread state of a thread known
00752  * to be coming from a valid previous state.
00753  *
00754  */
00755 rboolean threadstate_activate_complete(jvm_thread_index thridx)
00756 {
00757     STATE_ACTIVATE(COMPLETE);
00758     STATE_END(rtrue);
00759 }
00760 
00761 /*!
00762  * @brief Process the @b COMPLETE thread state.
00763  *
00764  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00765  * from @b COMPLETE to @b DEAD is requested here.
00766  *
00767  */
00768 rboolean threadstate_process_complete(jvm_thread_index thridx)
00769 {
00770     STATE_PROCESS(COMPLETE);
00771     STATE_END(threadstate_request_dead(thridx));
00772 }
00773 
00774 
00775 /*****************************************************************/
00776 
00777 /*!
00778  * @brief Request the @b BLOCKINGEVENT state.
00779  *
00780  * The @b BLOCKINGEVENT state can be entered from the
00781  * @b RUNNING or @b BADLOGIC states.  This can be caused by
00782  * java.lang.Thread.sleep() and java.lang.Thread.join() and
00783  * interruptible I/O operations.  Also, deprecated
00784  * java.lang.Thread.suspend() can go through @b BADLOGIC
00785  * to get here.
00786  *
00787  */
00788 rboolean threadstate_request_blockingevent(jvm_thread_index thridx)
00789 {
00790     STATE_REQUEST(BLOCKINGEVENT,
00791                   ((THREAD_STATE_RUNNING  == THIS_STATE(thridx)) ||
00792                    (THREAD_STATE_BADLOGIC == THIS_STATE(thridx))));
00793     STATE_END(rtrue);
00794 }
00795 
00796 /*!
00797  * @brief Activate the @b BLOCKINGEVENT thread state of a thread known
00798  * to be coming from a valid previous state.
00799  *
00800  */
00801 rboolean threadstate_activate_blockingevent(jvm_thread_index thridx)
00802 {
00803     STATE_ACTIVATE(BLOCKINGEVENT);
00804     STATE_END(rtrue);
00805 }
00806 
00807 /*!
00808  * @brief Process the @b BLOCKINGEVENT thread state.
00809  *
00810  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00811  * from @b BLOCKINGEVENT to @b BLOCKED is requested here.
00812  *
00813  */
00814 rboolean threadstate_process_blockingevent(jvm_thread_index thridx)
00815 {
00816     STATE_PROCESS(BLOCKINGEVENT);
00817 
00818     STATE_END(threadstate_request_blocked(thridx));
00819 }
00820 
00821 /*****************************************************************/
00822 
00823 /*!
00824  * @brief Request the @b BLOCKED state.
00825  *
00826  * The @b BLOCKED state can only be entered from @b BLOCKINGEVENT.
00827  *
00828  */
00829 rboolean threadstate_request_blocked(jvm_thread_index thridx)
00830 {
00831     STATE_REQUEST(BLOCKED,
00832                   (THREAD_STATE_BLOCKINGEVENT == THIS_STATE(thridx)));
00833     STATE_END(rtrue);
00834 }
00835 
00836 /*!
00837  * @brief Activate the @b BLOCKED thread state of a thread known
00838  * to be coming from a valid previous state.
00839  *
00840  */
00841 rboolean threadstate_activate_blocked(jvm_thread_index thridx)
00842 {
00843     STATE_ACTIVATE(BLOCKED);
00844     STATE_END(rtrue);
00845 }
00846 
00847 /*!
00848  * @brief Process the @b BLOCKED thread state.
00849  *
00850  * The @b BLOCKED state idles until the @b UNBLOCKED state
00851  * is requsted by threadutil_update_blockingevents().
00852  *
00853  */
00854 rboolean threadstate_process_blocked(jvm_thread_index thridx)
00855 {
00856     STATE_PROCESS(BLOCKED);
00857     STATE_END(rtrue);
00858 }
00859 
00860 
00861 /*****************************************************************/
00862 
00863 /*!
00864  * @brief Request the @b UNBLOCKED state.
00865  *
00866  * The @b UNBLOCKED state can only be entered from @b BLOCKED.
00867  *
00868  */
00869 rboolean threadstate_request_unblocked(jvm_thread_index thridx)
00870 {
00871     STATE_REQUEST(UNBLOCKED,
00872                   (THREAD_STATE_UNBLOCKED == THIS_STATE(thridx)));
00873     STATE_END(rtrue);
00874 }
00875 
00876 /*!
00877  * @brief Activate the @b UNBLOCKED thread state of a thread known
00878  * to be coming from a valid previous state.
00879  *
00880  */
00881 rboolean threadstate_activate_unblocked(jvm_thread_index thridx)
00882 {
00883     STATE_ACTIVATE(UNBLOCKED);
00884     STATE_END(rtrue);
00885 }
00886 
00887 /*!
00888  * @brief Process the @b UNBLOCKED thread state.
00889  *
00890  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00891  * from @b UNBLOCKED to @b RUNNABLE is requested here.
00892  *
00893  */
00894 rboolean threadstate_process_unblocked(jvm_thread_index thridx)
00895 {
00896     STATE_PROCESS(UNBLOCKED);
00897 
00898     STATE_END(threadstate_request_runnable(thridx));
00899 }
00900 
00901 
00902 /*****************************************************************/
00903 
00904 /*!
00905  * @brief Request the @b SYNCHRONIZED state.
00906  *
00907  * The @b SYNCHRONIZED state can only be entered from @b RUNNING.
00908  *
00909  */
00910 rboolean threadstate_request_synchronized(jvm_thread_index thridx)
00911 {
00912     STATE_REQUEST(SYNCHRONIZED,
00913                   (THREAD_STATE_RUNNING == THIS_STATE(thridx)));
00914     STATE_END(rtrue);
00915 }
00916 
00917 /*!
00918  * @brief Activate the @b SYNCHRONIZED thread state of a thread known
00919  * to be coming from a valid previous state.
00920  *
00921  */
00922 rboolean threadstate_activate_synchronized(jvm_thread_index thridx)
00923 {
00924     STATE_ACTIVATE(SYNCHRONIZED);
00925     STATE_END(rtrue);
00926 }
00927 
00928 /*!
00929  * @brief Process the @b SYNCHRONIZED thread state.
00930  *
00931  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00932  * from @b SYNCHRONIZED to @b LOCK is requested here.
00933  *
00934  */
00935 rboolean threadstate_process_synchronized(jvm_thread_index thridx)
00936 {
00937     STATE_PROCESS(SYNCHRONIZED);
00938 
00939     STATE_END(threadstate_request_lock(thridx));
00940 }
00941 
00942 
00943 /*****************************************************************/
00944 
00945 /*!
00946  * @brief Request the @b RELEASE state.
00947  *
00948  * The @b RELEASE state can only be entered from @b RUNNING.
00949  *
00950  */
00951 rboolean threadstate_request_release(jvm_thread_index thridx)
00952 {
00953     STATE_REQUEST(RELEASE,
00954                   (THREAD_STATE_RUNNING == THIS_STATE(thridx)));
00955     STATE_END(rtrue);
00956 }
00957 
00958 /*!
00959  * @brief Activate the @b RELEASE thread state of a thread known
00960  * to be coming from a valid previous state.
00961  *
00962  */
00963 rboolean threadstate_activate_release(jvm_thread_index thridx)
00964 {
00965     STATE_ACTIVATE(RELEASE);
00966 
00967     STATE_END(rtrue);
00968 }
00969 
00970 /*!
00971  * @brief Process the @b RELEASE thread state.
00972  *
00973  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
00974  * from @b RELEASE to @b WAIT is requested here.
00975  * However, this will @e only occur if this thread
00976  * holds the lock on the @link #rthread.locktarget
00977    rthread.locktarget@endlink object.
00978  *
00979  */
00980 rboolean threadstate_process_release(jvm_thread_index thridx)
00981 {
00982     STATE_PROCESS(RELEASE);
00983 
00984     jvm_object_hash locktarget = THREAD(thridx).locktarget;
00985 
00986     /*
00987      * Check if this thread holds an object monitor lock.
00988      * If not, clear JOIN status and abort.
00989      */
00990     if (rfalse == threadutil_holds_lock(thridx, locktarget))
00991     {
00992         THREAD(thridx).status &= ~(THREAD_STATUS_JOIN4EVER |
00993                                    THREAD_STATUS_JOINTIMED);
00994         return(rfalse);
00995     }
00996 
00997     /*
00998      * Release lock and go to @b WAIT.
00999      *
01000      * But first, clear the monitor lock on the object.
01001      * However, DO NOT wipe the @link #rthread.locktarget
01002        locktarget@endlink object hash in the thread.
01003      * It will be needed when in the @b LOCK state to
01004      * @b ACQUIRE the lock again.
01005      */
01006     (rvoid) objectutil_unsynchronize(locktarget, thridx);
01007 
01008     STATE_END(threadstate_request_wait(thridx));
01009 }
01010 
01011 
01012 /*****************************************************************/
01013 
01014 /*!
01015  * @brief Request the @b WAIT state.
01016  *
01017  * The @b WAIT state can only be entered from @b RELEASE.
01018  *
01019  */
01020 rboolean threadstate_request_wait(jvm_thread_index thridx)
01021 {
01022     STATE_REQUEST(WAIT, (THREAD_STATE_RELEASE == THIS_STATE(thridx)));
01023 
01024     STATE_END(rtrue);
01025 }
01026 
01027 /*!
01028  * @brief Activate the @b WAIT thread state of a thread known
01029  * to be coming from a valid previous state.
01030  *
01031  */
01032 rboolean threadstate_activate_wait(jvm_thread_index thridx)
01033 {
01034     STATE_ACTIVATE(WAIT);
01035 
01036     STATE_END(rtrue);
01037 }
01038 
01039 /*!
01040  * @brief Process the @b WAIT thread state.
01041  *
01042  * The @b WAIT state idles until the @b NOTIFY state
01043  * is requsted by threadutil_update_wait().
01044  *
01045  */
01046 rboolean threadstate_process_wait(jvm_thread_index thridx)
01047 {
01048     STATE_PROCESS(WAIT);
01049 
01050     STATE_END(rtrue);
01051 }
01052 
01053 
01054 /*****************************************************************/
01055 
01056 /*!
01057  * @brief Request the @b NOTIFY state.
01058  *
01059  * The @b NOTIFY state can only be entered from @b WAIT.
01060  *
01061  */
01062 rboolean threadstate_request_notify(jvm_thread_index thridx)
01063 {
01064     STATE_REQUEST(NOTIFY, (THREAD_STATE_WAIT == THIS_STATE(thridx)));
01065 
01066     STATE_END(rtrue);
01067 }
01068 
01069 /*!
01070  * @brief Activate the @b NOTIFY thread state of a thread known
01071  * to be coming from a valid previous state.
01072  *
01073  */
01074 rboolean threadstate_activate_notify(jvm_thread_index thridx)
01075 {
01076     STATE_ACTIVATE(NOTIFY);
01077 
01078     STATE_END(rtrue);
01079 }
01080 
01081 /*!
01082  * @brief Process the @b NOTIFY thread state.
01083  *
01084  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
01085  * from @b NOTIFY to @b LOCK is requested here.
01086  *
01087  */
01088 rboolean threadstate_process_notify(jvm_thread_index thridx)
01089 {
01090     STATE_PROCESS(NOTIFY);
01091 
01092     STATE_END(threadstate_request_lock(thridx));
01093 }
01094 
01095 
01096 /*****************************************************************/
01097 
01098 /*!
01099  * @brief Request the @b LOCK state.
01100  *
01101  * The @b LOCK state can be entered from @b SYNCHRONIZED or @b NOTIFY.
01102  *
01103  */
01104 rboolean threadstate_request_lock(jvm_thread_index thridx)
01105 {
01106     STATE_REQUEST(LOCK,
01107                   ((THREAD_STATE_SYNCHRONIZED == THIS_STATE(thridx)) ||
01108                    (THREAD_STATE_NOTIFY       == THIS_STATE(thridx))));
01109     STATE_END(rtrue);
01110 }
01111 
01112 /*!
01113  * @brief Activate the @b LOCK thread state of a thread known
01114  * to be coming from a valid previous state.
01115  *
01116  */
01117 rboolean threadstate_activate_lock(jvm_thread_index thridx)
01118 {
01119     STATE_ACTIVATE(LOCK);
01120 
01121     STATE_END(rtrue);
01122 }
01123 
01124 /*!
01125  * @brief Process the @b LOCK thread state.
01126  *
01127  * <em>THIS IS THE PLACE WHERE THREADS COMPETE FOR AN OBJECT
01128  * MONITORY LOCK</em>.  If a thread is able to successfully
01129  * run objectutil_synchronize(), then it acquires the MLOCK
01130  * for that object and moves from the @b LOCK state forward
01131  * to the @b ACQUIRE state.
01132  *
01133  * The @b LOCK state idles until the @b ACQUIRE state
01134  * is requsted by threadutil_update_lock().
01135  *
01136  */
01137 rboolean threadstate_process_lock(jvm_thread_index thridx)
01138 {
01139     STATE_PROCESS(LOCK);
01140 
01141     /*
01142      * Attempt to acquire object's monitor lock (MLOCK),
01143      * first come first served.  Go to @b ACQUIRE state
01144      * if ownership was achieved.  If not achieved, stay
01145      * here in the @b LOCK state and keep asking.
01146      *
01147      * The objectutil_synchronize() call will fail until the
01148      * MLOCK bit is clear on this object, at which time the
01149      * lock is acquired by this thread.  At that time, the
01150      * thread can move forward to the @b ACQUIRE state.
01151      */
01152     if (rtrue == objectutil_synchronize(THREAD(thridx).locktarget,
01153                                         thridx))
01154     {
01155         /*
01156          * Should succeed since now in @b LOCK state, so return code
01157          * should always be @link #rtrue rtrue@endlink.
01158          */
01159         (rvoid) threadstate_request_acquire(thridx);
01160     }
01161 
01162     STATE_END(rtrue);
01163 }
01164 
01165 
01166 /*****************************************************************/
01167 
01168 /*!
01169  * @brief Request the @b ACQUIRE state.
01170  *
01171  * The @b ACQUIRE state can only be entered from @b LOCK.
01172  *
01173  */
01174 rboolean threadstate_request_acquire(jvm_thread_index thridx)
01175 {
01176     STATE_REQUEST(ACQUIRE, (THREAD_STATE_LOCK == THIS_STATE(thridx)));
01177 
01178     STATE_END(rtrue);
01179 }
01180 
01181 /*!
01182  * @brief Activate the @b ACQUIRE thread state of a thread known
01183  * to be coming from a valid previous state.
01184  *
01185  */
01186 rboolean threadstate_activate_acquire(jvm_thread_index thridx)
01187 {
01188     STATE_ACTIVATE(ACQUIRE);
01189 
01190     STATE_END(rtrue);
01191 }
01192 
01193 /*!
01194  * @brief Process the @b ACQUIRE thread state.
01195  *
01196  * <em>THIS IS A TRANSIENT STATE!</em>  A state change
01197  * from @b ACQUIRE to @b RUNABLE is requested here.
01198  *
01199  */
01200 rboolean threadstate_process_acquire(jvm_thread_index thridx)
01201 {
01202     STATE_PROCESS(ACQUIRE);
01203 
01204     STATE_END(threadstate_request_runnable(thridx));
01205 }
01206 
01207 
01208 /*****************************************************************/
01209 
01210 /*!
01211  * @brief Request the @b DEAD state.
01212  *
01213  * The @b DEAD state can only be entered from @b COMPLETE.
01214  *
01215  */
01216 rboolean threadstate_request_dead(jvm_thread_index thridx)
01217 {
01218     STATE_REQUEST(DEAD, (THREAD_STATE_COMPLETE == THIS_STATE(thridx)));
01219 
01220     STATE_END(rtrue);
01221 }
01222 
01223 /*!
01224  * @brief Activate the @b DEAD thread state of a thread known
01225  * to be coming from a valid previous state.
01226  *
01227  */
01228 rboolean threadstate_activate_dead(jvm_thread_index thridx)
01229 {
01230     STATE_ACTIVATE(DEAD);
01231 
01232     STATE_END(rtrue);
01233 }
01234 
01235 /*!
01236  * @brief Process the @b DEAD thread state.
01237  *
01238  * Bogus, yet true:  <em>THIS IS A TRANSIENT STATE!</em>  the usual
01239  * message about this state applies, yet the target state is
01240  * the "not used" condition, so it may also be considered
01241  * inapplicable.  Here 'tis:
01242  *
01243  *     <em>THIS IS A TRANSIENT STATE!</em>  A state change
01244  *     from @b DEAD to <b>"not used"</b> is requested here.
01245  *
01246  * So how is this statement true?  Because thread_die()
01247  * is called once the thread enters this condition, removing
01248  * it from the array of active thread table entries.
01249  *
01250  */
01251 rboolean threadstate_process_dead(jvm_thread_index thridx)
01252 {
01253     STATE_PROCESS(DEAD);
01254 
01255     STATE_END(thread_die(thridx));
01256 }
01257 
01258 
01259 /*****************************************************************/
01260 
01261 /*!
01262  * @brief Request the @b BADLOGIC state.
01263  *
01264  * The @b BADLOGIC state can be entered from @e ANY state.
01265  * It is primarily a diagnostic state, but may be used
01266  * to gracefully handle java.lang.Thread.destroy() and
01267  * java.lang.Thread.stop() and java.lang.Thread.suspend()
01268  * and java.lang.Thread.resume().
01269  *
01270  */
01271 rboolean threadstate_request_badlogic(jvm_thread_index thridx)
01272 {
01273     STATE_REQUEST(BADLOGIC, (rtrue));
01274 
01275     STATE_END(rtrue);
01276 }
01277 
01278 /*!
01279  * @brief Activate the @b BADLOGIC thread state of a thread known
01280  * to be coming from a valid previous state.
01281  *
01282  */
01283 rboolean threadstate_activate_badlogic(jvm_thread_index thridx)
01284 {
01285     STATE_ACTIVATE(BADLOGIC);
01286 
01287     STATE_END(rtrue);
01288 }
01289 
01290 /*!
01291  * @brief Process the @b BADLOGIC thread state.
01292  *
01293  * The @b BADLOGIC state idles until another state is requested.
01294  * An "Idle forever" error message might be printed by code that
01295  * invoked this state.  If desired, this state can be moved
01296  * forward to @b COMPLETE or @b BLOCKINGEVENT.  Part of the
01297  * request logic for these states is to permit entrance
01298  * from the @b BADLOGIC state.
01299  *
01300  */
01301 rboolean threadstate_process_badlogic(jvm_thread_index thridx)
01302 {
01303     STATE_PROCESS(BADLOGIC);
01304 
01305     STATE_END(rtrue);
01306 }
01307 
01308 /*@} */ /* End of grouped definitions */
01309 
01310 
01311 /* EOF */
01312 

Generated on Fri Sep 30 18:59:35 2005 by  doxygen 1.4.4