Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/thread.h URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/thread.h?rev=307257&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/thread.h (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/thread.h Fri Oct 7 21:27:56 2005 @@ -0,0 +1,635 @@ +#ifndef _thread_h_included_ +#define _thread_h_included_ + +/*! + * @file thread.h + * + * @brief Definition of the @c @b java.lang.Thread structure in + * this real machine implementation. + * + * There is no notion of a thread group natively in this JVM. Thread + * groups are supported at the class library level. + * + * @section Control + * + * \$URL: https://svn.apache.org/path/name/thread.h $ \$Id: thread.h 0 09/28/2005 dlydick $ + * + * Copyright 2005 The Apache Software Foundation + * or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 ("the License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the License for the specific language governing permissions + * and limitations under the License. + * + * @version \$LastChangedRevision: 0 $ + * + * @date \$LastChangedDate: 09/28/2005 $ + * + * @author \$LastChangedBy: dlydick $ + * Original code contributed by Daniel Lydick on 09/28/2005. + * + * @section Reference + * + */ + +ARCH_COPYRIGHT_APACHE(thread, h, "$URL: https://svn.apache.org/path/name/thread.h $ $Id: thread.h 0 09/28/2005 dlydick $"); + + +#include /* For jmp_buf structure for setjmp(3)/longjmp(3)*/ + +#include "jvmreg.h" + +/*! + * @name Macros for addressing threads + * + * + * @param thridx Thread table index into the global + * @link #rjvm.thread rjvm.thread[]@endlink array (via + * @link #pjvm pjvm->thread[]@endlink). + * + */ + +/*@{ */ /* Begin grouped definitions */ + +/*! + * @def THREAD + * @brief Access structures of thread table at certain index. + * + * The thread table, being an array of slots, provides space for + * one thread instance per slot. This macro references one of + * them using the @p @b thridx index. + * + * @returns pointer to a thread slot + * + */ +#define THREAD(thridx) pjvm->thread[thridx] + +#define CURRENT_THREAD pjvm->current_thread /**< Access structures of + * the thread now running + * in the JVM. + */ + +#define PREV_STATE(thridx) THREAD(thridx).prev_state /**< + * Previous actual thread + * state. + */ + +#define THIS_STATE(thridx) THREAD(thridx).this_state /**< + * This current thread + * state. + */ + +#define NEXT_STATE(thridx) THREAD(thridx).next_state /**< + * Next requested thread + * state. + */ + +#define REQ_NEXT_STATE(state, thridx) \ + threadstate_request_##state(thridx) /**< Place a thread into + * requested thread state, + * see @link + #threadstate_request_new() + threadstate_request_XXX()@endlink + * for specifics. + */ + +#define CURRENT_THREAD_REQUEST_NEXT_STATE(state) \ + REQ_NEXT_STATE(state, CURRENT_THREAD) /**< Request that the + * current thread move into + * a certain thread state, + * see @link + #threadstate_request_new() + threadstate_request_XXX()@endlink + * for specifics. + */ + +#define THREAD_REQUEST_NEXT_STATE(state, thridx) \ + REQ_NEXT_STATE(state, thridx) /**< Request that an + * arbitrary thread move + * into a certain thread + * state, + * see @link + #threadstate_request_new() + threadstate_request_XXX()@endlink + * for specifics. + */ + +#define CURRENT_THREAD_ACTIVATE_THIS_STATE(state) \ + threadstate_activate_##state(CURRENT_THREAD) /**< + * Activate current thread + * state, actually moving + * it from a prior state + * into a requested state, + * see @link + #threadstate_activate_new() + threadstate_activate_XXX()@endlink + * for specifics. + */ + +#define THREAD_ACTIVATE_THIS_STATE(state, thridx) \ + threadstate_activate_##state(thridx) /**< + * Activate arbitrary thread + * state, actually moving it + * from a prior state into + * a requested state, see + * @link + #threadstate_activate_new() + threadstate_activate_XXX()@endlink + * for specifics. + */ + +#define CURRENT_THREAD_PROCESS_THIS_STATE(state) \ + threadstate_process_##state(CURRENT_THREAD) /**< + * Process activities for + * current thread in its + * current state, see + * @link + #threadstate_process_new() + threadstate_process_XXX()@endlink + * for specifics. + */ + +#define THREAD_PROCESS_THIS_STATE(state, thridx) \ + threadstate_process_##state(thridx) /**< + * Process activities for + * an arbitrary thread in + * its current state, see + * @link + #threadstate_process_new() + threadstate_process_XXX()@endlink + * for specifics. + */ + +/*@} */ /* End of grouped definitions */ + + +/*! + * @name Thread state machine state definitions. + * + * @brief Thread state machine state names, including min and max + * states. + * + */ +/*@{ */ /* Begin grouped definitions */ + +typedef enum +{ + THREAD_STATE_NEW = 0, /**< Newly allocated thread */ + THREAD_STATE_START = 1, /**< @b (transient state) Thread has + been started */ + THREAD_STATE_RUNNABLE = 2, /**< Thread may run JVM code */ + THREAD_STATE_RUNNING = 3, /**< Thread is running JVM code */ + THREAD_STATE_COMPLETE = 4, /**< @b (transient state) Thread has + finished running JVM code */ + THREAD_STATE_BLOCKINGEVENT = 5, /**< @b (transient state) Desist + from @b RUNING JVM code due to + I/O request or control + request such as + @c @b sleep() or + @c @b join() */ + THREAD_STATE_BLOCKED = 6, /**< Wait for completion of I/O + request or control request + such as @c @b sleep() + or @c @b join() */ + THREAD_STATE_UNBLOCKED = 7, /**< @b (transient state) I/O or + control request completed, now + can be @b RUNNABLE again. */ + THREAD_STATE_SYNCHRONIZED = 8, /**< @b (transient state) Entered a + @c @b synchronized + block */ + THREAD_STATE_RELEASE = 9, /**< @b (transient state) A + @c @b wait() request + released its lock. */ + THREAD_STATE_WAIT = 10, /**< @c @b wait() for a + @c @b notify(), + @c @b notifyAll() + or @c @b interrupt() + event. */ + THREAD_STATE_NOTIFY = 11, /**< Received a + @c @b notify(), + @c @b notifyAll() + or @c @b interrupt() + event. */ + THREAD_STATE_LOCK = 12, /**< Negotiate to @b ACQUIRE the + object's monitor lock again.*/ + THREAD_STATE_ACQUIRE = 13, /**< @b (transient state) + Re-acquired object's monitor + lock, may be @b RUNNABLE + again. */ + THREAD_STATE_DEAD = 14, /**< All work complete, ready to + deallocate thread slot. */ + THREAD_STATE_BADLOGIC = 15 /**< Not in spec, code convenience + for dealing with illegal + operational conditions. */ +} thread_state_enum; + + +#define THREAD_STATE_MIN_STATE THREAD_STATE_NEW /**< Lowest possible + state number */ +#define THREAD_STATE_MAX_STATE THREAD_STATE_BADLOGIC /**< Highest + possible state + number */ +/*@} */ /* End of grouped definitions */ + +/*! + * @name JVM state priority definitions. + * + */ + +/*@{ */ /* Begin grouped definitions */ + +typedef enum +{ + THREAD_PRIORITY_BAD = 0, /**< Not in spec, but useful in code */ + THREAD_PRIORITY_MIN = 1, /**< Minimum thread priority */ + THREAD_PRIORITY_NORM = 5, /**< Normal thread priority */ + THREAD_PRIORITY_MAX = 10 /**< Maximum thread priority */ + +} thread_priority_enum; + +/*@} */ /* End of grouped definitions */ + + +/*! + * @brief Real machine thread model implementation. + */ +typedef struct +{ + +/*********** Thread definitions ****************************/ + + jvm_thread_index id; /**< Self-same ID of this thread */ + + rchar *name; /**< Name of thread + * @todo not impl. + */ +#define THREAD_NAME_MAX_LEN 64 /**< Arbitrary max thread name length*/ + + jvm_object_hash thread_objhash;/**< Object hash for associated + java.lang.Thread object */ + + thread_priority_enum priority; /**< Runtime THREAD_PRIORITY_xxx */ + + rushort status; /**< Runtime status of thread, bitwise*/ + +/****** First 2 bits same for class, object, and thread ***********/ +#define THREAD_STATUS_EMPTY 0x0000 /**< This slot is available for use. + * DO NOT CHANGE since this + * is also the normal + * @c @b setjmp(3) return code + * from @link + #thread_exception_setup() + thread_exception_setup()@endlink + */ +#define THREAD_STATUS_INUSE 0x0001 /**< This slot contains a thread */ +#define THREAD_STATUS_NULL 0x0002 /**< Null thread (only 1 exists in + * normal use, any else besides the + * JVMCFG_NULL_THREAD is a thread + * slot that is being initialized.)*/ +/******************************************************************/ + +/****** The remaining bits are unique to thread *******************/ +#define THREAD_STATUS_ISDAEMON 0x0004 /**< Daemon thread state, vs user + thread, per Thread.isdaemon() */ + +#define THREAD_STATUS_SLEEP 0x0008 /**< thread is sleeping */ + +#define THREAD_STATUS_JOIN4EVER 0x0010 /**< thread has unconditionally + joined another */ + +#define THREAD_STATUS_JOINTIMED 0x0020 /**< thread has joined another, + but is waiting for a finite time */ + +#define THREAD_STATUS_WAIT4EVER 0x0040 /**< thread is unconditionally + waiting */ + +#define THREAD_STATUS_WAITTIMED 0x0080 /**< thread is waiting, but + finite time */ + +#define THREAD_STATUS_SUSPEND 0x0100 /**< thread is suspended, can + be resumed */ + +#define THREAD_STATUS_INTERRUPTIBLEIO 0x0200 /**< thread is waiting on + an interruptable I/O channel in class + java.nio.channels.InterruptibleChannel */ + +#define THREAD_STATUS_NOTIFIED 0x0400 /**< thread has been notified */ + + +#define THREAD_STATUS_INTERRUPTED 0x0800 /**< thread has been + interrupted */ + +#define THREAD_STATUS_THREW_EXCEPTION 0x1000 /**< thread threw a + * @c @b java.lang.Exception + * (but NOT a + * @c @b java.lang.Error). The + * object type is found in @link + #rthread.pThrowableEvent + pThrowableEvent@endlink and is not + * @link #rnull rnull@endlink. + */ + +#define THREAD_STATUS_THREW_ERROR 0x2000 /**< thread threw a + * @c @b java.lang.Error + * (but NOT a + * @c @b java.lang.Exception). + * The object type is found in @link + #rthread.pThrowableEvent + pThrowableEvent@endlink and is not + * @link #rnull rnull@endlink. + */ + +#define THREAD_STATUS_THREW_THROWABLE 0x4000 /**< thread threw a + * @c @b java.lang.Throwable + * of unknowable type. The + * object type is found in @link + #rthread.pThrowableEvent + pThrowableEvent@endlink and is not + * @link #rnull rnull@endlink. + */ + +#define THREAD_STATUS_THREW_UNCAUGHT 0x8000 /**< A + * @c @b java.lang.Throwable + * of some type was thrown, but not + * handled by the Java code itself. + * Instead, it will be handled + * by the default + @c @b java.lang.ThreadGroup.uncaughtException + * method. The value of @link + #rthread.pThrowableEvent + pThrowableEvent@endlink + * will be @link #rnull rnull@endlink. + */ + +/******************************************************************/ + + rchar *pThrowableEvent; /**< Exception, Error, or Throwable + * that was thrown by this thread. + * @link #rnull rnull@endlink + * if nothing was thrown. + */ + + jmp_buf *pnonlocal_ThrowableEvent; /**< Non-local return from + * Exception, Error, and Throwable + * conditions. + * + * @note Play pointer games to persuade + * runtime package to accept a jmp_buf + * that is within a structure. Whether + * this is a "feature" of the Solaris + * version of the library remains to be + * seen. + * + * Refer to opcode_run() for more + * information. + */ + + +/*********** State and blocking definitions ****************/ + + thread_state_enum prev_state; /**< Previous @link #THREAD_STATE_NEW + THREAD_STATE_xxx@endlink + (for diagnostics) */ + + thread_state_enum this_state; /**< Current @link #THREAD_STATE_NEW + THREAD_STATE_xxx@endlink */ + + thread_state_enum next_state; /**< Next scheduled + @link #THREAD_STATE_NEW + THREAD_STATE_xxx@endlink */ + + jvm_thread_index jointarget; /**< Doing @c @b Thread.join() + onto this thread */ + + volatile jlong sleeptime; /**< Milliseconds left on either + * @c @b Thread.sleep() + * or on a timed + * @c @b Thread.wait() + * or a timed + * @c @b Thread.join(). + * See also comments in + @link jvm/src/jvm.h jvm.h@endlink + * and in @link jvm/src/timeslice.c + timeslice.c@endlink. + */ + + jvm_object_hash locktarget; /**< Doing @c @b Object.wait() + * on this object. + * + * @todo This implementation can only + * handle ONE SINGLE monitor lock. + * Does it need to be able to + * handle arbitrary number of them at + * once? + */ + + +/*********** Program counter definitions *******************/ + + jvm_pc pc; /**< Program counter of this thread */ + + ruint pass_instruction_count; /**< Number of JVM instructions + * that have been run during this + * pass. + */ + + rulong thread_instruction_count; /**< Total number of JVM + * instructionsthat have been + * run by this thread. + */ + + +/*********** Stack pointer definitions *********************/ + + jint *stack; /**< Stack area for this thread */ + + jvm_sp sp; /**< Stack pointer of this thread */ + + jvm_sp fp; /**< Frame pointer in stack + to this stack frame. */ + + jvm_sp fp_end_program; /**< Final frame pointer in stack of + * place to stop execution, starting + * at beginning of program, but could + * be changed to a throwable event + * or some other arbitrary stack + * frame. Once the inner loop + * detects that the next stack frame + * would move beyond this boundary, + * JVM inner loop execution halts. + */ + +} rthread; + + +/*! + * @name Thread state name strings + * + */ + +/*@{ */ /* Begin grouped definitions */ + +extern const rchar *thread_state_name; + +#define THREAD_STATE_NEW_DESC "new" +#define THREAD_STATE_START_DESC "started" +#define THREAD_STATE_RUNNABLE_DESC "runnable" +#define THREAD_STATE_RUNNING_DESC "running" +#define THREAD_STATE_COMPLETE_DESC "complete" +#define THREAD_STATE_BLOCKINGEVENT_DESC "blockingevent" +#define THREAD_STATE_BLOCKED_DESC "blocked" +#define THREAD_STATE_UNBLOCKED_DESC "unblocked" +#define THREAD_STATE_SYNCHRONIZED_DESC "synchronized" +#define THREAD_STATE_RELEASE_DESC "release" +#define THREAD_STATE_WAIT_DESC "wait" +#define THREAD_STATE_NOTIFY_DESC "notify" +#define THREAD_STATE_LOCK_DESC "lock" +#define THREAD_STATE_ACQUIRE_DESC "acquire" +#define THREAD_STATE_DEAD_DESC "dead" +#define THREAD_STATE_BADLOGIC_DESC "bad_logic" +#define THREAD_STATE_ILLEGAL_DESC "illegal" + +/*@} */ /* End of grouped definitions */ + + +/* Prototypes for functions in 'thread.c' */ + +extern const rchar *thread_state_get_name(rushort state); + +extern jvm_thread_index thread_class_load(rchar *clsname, + rchar *mthname, + rchar *mthdesc, + rint priority, + rboolean isdaemon, + rboolean usesystemthread, + rboolean find_registerNatives); + +extern rvoid thread_init(rvoid); + +extern rboolean thread_die(jvm_thread_index thridx); + +extern rvoid thread_shutdown(rvoid); + +extern int thread_exception_setup(jvm_thread_index thridx); + +extern rvoid thread_throw_exception(jvm_thread_index thridx, + rushort thread_status_bits, + rchar *exception_name); + +/* Prototypes for functions in 'threadstate.c' */ + +/*! + * @name Thread state phases. + * + * @brief Each thread state has three phases, each of which is handled + * by a dedicated function. + * + * @b Requesting a state checks to see if a transition from the current + * state into the requested state is valid. If so, the @b NEXT + * state is set to the requested one. If not, the request is + * ignored. + * + * @b Activating a state moves the thread into the requested @b NEXT + * state so its @b THIS state changes. Its @b PREV state then reports + * the former state. + * + * @b Processing a state performs the activities for that state. + * + * + * @param thridx Thread table index of thread to process. + * + * + * @returns @link #rtrue rtrue@endlink if activities transpired + * normally, otherwise @link #rfalse rfalse@endlink. + * + */ + +/*@{ */ /* Begin grouped definitions */ + +extern rboolean threadstate_request_new(jvm_thread_index thridx); +extern rboolean threadstate_request_start(jvm_thread_index thridx); +extern rboolean threadstate_request_runnable(jvm_thread_index thridx); +extern rboolean threadstate_request_running(jvm_thread_index thridx); +extern rboolean threadstate_request_complete(jvm_thread_index thridx); +extern rboolean threadstate_request_blockingevent(jvm_thread_index + thridx); +extern rboolean threadstate_request_blocked(jvm_thread_index thridx); +extern rboolean threadstate_request_unblocked(jvm_thread_index thridx); +extern rboolean threadstate_request_synchronized(jvm_thread_index + thridx); +extern rboolean threadstate_request_release(jvm_thread_index thridx); +extern rboolean threadstate_request_wait(jvm_thread_index thridx); +extern rboolean threadstate_request_notify(jvm_thread_index thridx); +extern rboolean threadstate_request_lock(jvm_thread_index thridx); +extern rboolean threadstate_request_acquire(jvm_thread_index thridx); +extern rboolean threadstate_request_dead(jvm_thread_index thridx); +extern rboolean threadstate_request_badlogic(jvm_thread_index thridx); + +extern rboolean threadstate_activate_new(jvm_thread_index thridx); +extern rboolean threadstate_activate_start(jvm_thread_index thridx); +extern rboolean threadstate_activate_runnable(jvm_thread_index thridx); +extern rboolean threadstate_activate_running(jvm_thread_index thridx); +extern rboolean threadstate_activate_complete(jvm_thread_index thridx); +extern rboolean threadstate_activate_blockingevent(jvm_thread_index + thridx); +extern rboolean threadstate_activate_blocked(jvm_thread_index thridx); +extern rboolean threadstate_activate_unblocked(jvm_thread_index thridx); +extern rboolean threadstate_activate_synchronized(jvm_thread_index + thridx); +extern rboolean threadstate_activate_release(jvm_thread_index thridx); +extern rboolean threadstate_activate_wait(jvm_thread_index thridx); +extern rboolean threadstate_activate_notify(jvm_thread_index thridx); +extern rboolean threadstate_activate_lock(jvm_thread_index thridx); +extern rboolean threadstate_activate_acquire(jvm_thread_index thridx); +extern rboolean threadstate_activate_dead(jvm_thread_index thridx); +extern rboolean threadstate_activate_badlogic(jvm_thread_index thridx); + +extern rboolean threadstate_process_new(jvm_thread_index thridx); +extern rboolean threadstate_process_start(jvm_thread_index thridx); +extern rboolean threadstate_process_runnable(jvm_thread_index thridx); +extern rboolean threadstate_process_running(jvm_thread_index thridx); +extern rboolean threadstate_process_complete(jvm_thread_index thridx); +extern rboolean threadstate_process_blockingevent(jvm_thread_index + thridx); +extern rboolean threadstate_process_blocked(jvm_thread_index thridx); +extern rboolean threadstate_process_unblocked(jvm_thread_index thridx); +extern rboolean threadstate_process_synchronized(jvm_thread_index + thridx); +extern rboolean threadstate_process_release(jvm_thread_index thridx); +extern rboolean threadstate_process_wait(jvm_thread_index thridx); +extern rboolean threadstate_process_notify(jvm_thread_index thridx); +extern rboolean threadstate_process_lock(jvm_thread_index thridx); +extern rboolean threadstate_process_acquire(jvm_thread_index thridx); +extern rboolean threadstate_process_dead(jvm_thread_index thridx); +extern rboolean threadstate_process_badlogic(jvm_thread_index thridx); + +/*@} */ /* End of grouped definitions */ + + +/* Prototypes for functions in 'threadutil.c' */ +extern rvoid threadutil_update_sleeptime_interval(rvoid); + +extern rvoid threadutil_update_blockingevents(jvm_thread_index + thridxcurr); + +extern rvoid threadutil_update_wait(jvm_thread_index thridxcurr); + +extern rvoid threadutil_update_lock(jvm_thread_index thridxcurr); + +extern rboolean threadutil_holds_lock(jvm_thread_index thridx, + jvm_object_hash objhashlock); + +#endif /* _thread_h_included_ */ + + +/* EOF */ Added: incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadstate.c URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadstate.c?rev=307257&view=auto ============================================================================== --- incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadstate.c (added) +++ incubator/harmony/enhanced/trunk/sandbox/contribs/bootjvm/bootJVM/jvm/src/threadstate.c Fri Oct 7 21:27:56 2005 @@ -0,0 +1,1311 @@ +/*! + * @file threadstate.c + * + * @brief Validate and perform state transitions, and process each + * state of the JVM thread state machin. + * + * This implementation of the JVM state machine using both stable and + * transient states. The thread system operates as a state machine + * based on the JVM spec requirements. The states for this + * implementation are shown below. Those marked @b (+) are + * transient states and will move forward to the next stable + * state as soon as possible: + * + * + * + * The state transitions are: + * + * + * + * The first line (line a) is the main flow of control. + * + * (line b) depend on various programmatic events such as + * java.lang.Thread.yield() invocation and normal JVM thread + * arbitration. + * + * (line c) involves scheduled programmatic events like + * java.lang.Thread.sleep() and java.lang.Thread.join(), + * java.lang.Thread.interrupt() events (line c), + * or interruptible I/O operations. + * + * (line d) depicts @c @b synchronized() requests (line d) + * + * (line e) involives java.lang.Object.wait() requests (after + * object lock acquired) via java.lang.Object.notify() or + * java.lang.Object.notifyAll() or java.lang.Thread.interrupt() + * events. + * + * (line f), shows the so-called "stillborn" thread that dies + * before it has a chance to java.lang.Thread.start(). + * + * (lines g, h, i), demonstrates how this implementation + * gracefully minimizes the damage of the deprecated + * java.lang.Thread.destroy(), java.lang.Thread.stop(), + * java.lang.Thread.suspend(), and java.lang.Thread.resume(). + * + * (line j), shows a state that has been added to handle errors, + * typically from development and testing. This provides a valid + * state transition that may be done programmatically to sideline + * any desired thread. + * + * Notice that there are more states here than in the classic model + * for the JVM. Part of the reason for this is that a finer granularity + * of control provides the state model with an insertion point for + * diagnostics of the state model, especially in the transient states + * (namely @b START, @b RELEASE, @b SYNCHRONIZED, @b NOTIFY, @b ACQUIRE, + * and @b COMPLETE). This is complementary to the definition of each + * state. The implementation of this model includes three groups of + * functions named after each of three phases of state change and + * processing and after each state name: + * + * + * + * These three stages in the JVM outer loop provide immediate + * diagnostics in case of problems with state transitions, which is, + * of course, useful during development, but can also provide + * safeguards during normal runtime. The processing overhead is + * negligible since it is in the @e outer loop. + * All groups of routines return a boolean describing whether or not + * the activities for that phase of that state succeeded. For example, + * thread_request_runnable() attempts to take a thread from its current + * state into + * @link #THREAD_STATE_RUNNABLE THREAD_STATE_RUNNABLE@endlink. + * If it succeeds, it returns @link #rtrue rtrue@endlink, otherwise + * @link #rfalse rfalse@endlink. + * + * All transition requests work @e exactly the same way. The actual + * performance of that change may require doing some work, depending + * on the particular state being requested, but most require only a + * simple state transition. For example, the beginning of the world is + * threadstate_request_start(), which is equivalent to the + * java.lang.Thread method java.lang.Thread.start(). + * At various times during development, it had some work to perform + * as the thread state model was integrated into the JVM, such as + * loading the JVM's PC with the entry point of the correct method. + * But in the case of threadstate_request_unblocked(), a state + * transition will also be requested since it is a transitory state in + * addition to any other work it may perform. + * + * All logic for each state change is found within its respective + * @b threadstate_[@link #threadstate_request_new() request@endlink| + @link #threadstate_activate_new() activate@endlink + @link #threadstate_process_new() process@endlink]_XXX() + * function below. + * + * + * @attention: Only a @b NEW thread may be moved into the @b START + * state. Only an @link #THREAD_STATUS_EMPTY + THREAD_STATUS_EMPTY@endlink thread may be moved into + * @link #THREAD_STATUS_INUSE THREAD_STATUS_INUSE@endlink + * status and hence the @b NEW state. Only the + * @link #JVMCFG_NULL_THREAD JVMCFG_NULL_THREAD@endlink + * may be permanently marked as being + * @link #THREAD_STATUS_NULL THREAD_STATUS_NULL@endlink. + * These two conditions must @e never be manipulated + * by thread_new() and thread_die(). + * + * + * @section Control + * + * \$URL: https://svn.apache.org/path/name/threadstate.c $ \$Id: threadstate.c 0 09/28/2005 dlydick $ + * + * Copyright 2005 The Apache Software Foundation + * or its licensors, as applicable. + * + * Licensed under the Apache License, Version 2.0 ("the License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the License for the specific language governing permissions + * and limitations under the License. + * + * @version \$LastChangedRevision: 0 $ + * + * @date \$LastChangedDate: 09/28/2005 $ + * + * @author \$LastChangedBy: dlydick $ + * Original code contributed by Daniel Lydick on 09/28/2005. + * + * @section Reference + * + */ + +#include "arch.h" +ARCH_COPYRIGHT_APACHE(threadstate, c, "$URL: https://svn.apache.org/path/name/threadstate.c $ $Id: threadstate.c 0 09/28/2005 dlydick $"); + + +#include "jvmcfg.h" +#include "classfile.h" +#include "jvm.h" +#include "opcode.h" + + +/*! + * @name State phase macros + * + * @brief Macros to support the three phases of moving from one + * thread state to another. + * + * See section on the JVM thread model state machine for an explanation + * as to @e why these functions exist. Concerning @e how they operate, + * an example of their usage in the @b START state functions will + * provide clear guidance of how to use them generally. The first state + * transition request is always from @b NEW to @b START. The macro + * expansion of the macros inside of @link #threadstate_request_start() + threadstate_request_start()@endlink demonstrate syntax for how + * this accomplihed. Following that is the syntax for @link + #threadstate_activate_start() threadstate_activate_start()@endlink + * and @link #threadstate_process_start() + threadstate_process_start()@endlink. The declaration of these + * three functions follows later. For good form when using these + * functions with these state phase macros, be sure to place + * the whole of the second parameter expression of STATE_REQUEST() + * in (parentheses). + * + * Transition is shown from @b NEW to @b START to show a more + * normal example than from "not in use" to @b NEW. + * + * The expansion of the macros inside of the three @b START functions + * produces the following code: + * + * @verbatim + rboolean threadstate_request_start(jvm_thread_index thridx) + { + if (THREAD_STATE_NEW == THREAD(thridx).this_state) + { + THREAD(thridx).next_state = THREAD_STATE_START; + + ** use (rtrue) if nothing else needed ** + return((rtrue) ? rtrue : rfalse); + } + else + { + return(rfalse); + }; + } + + rboolean threadstate_activate_start(jvm_thread_index thridx) + { + if (THREAD_STATE_START == THREAD(thridx).next_state) + { + ** Record previous state when changing to next one ** + THREAD(thridx).prev_state = THREAD(thridx).this_state; + THREAD(thridx).this_state = THREAD(thridx).next_state; + } + if (THREAD_STATE_START == THREAD(thridx).this_state) + { + return((rtrue) ? rtrue : rfalse); + } + else + { + return(rfalse); + }; + } + + rboolean threadstate_process_start(jvm_thread_index thridx) + { + if (THREAD_STATE_START == THREAD(thridx).this_state) + { + + ** ... Process activities for this thread state here ... ** + + ** use (rtrue) if nothing else needed ** + return((threadstate_request_runnable(thridx)) ? rtrue:rfalse); + } + else + { + return(rfalse); + }; + } + + @endverbatim + * + */ + +/*@{ */ /* Begin grouped definitions */ + +/*! + * @def STATE_REQUEST() + * + * @brief Request a state change from this state to another state. + * + * + * @param upper New state name in UPPER CASE (for macro + * expansion purposes) + * + * @param unique_state_test BE SURE to put put this parameter + * in (parentheses) for proper macro expansion! + * Permit state change into requested state + * @e only if this expression evaluates to + * @link #rtrue rtrue@endlink, which may be + * explicitly stated if this state change is + * unconditional. + * + * @returns @link #rtrue rtrue@endlink if state change was permitted, + * otherwise @link #rfalse rfalse@endlink. + * + */ +#define STATE_REQUEST(upper, unique_state_test) \ + if (unique_state_test) \ + { \ + NEXT_STATE(thridx) = THREAD_STATE_##upper + +/* } ignore-- keeps text editors happy */ + +/*! + * @def STATE_ACTIVATE() + * + * @brief Activate a state change that was validated by + * @link #STATE_REQUEST() STATE_REQUEST()@endlink. + * + * + * @param upper New state name in UPPER CASE (for macro + * expansion purposes) + * + * + * @returns @link #rtrue rtrue@endlink if state change was permitted, + * otherwise @link #rfalse rfalse@endlink. + * + */ +#define STATE_ACTIVATE(upper) \ + if (THREAD_STATE_##upper == NEXT_STATE(thridx)) \ + { \ + /* Record previous state when changing to next one */ \ + PREV_STATE(thridx) = THIS_STATE(thridx); \ + THIS_STATE(thridx) = NEXT_STATE(thridx); \ + } \ + \ + if (THREAD_STATE_##upper == THIS_STATE(thridx)) \ + { + +/* } ignore-- keeps text editors happy */ + +/*! + * @def STATE_PROCESS() + * + * @brief Process a state change that was activated by + * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink. + * + * + * @param upper New state name in UPPER CASE (for macro + * expansion purposes) + * + * + * @returns @link #rtrue rtrue@endlink if state change was permitted, + * otherwise @link #rfalse rfalse@endlink. + * + */ +#define STATE_PROCESS(upper) \ + if (THREAD_STATE_##upper == THIS_STATE(thridx)) \ + { + +/* } ignore-- keeps text editors happy */ + +/* { ignore-- keeps text editors happy */ + +/*! + * @def STATE_END() + * + * @brief Terminate the code fragment initiated by + * @link #STATE_REQUEST() STATE_REQUEST()@endlink or + * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink or + * @link #STATE_PROCESS() STATE_PROCESS()@endlink. + * + * In between the @link #STATE_REQUEST() STATE_REQUEST()@endlink and + * @link #STATE_ACTIVATE() STATE_ACTIVATE()@endlink and + * @link #STATE_PROCESS() STATE_PROCESS()@endlink macro instance and + * this macro, any phase-specific, state-specific code may be inserted. + * Although most states do not do so, pay particular attention + * to those that do, also any comments that may be present in lieu of + * code. + * + */ +#define STATE_END(expr) \ + /* use (rtrue) if nothing else needed */ \ + return((expr) ? rtrue : rfalse); \ + } \ + else \ + { \ + return(rfalse); \ + } + +/*@} */ /* End of grouped definitions */ + + +/*! + * @name JVM thread model state machine + * + * @brief Implement the JVM state machine using both stable and + * transient states. + * + * See tables above for full description. + * + * + * @todo Need to find a way (per spec section 5.3.5) to throw + * a java.lang.LinkageError and/or java.lang.ClassFormatError + * for bad classfile representations. Also major/minor versions + * mismatch should throw + * java/class/UnsupportedClassVersion error. + * + * + * @param thridx thread index of thread whose state is to be changed. + * + * + * @returns @link #rtrue rtrue@endlink if all activities were + * successful, else @link #rfalse rfalse@endlink. + * + */ + +/*@{ */ /* Begin grouped definitions */ + + +/*****************************************************************/ + +/*! + * @brief Request the @b NEW thread state. + * + * The @b NEW state starts the whole state machine for a thread. + * + */ +rboolean threadstate_request_new(jvm_thread_index thridx) +{ + STATE_REQUEST(NEW, (rtrue)); + STATE_END(rtrue); +} + + +/*! + * @brief Activate the @b NEW thread state for a new thread. + * + */ +rboolean threadstate_activate_new(jvm_thread_index thridx) +{ + STATE_ACTIVATE(NEW); + STATE_END(rtrue); +} + + +/*! + * @brief Process the @b NEW thread state. + * + * The @b NEW state idles until the @b START state is requested. + * + */ +rboolean threadstate_process_new(jvm_thread_index thridx) +{ + STATE_PROCESS(NEW); + STATE_END(rtrue); +} + +/*****************************************************************/ + +/*! + * @brief Request the @b START state. + * + * The @b START state can only be entered from @b NEW. + * + */ + +rboolean threadstate_request_start(jvm_thread_index thridx) +{ + STATE_REQUEST(START, (THREAD_STATE_NEW == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b START thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_start(jvm_thread_index thridx) +{ + STATE_ACTIVATE(START); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b START thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b START to @b RUNNABLE is requested here. + * + */ +rboolean threadstate_process_start(jvm_thread_index thridx) +{ + STATE_PROCESS(START); + + /* ... Process activities for this thread state here ... */ + + STATE_END(threadstate_request_runnable(thridx)); +} + +/*****************************************************************/ + +/*! + * @brief Request the @b RUNNABLE state. + * + * The @b RUNNABLE state can be entered from @b START, @b RUNNING, + * @b UNBLOCKED, or @b ACQUIRE. + * + */ +rboolean threadstate_request_runnable(jvm_thread_index thridx) +{ + STATE_REQUEST(RUNNABLE, + ((THREAD_STATE_START == THIS_STATE(thridx)) || + (THREAD_STATE_RUNNING == THIS_STATE(thridx)) || + (THREAD_STATE_UNBLOCKED == THIS_STATE(thridx)) || + (THREAD_STATE_ACQUIRE == THIS_STATE(thridx)) )); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b RUNNABLE thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_runnable(jvm_thread_index thridx) +{ + STATE_ACTIVATE(RUNNABLE); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b RUNNABLE thread state. + * + * Always try to keep @b RUNNABLE thread in the @b RUNNING state. + * Although not formally a transient state, @b RUNNABLE indicates + * that a thread is @e potentially one that could be @b RUNNING, + * thus the attempt to keep it there. + * + */ +rboolean threadstate_process_runnable(jvm_thread_index thridx) +{ + STATE_PROCESS(RUNNABLE); + STATE_END(rtrue); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b RUNNING state. + * + * The @b RUNNING state can only be entered from @b RUNNABLE. + * + * The JVM inner execution loop is called from + * threadstate_process_running(), causing any thread in the + * @b RUNNING state to normally keep executing its code + * from where it left off last time. + * + */ +rboolean threadstate_request_running(jvm_thread_index thridx) +{ + STATE_REQUEST(RUNNING, + (THREAD_STATE_RUNNABLE == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b RUNNING thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_running(jvm_thread_index thridx) +{ + STATE_ACTIVATE(RUNNING); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b RUNNING thread state. + * + * Run the next virtual instruction engine on the + * current thread from where it left off last time. + * + * @attention Notice that the normal way to invoke + * opcode_run() is in this location, as + * driven by the JVM outer loop in jvm_run(). + * + */ +rboolean threadstate_process_running(jvm_thread_index thridx) +{ + STATE_PROCESS(RUNNING); + + STATE_END(opcode_run(CURRENT_THREAD, rtrue)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b COMPLETE state. + * + * The @b COMPLETE state can be entered from @b NEW or @b RUNNING + * or @b BADLOGIC. + * + * When entered from @b NEW, it is a so-called "stillborn" thread that + * was created but never used. + * + * When entered from @b BADLOGIC, java.lang.Thread.destroy() or + * java.lang.Thread.stop() was invoked, both of which are + * dangerous, deprecated methods. + * + */ +rboolean threadstate_request_complete(jvm_thread_index thridx) +{ + STATE_REQUEST(COMPLETE, + ((THREAD_STATE_NEW == THIS_STATE(thridx)) || + (THREAD_STATE_RUNNING == THIS_STATE(thridx)) || + (THREAD_STATE_BADLOGIC == THIS_STATE(thridx)))); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b COMPLETE thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_complete(jvm_thread_index thridx) +{ + STATE_ACTIVATE(COMPLETE); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b COMPLETE thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b COMPLETE to @b DEAD is requested here. + * + */ +rboolean threadstate_process_complete(jvm_thread_index thridx) +{ + STATE_PROCESS(COMPLETE); + STATE_END(threadstate_request_dead(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b BLOCKINGEVENT state. + * + * The @b BLOCKINGEVENT state can be entered from the + * @b RUNNING or @b BADLOGIC states. This can be caused by + * java.lang.Thread.sleep() and java.lang.Thread.join() and + * interruptible I/O operations. Also, deprecated + * java.lang.Thread.suspend() can go through @b BADLOGIC + * to get here. + * + */ +rboolean threadstate_request_blockingevent(jvm_thread_index thridx) +{ + STATE_REQUEST(BLOCKINGEVENT, + ((THREAD_STATE_RUNNING == THIS_STATE(thridx)) || + (THREAD_STATE_BADLOGIC == THIS_STATE(thridx)))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b BLOCKINGEVENT thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_blockingevent(jvm_thread_index thridx) +{ + STATE_ACTIVATE(BLOCKINGEVENT); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b BLOCKINGEVENT thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b BLOCKINGEVENT to @b BLOCKED is requested here. + * + */ +rboolean threadstate_process_blockingevent(jvm_thread_index thridx) +{ + STATE_PROCESS(BLOCKINGEVENT); + + STATE_END(threadstate_request_blocked(thridx)); +} + +/*****************************************************************/ + +/*! + * @brief Request the @b BLOCKED state. + * + * The @b BLOCKED state can only be entered from @b BLOCKINGEVENT. + * + */ +rboolean threadstate_request_blocked(jvm_thread_index thridx) +{ + STATE_REQUEST(BLOCKED, + (THREAD_STATE_BLOCKINGEVENT == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b BLOCKED thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_blocked(jvm_thread_index thridx) +{ + STATE_ACTIVATE(BLOCKED); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b BLOCKED thread state. + * + * The @b BLOCKED state idles until the @b UNBLOCKED state + * is requsted by threadutil_update_blockingevents(). + * + */ +rboolean threadstate_process_blocked(jvm_thread_index thridx) +{ + STATE_PROCESS(BLOCKED); + STATE_END(rtrue); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b UNBLOCKED state. + * + * The @b UNBLOCKED state can only be entered from @b BLOCKED. + * + */ +rboolean threadstate_request_unblocked(jvm_thread_index thridx) +{ + STATE_REQUEST(UNBLOCKED, + (THREAD_STATE_UNBLOCKED == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b UNBLOCKED thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_unblocked(jvm_thread_index thridx) +{ + STATE_ACTIVATE(UNBLOCKED); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b UNBLOCKED thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b UNBLOCKED to @b RUNNABLE is requested here. + * + */ +rboolean threadstate_process_unblocked(jvm_thread_index thridx) +{ + STATE_PROCESS(UNBLOCKED); + + STATE_END(threadstate_request_runnable(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b SYNCHRONIZED state. + * + * The @b SYNCHRONIZED state can only be entered from @b RUNNING. + * + */ +rboolean threadstate_request_synchronized(jvm_thread_index thridx) +{ + STATE_REQUEST(SYNCHRONIZED, + (THREAD_STATE_RUNNING == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b SYNCHRONIZED thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_synchronized(jvm_thread_index thridx) +{ + STATE_ACTIVATE(SYNCHRONIZED); + STATE_END(rtrue); +} + +/*! + * @brief Process the @b SYNCHRONIZED thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b SYNCHRONIZED to @b LOCK is requested here. + * + */ +rboolean threadstate_process_synchronized(jvm_thread_index thridx) +{ + STATE_PROCESS(SYNCHRONIZED); + + STATE_END(threadstate_request_lock(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b RELEASE state. + * + * The @b RELEASE state can only be entered from @b RUNNING. + * + */ +rboolean threadstate_request_release(jvm_thread_index thridx) +{ + STATE_REQUEST(RELEASE, + (THREAD_STATE_RUNNING == THIS_STATE(thridx))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b RELEASE thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_release(jvm_thread_index thridx) +{ + STATE_ACTIVATE(RELEASE); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b RELEASE thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b RELEASE to @b WAIT is requested here. + * However, this will @e only occur if this thread + * holds the lock on the @link #rthread.locktarget + rthread.locktarget@endlink object. + * + */ +rboolean threadstate_process_release(jvm_thread_index thridx) +{ + STATE_PROCESS(RELEASE); + + jvm_object_hash locktarget = THREAD(thridx).locktarget; + + /* + * Check if this thread holds an object monitor lock. + * If not, clear JOIN status and abort. + */ + if (rfalse == threadutil_holds_lock(thridx, locktarget)) + { + THREAD(thridx).status &= ~(THREAD_STATUS_JOIN4EVER | + THREAD_STATUS_JOINTIMED); + return(rfalse); + } + + /* + * Release lock and go to @b WAIT. + * + * But first, clear the monitor lock on the object. + * However, DO NOT wipe the @link #rthread.locktarget + locktarget@endlink object hash in the thread. + * It will be needed when in the @b LOCK state to + * @b ACQUIRE the lock again. + */ + (rvoid) objectutil_unsynchronize(locktarget, thridx); + + STATE_END(threadstate_request_wait(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b WAIT state. + * + * The @b WAIT state can only be entered from @b RELEASE. + * + */ +rboolean threadstate_request_wait(jvm_thread_index thridx) +{ + STATE_REQUEST(WAIT, (THREAD_STATE_RELEASE == THIS_STATE(thridx))); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b WAIT thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_wait(jvm_thread_index thridx) +{ + STATE_ACTIVATE(WAIT); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b WAIT thread state. + * + * The @b WAIT state idles until the @b NOTIFY state + * is requsted by threadutil_update_wait(). + * + */ +rboolean threadstate_process_wait(jvm_thread_index thridx) +{ + STATE_PROCESS(WAIT); + + STATE_END(rtrue); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b NOTIFY state. + * + * The @b NOTIFY state can only be entered from @b WAIT. + * + */ +rboolean threadstate_request_notify(jvm_thread_index thridx) +{ + STATE_REQUEST(NOTIFY, (THREAD_STATE_WAIT == THIS_STATE(thridx))); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b NOTIFY thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_notify(jvm_thread_index thridx) +{ + STATE_ACTIVATE(NOTIFY); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b NOTIFY thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b NOTIFY to @b LOCK is requested here. + * + */ +rboolean threadstate_process_notify(jvm_thread_index thridx) +{ + STATE_PROCESS(NOTIFY); + + STATE_END(threadstate_request_lock(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b LOCK state. + * + * The @b LOCK state can be entered from @b SYNCHRONIZED or @b NOTIFY. + * + */ +rboolean threadstate_request_lock(jvm_thread_index thridx) +{ + STATE_REQUEST(LOCK, + ((THREAD_STATE_SYNCHRONIZED == THIS_STATE(thridx)) || + (THREAD_STATE_NOTIFY == THIS_STATE(thridx)))); + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b LOCK thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_lock(jvm_thread_index thridx) +{ + STATE_ACTIVATE(LOCK); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b LOCK thread state. + * + * THIS IS THE PLACE WHERE THREADS COMPETE FOR AN OBJECT + * MONITORY LOCK. If a thread is able to successfully + * run objectutil_synchronize(), then it acquires the MLOCK + * for that object and moves from the @b LOCK state forward + * to the @b ACQUIRE state. + * + * The @b LOCK state idles until the @b ACQUIRE state + * is requsted by threadutil_update_lock(). + * + */ +rboolean threadstate_process_lock(jvm_thread_index thridx) +{ + STATE_PROCESS(LOCK); + + /* + * Attempt to acquire object's monitor lock (MLOCK), + * first come first served. Go to @b ACQUIRE state + * if ownership was achieved. If not achieved, stay + * here in the @b LOCK state and keep asking. + * + * The objectutil_synchronize() call will fail until the + * MLOCK bit is clear on this object, at which time the + * lock is acquired by this thread. At that time, the + * thread can move forward to the @b ACQUIRE state. + */ + if (rtrue == objectutil_synchronize(THREAD(thridx).locktarget, + thridx)) + { + /* + * Should succeed since now in @b LOCK state, so return code + * should always be @link #rtrue rtrue@endlink. + */ + (rvoid) threadstate_request_acquire(thridx); + } + + STATE_END(rtrue); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b ACQUIRE state. + * + * The @b ACQUIRE state can only be entered from @b LOCK. + * + */ +rboolean threadstate_request_acquire(jvm_thread_index thridx) +{ + STATE_REQUEST(ACQUIRE, (THREAD_STATE_LOCK == THIS_STATE(thridx))); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b ACQUIRE thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_acquire(jvm_thread_index thridx) +{ + STATE_ACTIVATE(ACQUIRE); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b ACQUIRE thread state. + * + * THIS IS A TRANSIENT STATE! A state change + * from @b ACQUIRE to @b RUNABLE is requested here. + * + */ +rboolean threadstate_process_acquire(jvm_thread_index thridx) +{ + STATE_PROCESS(ACQUIRE); + + STATE_END(threadstate_request_runnable(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b DEAD state. + * + * The @b DEAD state can only be entered from @b COMPLETE. + * + */ +rboolean threadstate_request_dead(jvm_thread_index thridx) +{ + STATE_REQUEST(DEAD, (THREAD_STATE_COMPLETE == THIS_STATE(thridx))); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b DEAD thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_dead(jvm_thread_index thridx) +{ + STATE_ACTIVATE(DEAD); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b DEAD thread state. + * + * Bogus, yet true: THIS IS A TRANSIENT STATE! the usual + * message about this state applies, yet the target state is + * the "not used" condition, so it may also be considered + * inapplicable. Here 'tis: + * + * THIS IS A TRANSIENT STATE! A state change + * from @b DEAD to "not used" is requested here. + * + * So how is this statement true? Because thread_die() + * is called once the thread enters this condition, removing + * it from the array of active thread table entries. + * + */ +rboolean threadstate_process_dead(jvm_thread_index thridx) +{ + STATE_PROCESS(DEAD); + + STATE_END(thread_die(thridx)); +} + + +/*****************************************************************/ + +/*! + * @brief Request the @b BADLOGIC state. + * + * The @b BADLOGIC state can be entered from @e ANY state. + * It is primarily a diagnostic state, but may be used + * to gracefully handle java.lang.Thread.destroy() and + * java.lang.Thread.stop() and java.lang.Thread.suspend() + * and java.lang.Thread.resume(). + * + */ +rboolean threadstate_request_badlogic(jvm_thread_index thridx) +{ + STATE_REQUEST(BADLOGIC, (rtrue)); + + STATE_END(rtrue); +} + +/*! + * @brief Activate the @b BADLOGIC thread state of a thread known + * to be coming from a valid previous state. + * + */ +rboolean threadstate_activate_badlogic(jvm_thread_index thridx) +{ + STATE_ACTIVATE(BADLOGIC); + + STATE_END(rtrue); +} + +/*! + * @brief Process the @b BADLOGIC thread state. + * + * The @b BADLOGIC state idles until another state is requested. + * An "Idle forever" error message might be printed by code that + * invoked this state. If desired, this state can be moved + * forward to @b COMPLETE or @b BLOCKINGEVENT. Part of the + * request logic for these states is to permit entrance + * from the @b BADLOGIC state. + * + */ +rboolean threadstate_process_badlogic(jvm_thread_index thridx) +{ + STATE_PROCESS(BADLOGIC); + + STATE_END(rtrue); +} + +/*@} */ /* End of grouped definitions */ + + +/* EOF */