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