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

jlThread.c

Go to the documentation of this file.
00001 /*!
00002  * @file jlThread.c
00003  *
00004  * @brief Native implementation of @c @b java.lang.Thread
00005  *
00006  * @todo  Perform intelligent check on input parameter
00007  *        @b objhash range for all functions.
00008  *
00009  * @todo  In real life, the @b objhashthis values and @b clsidxthis
00010  *        values will be valid or these functions could not be
00011  *        invoked since these data types are @e mandatory for
00012  *        referencing them.  This probably means that the parameter
00013  *        valididty checking could probably be relaxed.
00014  *
00015  * @section Control
00016  *
00017  * \$URL: https://svn.apache.org/path/name/jlThread.c $ \$Id: jlThread.c 0 09/28/2005 dlydick $
00018  *
00019  * Copyright 2005 The Apache Software Foundation
00020  * or its licensors, as applicable.
00021  *
00022  * Licensed under the Apache License, Version 2.0 ("the License");
00023  * you may not use this file except in compliance with the License.
00024  * You may obtain a copy of the License at
00025  *
00026  *     http://www.apache.org/licenses/LICENSE-2.0
00027  *
00028  * Unless required by applicable law or agreed to in writing,
00029  * software distributed under the License is distributed on an
00030  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00031  * either express or implied.
00032  *
00033  * See the License for the specific language governing permissions
00034  * and limitations under the License.
00035  *
00036  * @version \$LastChangedRevision: 0 $
00037  *
00038  * @date \$LastChangedDate: 09/28/2005 $
00039  *
00040  * @author \$LastChangedBy: dlydick $
00041  *         Original code contributed by Daniel Lydick on 09/28/2005.
00042  *
00043  * @section Reference
00044  *
00045  */
00046 
00047 #include "arch.h"
00048 ARCH_COPYRIGHT_APACHE(jlThread, c, "$URL: https://svn.apache.org/path/name/jlThread.c $ $Id: jlThread.c 0 09/28/2005 dlydick $");
00049 
00050 
00051 #include "jvmcfg.h"
00052 #include "classfile.h"
00053 #include "jvm.h"
00054 #include "jvmclass.h"
00055 #include "linkage.h"
00056 
00057 
00058 /*!
00059  * @name Native implementation of java.lang.Thread.sleep() functions.
00060  *
00061  * @brief Sleep based on millisecond timer ticks.
00062  *
00063  * Results are undefined if thread has the @b JOIN4EVER, @b JOINTIMED,
00064  * @b WAIT4EVER, @b WAITTIMED, or @b INTERRUPTIBLEIO status or if thread
00065  * has been @b NOTIFIED or @b INTERRUPTED.
00066  *
00067  * This will only succeed if thread is in @b RUNNING state.
00068  *
00069  * The <b><code>sleep(ms, ns)</code></b> version ignores the
00070  * nanoseconds parameter and works just like
00071  * <b><code>sleep(ms)</code></b>.
00072  *
00073  * The class index of the current class is always passed
00074  * as the first parameter.
00075  *
00076  *
00077  * @param  clsidxthis              Class table index of the class of
00078  *                                 @c @b this object, namely,
00079  *                                 @c @b java.lang.Thread .
00080  *
00081  * @param  sleeptime_milliseconds  Number of timer ticks (milliseconds)
00082  *                                 to sleep.
00083  *
00084  * @param  sleeptime_nanoseconds   Number of nanoseconds to sleep
00085  *                                 in addition to the milliseconds.
00086  *
00087  *
00088  * @returns @link #jvoid jvoid@endlink
00089  *
00090  *
00091  * @throws JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00092  *         @link #JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00093            if another thread had interrupted this thread@endlink.
00094  *
00095  *
00096  * @note These @c @b java.lang.Thread methods are unusual in that
00097  * they does not require a @c @b jobject (in parlance of this
00098  * implementation, a @link #jvm_object_hash jvm_object_hash@endlink)
00099  * to run because they are declared as @c @b static methods.  As
00100  * implemented here, the usual @b objhashthis parameter is therefore
00101  * replaced by * @b clsidxthis.  The thread context is located in
00102  * @link #CURRENT_THREAD CURRENT_THREAD@endlink.
00103  *
00104  *
00105  * @todo Make sure thread interruption logic below here is working.
00106  *
00107  */
00108 
00109 /*@{ */ /* Begin grouped definitions */
00110 
00111 /*!
00112  * @brief Native implementation of millisecond
00113  * sleep method @c @b java.lang.Thread.sleep(jlong)
00114  *
00115  */
00116 
00117 jvoid jlThread_sleep(jvm_class_index clsidxthis,
00118                      jlong           sleeptime_milliseconds)
00119 {
00120     /* Current thread always assumed valid */
00121     jvm_thread_index thridx = CURRENT_THREAD;
00122 
00123     THREAD(thridx).status |= THREAD_STATUS_SLEEP;
00124     THREAD(thridx).sleeptime = sleeptime_milliseconds;
00125     (rvoid) threadstate_request_runnable(thridx);
00126 
00127     return;
00128 
00129 } /* END of jlThread_sleep() */
00130 
00131 
00132 /*!
00133  *
00134  * @brief Native implementation of millisecond and nanosecond
00135  * sleep method <b><code>java.lang.Thread.sleep(jlong, jint)</code></b>
00136  *
00137  * Ignore the @b sleeptime_nanoseconds parameter in this implementation.
00138  *
00139  */
00140 jvoid jlThread_sleep_nanos(jvm_class_index clsidxthis,
00141                            jlong           sleeptime_milliseconds,
00142                            jint            sleeptime_nanoseconds)
00143 {
00144     /* Do nothing with @b sleeptime_nanoseconds */
00145 
00146     jlThread_sleep(clsidxthis, sleeptime_milliseconds);
00147 
00148 } /* END of jlThread_sleep_nanos() */
00149 
00150 /*@} */ /* End of grouped definitions */
00151 
00152 
00153 /*!
00154  * @name Native implementation of java.lang.Thread.join() functions.
00155  *
00156  * @brief Join one thread onto another, timed and untimed.
00157  *
00158  * Results are undefined if thread has the @b JOIN4EVER, @b JOINTIMED,
00159  * @b WAIT4EVER, @b WAITTIMED, or @b INTERRUPTIBLEIO status or if thread
00160  * has been @b NOTIFIED or @b INTERRUPTED.
00161  *
00162  * This will only succeed if thread is in @b RUNNING state.
00163  *
00164  * The <b><code>join(ms, ns)</code></b> version ignores the
00165  * nanoseconds parameter and works just like @c @b join(ms).
00166  *
00167  * The object hash of @c @b this object is always passed
00168  * as the first parameter.
00169  *
00170  *
00171  * @param  objhashthis             Object table hash of
00172  *                                 @c @b this object.
00173  *
00174  * @param  sleeptime               Number of timer ticks (milliseconds)
00175  *                                 to sleep.
00176  *
00177  * @param  sleeptime_nanoseconds   Number of nanoseconds to wait on join
00178  *                                 in addition to the milliseconds.
00179  *
00180  * @returns @link #jvoid jvoid@endlink
00181  *
00182  * @throws JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00183  *         @link #JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00184            if another thread had interrupted this thread@endlink.
00185  *
00186  *
00187  * @todo Make sure thread interruption logic below here is working.
00188  *
00189  */
00190 
00191 /*@{ */ /* Begin grouped definitions */
00192 
00193 /*!
00194  * @brief Native implementation of @c @b java.lang.Thread.join()
00195  *
00196  */
00197 
00198 jvoid jlThread_join4ever(jvm_object_hash objhashthis)
00199 {
00200     /* Current thread always assumed valid */
00201     jvm_thread_index thridxthis = CURRENT_THREAD;
00202 
00203     jvm_thread_index thridxjoin =
00204                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00205 
00206     THREAD(thridxthis).status |= THREAD_STATUS_JOIN4EVER;
00207     THREAD(thridxthis).jointarget = thridxjoin;
00208     (rvoid) threadstate_request_runnable(thridxthis);
00209 
00210     return;
00211 
00212 } /* END of jlThread_join4ever() */
00213 
00214 
00215 /*!
00216  * @brief Native implementation
00217  * of @c @b java.lang.Thread.join(jlong)
00218  *
00219  */
00220 jvoid jlThread_jointimed(jvm_object_hash objhashthis,
00221                          jlong           sleeptime)
00222 {
00223     /* Current thread always assumed valid */
00224     jvm_thread_index thridxthis = CURRENT_THREAD;
00225 
00226     jvm_thread_index thridxjoin =
00227                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00228 
00229     THREAD(thridxthis).status |= THREAD_STATUS_JOINTIMED;
00230     THREAD(thridxthis).jointarget = thridxjoin;
00231     THREAD(thridxthis).sleeptime = sleeptime;
00232     (rvoid) threadstate_request_runnable(thridxthis);
00233 
00234     return;
00235 
00236 } /* END of jlThread_jointimed() */
00237 
00238 
00239 /*!
00240  * @brief Native implementation
00241  * of <b><code>java.lang.Thread.join(jlong, jint)</code></b>
00242  *
00243  * Ignore the @b sleeptime_nanoseconds parameter in this implementation.
00244  *
00245  */
00246 jvoid jlThread_jointimed_nanos(jvm_object_hash objhashthis,
00247                                jlong           sleeptime,
00248                                jint            sleeptime_nanoseconds)
00249 {
00250     /* Do nothing with @b sleeptime_nanoseconds */
00251 
00252     jlThread_jointimed(objhashthis, sleeptime);
00253 
00254     return;
00255 
00256 } /* END of jlThread_jointimed_nanos() */
00257 
00258 /*@} */ /* End of grouped definitions */
00259 
00260 
00261 /*!
00262  * @name Native implementation of class static functions.
00263  *
00264  * The class index of the current class is always passed
00265  * as the first parameter.
00266  *
00267  * @note These @c @b java.lang.Thread methods are unusual in that
00268  * they does not require a @c @b jobject (in parlance of this
00269  * implementation, a @link #jvm_object_hash jvm_object_hash@endlink)
00270  * to run because they are declared as @c @b static methods.  As
00271  * implemented here, the usual @b objhashthis parameter is therefore
00272  * replaced by * @b clsidxthis.  The thread context is located in
00273  * @link #CURRENT_THREAD CURRENT_THREAD@endlink.
00274  *
00275  */
00276 
00277 /*@{ */ /* Begin grouped definitions */
00278 
00279 /*!
00280  * @brief Native implementation
00281  * of @c @b java.lang.Thread.currentThread()
00282  *
00283  *
00284  * @param  clsidxthis  Class table index of the class of
00285  *                     @c @b this object, namely,
00286  *                     @c @b java.lang.Thread .
00287  *
00288  *
00289  * @returns @c @b java.lang.Thread
00290  *          of @link rjvm#current_thread pjvm->current_thread@endlink,
00291  *          also known as @link #CURRENT_THREAD CURRENT_THREAD@endlink
00292  *
00293  */
00294 
00295 jvm_object_hash jlThread_currentThread(jvm_class_index clsidxthis)
00296 {
00297     /* Current thread always assumed valid */
00298     return(THREAD(CURRENT_THREAD).thread_objhash);
00299 
00300 } /* END of jlThread_currentThread() */
00301 
00302 
00303 /*!
00304  * @brief Native implementation of @c @b java.lang.Thread.yield()
00305  *
00306  *
00307  * @param  clsidxthis  Class table index of the class of
00308  *                     @c @b this object, namely,
00309  *                     @c @b java.lang.Thread .
00310  *
00311  *
00312  * @returns @link #jtrue jtrue@endlink if thread could be modified,
00313  *          else @link #jfalse jfalse@endlink.
00314  *
00315  */
00316 jboolean jlThread_yield(jvm_class_index clsidxthis)
00317 {
00318     /* Current thread always assumed valid */
00319     jvm_thread_index thridx = CURRENT_THREAD;
00320 
00321     jboolean rc = threadstate_request_runnable(thridx);
00322 
00323     if (jfalse == rc)
00324     {
00325         threadstate_request_badlogic(thridx);
00326     }
00327 
00328     return(rc);
00329 
00330 } /* END of jlThread_yield() */
00331 
00332 
00333 /*!
00334  * @brief Native implementation
00335  * of @c @b java.lang.Thread.interrupted()
00336  *
00337  * Status is @b CLEARED by this method after testing it.
00338  *
00339  * @note <b>This is a static method and has no need of a
00340  * @c @b this object hash.  Therefore, the first
00341  * parameter is @e not an object hash, but the first
00342  * application parameter itself.</b>
00343  *
00344  *
00345  * @param  clsidxthis  Class table index of the class of
00346  *                     @c @b this object, namely,
00347  *                     @c @b java.lang.Thread .
00348  *
00349  *
00350  * @returns @link #jtrue jtrue@endlink if thread has been interrupted,
00351  * else @link #jfalse jfalse@endlink.
00352  *
00353  */
00354 
00355 jboolean jlThread_interrupted(jvm_class_index clsidxthis)
00356 {
00357     /* Current thread always assumed valid */
00358     jvm_thread_index thridx = CURRENT_THREAD;
00359 
00360     /* Retrieve status */
00361     jboolean rc = (THREAD_STATUS_INTERRUPTED &
00362                    THREAD(thridx).status) ? jtrue : jfalse;
00363 
00364     /* Clear status */
00365     THREAD(thridx).status &= ~THREAD_STATUS_INTERRUPTED;
00366 
00367     /* Report result */
00368     return(rc);
00369 
00370 } /* END of jlThread_interrupted() */
00371 
00372 
00373 /*!
00374  * @brief Native implementation
00375  * of @c @b java.lang.Thread.holdsLock()
00376  *
00377  *
00378  * @param  clsidxthis  Class table index of the class of
00379  *                     @c @b this object, namely,
00380  *                     @c @b java.lang.Thread .
00381  *
00382  * @param  objhashLOCK Object hash of object to query.
00383  *
00384  *
00385  * @returns @link #jtrue jtrue@endlink if this thread holds the
00386  * object's monitor lock, else @link #jfalse jfalse@endlink.
00387  *
00388  * @throws JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION
00389  *         @link #JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION
00390            if the object hash is a null object@endlink.
00391  *
00392  */
00393 
00394 jboolean jlThread_holdsLock(jvm_class_index clsidxthis,
00395                             jvm_object_hash objhashLOCK)
00396 {
00397     if (jvm_object_hash_null == objhashLOCK)
00398     {
00399         /*
00400          * The @objhashLOCK is a
00401          * @link #jvm_object_hash_null jvm_object_hash_null@endlink
00402          * object
00403          */
00404 
00405         /* Current thread always assumed valid */
00406         thread_throw_exception(CURRENT_THREAD,
00407                                THREAD_STATUS_THREW_EXCEPTION,
00408                                JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION);
00409 /*NOTREACHED*/
00410     }
00411 
00412     /* Current thread always assumed valid */
00413     if (rtrue == threadutil_holds_lock(CURRENT_THREAD, objhashLOCK))
00414     { 
00415         return(jtrue);
00416     }
00417 
00418     return(jfalse);
00419 
00420 } /* END of jlThread_holdsLock() */
00421 
00422 
00423 /*@} */ /* End of grouped definitions */
00424 
00425 /*!
00426  * @name Native implementation of object instance functions.
00427  *
00428  * The object hash of @c @b this object is always passed
00429  * as the first parameter.
00430  *
00431  */
00432 
00433 
00434 /*@{ */ /* Begin grouped definitions */
00435 
00436 /*!
00437  * @brief Native implementation
00438  * of @c @b java.lang.Thread.interrupt()
00439  *
00440  * The
00441  * @link #THREAD_STATUS_INTERRUPTED THREAD_STATUS_INTERRUPTED@endlink
00442  * bit is unconditionally set here.  The logic for clearing the bit
00443  * and throwing exceptions is performed when this bit is read by other
00444  * functions.
00445  *
00446  *
00447  * @param  objhashthis  Object table hash of @c @b this object.
00448  *
00449  *
00450  * @returns @link #jtrue jtrue@endlink if thread could be modified, else
00451  * throw @b SecurityException.
00452  *
00453  *
00454  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00455  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00456            if thread cannot be interrupted@endlink.
00457  *
00458  */
00459 
00460 jboolean jlThread_interrupt(jvm_object_hash objhashthis)
00461 {
00462     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00463         (rtrue == VERIFY_THREAD_LINKAGE(
00464                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00465     {
00466         jvm_thread_index thridx =
00467                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00468 
00469         THREAD(thridx).status |= THREAD_STATUS_INTERRUPTED;
00470         return(jtrue);
00471     }
00472 
00473     /* Could not interrupt this thread */
00474     /* Current thread always assumed valid */
00475     thread_throw_exception(CURRENT_THREAD,
00476                            THREAD_STATUS_THREW_EXCEPTION,
00477                            JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
00478 /*NOTREACHED*/
00479     return(jfalse); /* Satisfy compiler */
00480 
00481 } /* END of jlThread_interrupt() */
00482 
00483 
00484 /*!
00485  * @brief Native implementation
00486  * of @c @b java.lang.Thread.isInterrupted()
00487  *
00488  * Status is UNCHANGED by this method after testing it.
00489  *
00490  *
00491  * @param  objhashthis  Object table hash of @c @b this object.
00492  *
00493  *
00494  * @returns @link #jtrue jtrue@endlink if thread has been interrupted,
00495  * else @link #jfalse jfalse@endlink.
00496  *
00497  */
00498 
00499 jboolean jlThread_isInterrupted(jvm_object_hash objhashthis)
00500 {
00501     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00502         (rtrue == VERIFY_THREAD_LINKAGE(
00503                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00504     {
00505         jvm_thread_index thridx =
00506                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00507 
00508 
00509         /* Retrieve status */
00510         jboolean rc = (THREAD_STATUS_INTERRUPTED &
00511                    THREAD(thridx).status) ? jtrue : jfalse;
00512 
00513         /* Report result */
00514         return(rc);
00515     }
00516 
00517     return(jfalse);
00518 
00519 } /* END of jlThread_isInterrupted() */
00520 
00521 
00522 /*!
00523  * @brief Native implementation
00524  * of @c @b java.lang.Thread.isAlive()
00525  *
00526  *
00527  * @param  objhashthis  Object table hash of @c @b this object.
00528  *
00529  *
00530  * @returns @link #jtrue jtrue@endlink if thread is in use and
00531  * not @b NEW and neither @b COMPLETE (transient) nor @b DEAD,
00532  * else @link #jfalse jfalse@endlink.
00533  *
00534  * @todo  CAVEAT:  Should this thread eventually get reallocated as
00535  *        @link #rjvm.thread_new_last pjvm->thread_new_last@endlink
00536  *        wraps around after @link #JVMCFG_MAX_THREADS
00537           JVMCFG_MAX_THREADS@endlink more new threads, this function
00538  *        will return a stale result at the real machine level.  This
00539  *        is unlikely, however, because the allocation of
00540  *        @c @b java.lang.Thread objects will likely cover
00541  *        this concern at a higher level in the design.
00542  */
00543 
00544 jboolean jlThread_isAlive(jvm_object_hash objhashthis)
00545 {
00546     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00547         (rtrue == VERIFY_THREAD_LINKAGE(
00548                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00549     {
00550         jvm_thread_index thridx =
00551                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00552 
00553         switch (THREAD(thridx).this_state)
00554         {
00555             case THREAD_STATE_NEW:
00556             case THREAD_STATE_COMPLETE:
00557             case THREAD_STATE_DEAD:
00558                 return(jfalse);
00559             default:
00560                 return(jtrue);
00561         }
00562 
00563     }
00564 
00565     return(jfalse);
00566 
00567 } /* END of jlThread_isAlive() */
00568 
00569 
00570 /*!
00571  * @brief Native implementation of @c @b java.lang.Thread.start()
00572  *
00573  * This will only succeed if thread is in @b NEW state.
00574  *
00575  *
00576  * @param  objhashthis  Object table hash of @c @b this object.
00577  *
00578  *
00579  * @returns @link #jtrue jtrue@endlink if thread could be started,
00580  * else @link #jfalse jfalse@endlink.
00581  *
00582  * @throws JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00583  *         @link #JVMCLASS_JAVA_LANG_INTERRUPTEDEXCEPTION
00584            if another thread had interrupted this thread@endlink.
00585  *
00586  */
00587 
00588 jboolean jlThread_start(jvm_object_hash objhashthis)
00589 {
00590     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00591         (rtrue == VERIFY_THREAD_LINKAGE(
00592                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00593     {
00594         jvm_thread_index thridx = 
00595                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00596 
00597         return(threadstate_request_start(thridx));
00598     }
00599 
00600     return(jfalse);
00601 
00602 } /* END of jlThread_start() */
00603 
00604 
00605 /*!
00606  * @brief Native implementation
00607  * of @c @b java.lang.Thread.countStackFrames() .
00608  *
00609  *
00610  * @deprecated <b>CAVEAT EMPTOR:</b>  This method has been deprecated
00611  *                                    in the JDK library API
00612  *                                    documentation.
00613  *
00614  *
00615  * @param  objhashthis  Object table hash of @c @b this object.
00616  *
00617  *
00618  * @returns number of frames
00619  *
00620  *
00621  * @throws JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION
00622  *         @link #JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION
00623            if another thread had interrupted this thread@endlink.
00624  *
00625  */
00626 
00627 jint jlThread_countStackFrames(jvm_object_hash objhashthis)
00628 {
00629     jint rc = 0;
00630 
00631     if ((rfalse == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) ||
00632         (rfalse == VERIFY_THREAD_LINKAGE(
00633                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00634     {
00635         return(rc);
00636     }
00637 
00638     jvm_thread_index thridx = 
00639                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00640 
00641     if (!(THREAD_STATUS_INTERRUPTED & THREAD(thridx).status))
00642     {
00643         /* This thread is not suspended at this time */
00644         thread_throw_exception(thridx,
00645                                THREAD_STATUS_THREW_EXCEPTION,
00646                         JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION);
00647 /*NOTREACHED*/
00648     }
00649 
00650     jvm_sp fptest = FIRST_STACK_FRAME(thridx);
00651 
00652     /* Examine stack frame until end of stack,where last FP points*/
00653     while (!(CHECK_FINAL_STACK_FRAME_GENERIC(thridx, fptest)))
00654     {
00655         fptest = NEXT_STACK_FRAME_GENERIC(thridx, fptest);
00656 
00657         rc++;
00658     }
00659 
00660     return(rc);
00661 
00662 } /* END of jlThread_countStackFrames() */
00663 
00664 
00665 /*!
00666  * @brief Native implementation
00667  * of @c @b java.lang.Thread.setPriority()
00668  *
00669  *
00670  * @param  objhashthis  Object table hash of @c @b this object.
00671  *
00672  * @param  priority new priority value
00673  *
00674  *
00675  * @returns If this thread is in use, result is
00676  *          @link #jtrue jtrue@endlink,
00677  *          else @link #jfalse jfalse@endlink.
00678  *
00679  * @throws JVMCLASS_JAVA_LANG_ILLEGALARGUMENTEXCEPTION
00680  *         @link #JVMCLASS_JAVA_LANG_ILLEGALARGUMENTEXCEPTION
00681            if the requested thread priorty is out of range@endlink.
00682  *
00683  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00684  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00685            if this thread cannot have its priority modified@endlink.
00686  *
00687  * @todo Add logic to detect @b SecurityException.
00688  *
00689  */
00690 
00691 jboolean jlThread_setPriority(jvm_object_hash objhashthis,
00692                               jint             priority)
00693 {
00694     if ((THREAD_PRIORITY_MIN > priority) ||
00695         (THREAD_PRIORITY_MAX < priority))
00696     {
00697         /* The priority is out of range */
00698 
00699         /* Current thread always assumed valid */
00700         thread_throw_exception(CURRENT_THREAD,
00701                                THREAD_STATUS_THREW_EXCEPTION,
00702                            JVMCLASS_JAVA_LANG_ILLEGALARGUMENTEXCEPTION);
00703 /*NOTREACHED*/
00704     }
00705 
00706     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00707         (rtrue == VERIFY_THREAD_LINKAGE(
00708                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00709     {
00710         jvm_thread_index thridx =
00711                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00712 
00713         THREAD(thridx).priority = priority;
00714         return(jtrue);
00715     }
00716 
00717     /* Need to detect @b SecurityException */
00718 #if 1
00719     return(jfalse);
00720 #else
00721     /* This thread cannot have its priority modified */
00722     /* Current thread always assumed valid */
00723     thread_throw_exception(CURRENT_THREAD,
00724                            THREAD_STATUS_THREW_EXCEPTION,
00725                            JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
00726 /*NOTREACHED*/
00727     return(jfalse); /* Satisfy compiler */
00728 #endif
00729 
00730 } /* END of jlThread_setPriority() */
00731 
00732 
00733 /*!
00734  * @brief Native implementation
00735  * of @c @b java.lang.Thread.getPriority()
00736  *
00737  *
00738  *
00739  * @param  objhashthis  Object table hash of @c @b this object.
00740  *
00741  *
00742  * @returns Execution priority of this thread.  If not in use, result is
00743  *          @link #THREAD_PRIORITY_BAD THREAD_PRIORITY_BAD@endlink.
00744  *
00745  */
00746 
00747 jint jlThread_getPriority(jvm_object_hash objhashthis)
00748 {
00749     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00750         (rtrue == VERIFY_THREAD_LINKAGE(
00751                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00752     {
00753         jvm_thread_index thridx =
00754                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00755 
00756         return(THREAD(thridx).priority);
00757     }
00758 
00759     /* Invalid value for invalid thread */
00760     return(THREAD_PRIORITY_BAD);
00761 
00762 } /* END of jlThread_getPriority() */
00763 
00764 
00765 /*!
00766  * @brief Native implementation
00767  * of @c @b java.lang.Thread.destroy()
00768  *
00769  * Simply kill the thread without @e any cleanup.
00770  * <b>THIS IS A VERY BAD THING!</b>  (Perhaps this
00771  * is why most JDK's do not implement this method
00772  * any more!)
00773  *
00774  * There is typically no implementation done of
00775  * @c @b java.lang.Thread.destroy(Runnable) ,
00776  * but will initially be done here.
00777  *
00778  * @todo  Should this be implemented? Some JDK's probably don't
00779  *        implement it any more.
00780  *
00781  *
00782  * @param  objhashthis  Object table hash of @c @b this object.
00783  *
00784  *
00785  * @returns @link #jtrue jtrue@endlink if thread was moved to
00786  *          @b COMPLETE state, else @link #jfalse jfalse@endlink.
00787  *
00788  */
00789 
00790 jboolean jlThread_destroy(jvm_object_hash objhashthis)
00791 {
00792     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00793         (rtrue == VERIFY_THREAD_LINKAGE(
00794                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00795     {
00796         jvm_thread_index thridx =
00797                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00798 
00799         /* GAG!  This will @e really break the state machine! */
00800         /* THREAD(thridxcurr).status &= ~THREAD_STATUS_INUSE; */
00801 
00802         /* So try to kill it quietly: */
00803         threadstate_request_badlogic(thridx);
00804         threadstate_activate_badlogic(thridx);
00805         threadstate_activate_badlogic(thridx);
00806         return(threadstate_request_complete(thridx));
00807     }
00808 
00809     return(jfalse);
00810 
00811 } /* END of jlThread_destroy() */
00812 
00813 
00814 /*!
00815  * @brief Native implementation
00816  * of @c @b java.lang.Thread.checkAccess()
00817  *
00818  * This method will @e always give permission in this JVM.
00819  *
00820  * @todo  A smart java.lang.SecurityManager will take
00821  *        care of this matter.
00822  *
00823  *
00824  * @param  objhashthis  Object table hash of @c @b this object.
00825  *
00826  *
00827  * @returns @link #jtrue jtrue@endlink unconditionally.
00828  *
00829  *
00830  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00831  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00832        if current thread is not permitted to modify this thread@endlink.
00833  *
00834  * @todo Add logic to detect @b SecurityException beyond passing in
00835  * an invalid @b objhashthis.
00836  *
00837  */
00838 jboolean jlThread_checkAccess(jvm_object_hash objhashthis)
00839 {
00840     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00841         (rtrue == VERIFY_THREAD_LINKAGE(
00842                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00843     {
00844 /* unused
00845         jvm_thread_index thridx =
00846                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00847 */
00848         return(jtrue);
00849     }
00850 
00851     /* Could not modify this thread */
00852     thread_throw_exception(CURRENT_THREAD,
00853                            THREAD_STATUS_THREW_EXCEPTION,
00854                            JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
00855 /*NOTREACHED*/
00856     return(jfalse); /* Satisfy compiler */
00857 
00858 } /* END of jlThread_checkAccess() */
00859 
00860 
00861 /*!
00862  * @brief Native implementation
00863  * of <code>java.lang.Thread.setDaemon()<code>
00864  *
00865  * @todo  See notes elsewhere about implementation of the ISDAEMON bit.
00866  *        This concept must be implemented in the JVM structures so as
00867  *        to know when to quit (no non-daemon threads running, that is,
00868  *        no user threads running).  Currently, it is a status bit in
00869  *        the @link rthread#status rthread.status@endlink structure
00870  *        named
00871  *        @link #THREAD_STATUS_ISDAEMON THREAD_STATUS_ISDAEMON@endlink
00872  *        but is typically @e also found as a private class member
00873  *        of @c @b java.lang.Thread .  If this were @e always
00874  *        true, then the former could be eliminated.  Since this code
00875  *        actually @e implements this class' native methods, either one
00876  *        could be eliminated @e if none of the other (non-native) class
00877  *        methods referenced the private variable without going through
00878  *        @link #jlThread_isDaemon jlThread_isDaemon@endlink.  However,
00879  *        this question is why this action item is present.
00880  *
00881  *
00882  * @param  objhashthis  Object table hash of @c @b this object.
00883  *
00884  * @param  isdaemon     @link #rtrue rtrue@endlink or
00885  *                      @link #rfalse rfalse@endlink,
00886  *                      depending on requested condition
00887  *
00888  *
00889  * @returns @link #jtrue jtrue@endlink if could make the change,
00890  * else throw @b SecurityException.
00891  *
00892  *
00893  * @throws JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION
00894  *         @link #JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION
00895            if thread is not in the @b NEW state when attempting
00896            to set this condition@endlink.
00897  *
00898  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00899  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
00900            if current thread cannot change this thread@endlink.
00901  *
00902  *
00903  * @todo Review jvm_init() code for setting up threads before there
00904  *       is a @c @b setjmp(3) handler for @c @b setDaemon() exceptions.
00905  *
00906  * @todo Add logic to detect @b SecurityException beyond passing in
00907  * an invalid @b objhashthis.
00908  *
00909  */
00910 
00911 jvoid jlThread_setDaemon(jvm_object_hash objhashthis,
00912                         jboolean        isdaemon)
00913 {
00914     if ((rfalse == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) ||
00915         (rfalse == VERIFY_THREAD_LINKAGE(
00916                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00917     {
00918         /* The requested thread is not valid */
00919         /* Current thread always assumed valid */
00920         thread_throw_exception(CURRENT_THREAD,
00921                                THREAD_STATUS_THREW_EXCEPTION,
00922                                JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
00923 /*NOTREACHED*/
00924     }
00925 
00926     jvm_thread_index thridx = 
00927                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00928 
00929     if (THREAD_STATE_NEW == THREAD(thridx).this_state)
00930     {
00931         if (jtrue == isdaemon)
00932         {
00933             THREAD(thridx).status |= THREAD_STATUS_ISDAEMON;
00934         }
00935         else
00936         {
00937             THREAD(thridx).status &= ~THREAD_STATUS_ISDAEMON;
00938         }
00939 
00940         return;
00941     }
00942 
00943     /* This thread is in some state besides @b NEW */
00944     thread_throw_exception(thridx,
00945                            THREAD_STATUS_THREW_EXCEPTION,
00946                         JVMCLASS_JAVA_LANG_ILLEGALTHREADSTATEEXCEPTION);
00947 /*NOTREACHED*/
00948     return; /* Satisfy compiler */
00949 
00950 } /* END of jlThread_setDaemon() */
00951 
00952 
00953 /*!
00954  * @brief Native implementation
00955  * of @c @b java.lang.Thread.isDaemon()
00956  *
00957  * @todo  See notes elsewhere about implementation of the ISDAEMON bit.
00958  *
00959  *
00960  * @param  objhashthis  Object table hash of @c @b this object.
00961  *
00962  *
00963  * @returns @link #jtrue jtrue@endlink or @link #jfalse jfalse@endlink,
00964  *          depending on value of @b ISDAEMON bit.
00965  *
00966  */
00967 
00968 jboolean jlThread_isDaemon(jvm_object_hash objhashthis)
00969 {
00970     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
00971         (rtrue == VERIFY_THREAD_LINKAGE(
00972                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
00973     {
00974         jvm_thread_index thridx =
00975                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
00976 
00977         return((THREAD_STATUS_ISDAEMON & THREAD(thridx).status)
00978                ? jtrue
00979                : jfalse);
00980     }
00981 
00982     return(jfalse);
00983 
00984 } /* END of jlThread_isDaemon() */
00985 
00986 
00987 #if 0
00988 /*!
00989  * @brief Native implementation
00990  * of @c @b java.lang.Thread.setName()
00991  *
00992  * @todo  Needs work to convert java.lang.String into
00993  *        (rthread).name (written @e long before @b String code).
00994  *
00995  *
00996  * @param  objhashthis  Object table hash of @c @b this object.
00997  *
00998  *         name    Null-terminated string containing new thread name
00999  *
01000  *
01001  * @returns @link #jvoid jvoid@endlink
01002  *
01003  */
01004 jvoid jlThread_setName(jvm_object_hash  objhashthis,
01005                        rchar           *newname)
01006 {
01007     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
01008         (rtrue == VERIFY_THREAD_LINKAGE(
01009                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
01010     {
01011         jvm_thread_index thridx =
01012                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
01013 
01014 
01015         SomeRenditionOf(THREAD(thridx).name) = SomeRenditionOf(newname);
01016     }
01017 
01018     return;
01019 
01020 } /* END of jlThread_setName() */
01021 
01022 
01023 /*!
01024  * @brief Native implementation
01025  * of @c @b java.lang.Thread.getName()
01026  *
01027  * @todo  Needs work to convert java.lang.String into
01028  *        (rthread).name (written @e long before @b String code).
01029  *
01030  *
01031  * @param  objhashthis  Object table hash of @c @b this object.
01032  *
01033  *
01034  * @returns Object hash to @c @b String containing thread name
01035  *
01036  */
01037 jvm_object_hash jlThread_getName(jvm_object_hash objhashthis)
01038 {
01039     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
01040         (rtrue == VERIFY_THREAD_LINKAGE(
01041                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
01042     {
01043         jvm_thread_index thridx =
01044                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
01045 
01046 
01047         return(SomeRenditionOf(THREAD(thridx).name));
01048     }
01049 
01050     ... now what?
01051 
01052 } /* END of jlThread_setName() */
01053 #endif
01054 
01055 
01056 /*!
01057  * @brief Native implementation
01058  * of @c @b java.lang.Thread.stop(jvoid)
01059  *
01060  * There is typically no native implementation of
01061  * @c @b java.lang.Thread.stop(Runnable) .
01062  *
01063  *
01064  * @deprecated <b>CAVEAT EMPTOR:</b>  This method has been deprecated
01065  *                                    in the JDK library API
01066  *                                    documentation.
01067  *
01068  *
01069  * @param  objhashthis  Object table hash of @c @b this object.
01070  *
01071  *
01072  * @returns @link #jtrue jtrue@endlink if thread could be modified,
01073  * else throw @b SecurityException
01074  *
01075  *
01076  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01077  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01078            if current thread cannot change this thread@endlink.
01079  *
01080  * @todo Add logic to detect @b SecurityException beyond passing in
01081  * an invalid @b objhashthis.
01082  *
01083  */
01084 
01085 jvoid jlThread_stop(jvm_object_hash objhashthis)
01086 {
01087     if ((rfalse == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) ||
01088         (rfalse == VERIFY_THREAD_LINKAGE(
01089                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
01090     {
01091         /* This thread cannot change the requested thread */
01092         /* Current thread always assumed valid */
01093         thread_throw_exception(CURRENT_THREAD,
01094                                THREAD_STATUS_THREW_EXCEPTION,
01095                                JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
01096 /*NOTREACHED*/
01097     }
01098 
01099     jvm_thread_index thridx =
01100                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
01101 
01102     jvm_object_hash objhash;
01103 
01104     /* Remove all monitor locks */
01105     for (objhash = JVMCFG_FIRST_OBJECT;
01106          objhash < JVMCFG_MAX_OBJECTS;
01107          objhash++)
01108     {
01109         /* Check object in use and locked, and do BIDIRECTIONAL test
01110          * of this thread knowing about this object lock / vice versa */
01111         if ((OBJECT_STATUS_INUSE & OBJECT(objhash).status)   &&
01112             (OBJECT_STATUS_MLOCK & OBJECT(objhash).status)   &&
01113             (thridx         == OBJECT(objhash).mlock_thridx) &&
01114             (objhash        == THREAD(thridx).locktarget))
01115         {
01116             OBJECT(objhash).status       &= ~OBJECT_STATUS_MLOCK;
01117             OBJECT(objhash).mlock_count   = 0;
01118             OBJECT(objhash).mlock_thridx  = jvm_thread_index_null;
01119         }
01120     }
01121 
01122     /* GAG!  This will @e really break the state machine! */
01123     /* THREAD(thridx).status &= ~THREAD_STATUS_INUSE; */
01124 
01125     /* So try to kill it quietly: */
01126     threadstate_request_badlogic(thridx);
01127     threadstate_activate_badlogic(thridx);
01128     (rvoid) threadstate_request_complete(thridx);
01129 
01130     return;
01131 
01132 } /* END of jlThread_stop() */
01133 
01134 
01135 /*!
01136  * @brief Native implementation
01137  * of @c @b java.lang.Thread.suspend()
01138  *
01139  * Results are undefined if thread has the @b SLEEP, @b WAIT4EVER,
01140  * @b WAITTIMED, or @b INTERRUPTIBLEIO status or if thread has
01141  * been @b NOTIFIED or @b INTERRUPTED.
01142  *
01143  * This will work if thread is in @e any state at all.
01144  *
01145  * @deprecated <b>CAVEAT EMPTOR:</b>  This method has been deprecated
01146  *                                    in the JDK library API
01147  *                                    documentation.
01148  *
01149  *
01150  * @param  objhashthis  Object table hash of @c @b this object.
01151  *
01152  *
01153  * @returns @link #jtrue jtrue@endlink if thread could be modified,
01154  * else throw @b SecurityException.
01155  *
01156  *
01157  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01158  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01159            if could not suspend thread@endlink.
01160  *
01161  * @todo Add logic to detect @b SecurityException beyond passing in
01162  * an invalid @b objhashthis.
01163  *
01164  */
01165 
01166 jvoid jlThread_suspend(jvm_object_hash objhashthis)
01167 {
01168     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
01169         (rtrue == VERIFY_THREAD_LINKAGE(
01170                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
01171     {
01172         jvm_thread_index thridx =
01173                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
01174 
01175         THREAD(thridx).status |= THREAD_STATUS_SUSPEND;
01176 
01177         /*
01178          * Move through BADLOGIC state and into BLOCKINGEVENT,
01179          * which will put it in line to be BLOCKED.
01180          */
01181         threadstate_request_badlogic(thridx);
01182         threadstate_activate_badlogic(thridx);
01183         (rvoid) threadstate_request_blockingevent(thridx);
01184 
01185         return;
01186     }
01187 
01188     /* Could not suspend this thread */
01189     thread_throw_exception(CURRENT_THREAD,
01190                            THREAD_STATUS_THREW_EXCEPTION,
01191                            JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
01192 /*NOTREACHED*/
01193     return; /* Satisfy compiler */
01194 
01195 } /* END of jlThread_suspend() */
01196 
01197 
01198 /*!
01199  * @brief Native implementation
01200  * of @c @b java.lang.Thread.resume()
01201  *
01202  * Results are undefined if thread has the @b SLEEP, @b WAIT4EVER,
01203  * @b WAITTIMED, or @b INTERRUPTIBLEIO status or if thread has
01204  * been @b NOTIFIED or @b INTERRUPTED.
01205  *
01206  * This will work if thread is in @e any state at all.
01207  *
01208  *
01209  * @deprecated <b>CAVEAT EMPTOR:</b>  This method has been deprecated
01210  *                                    in the JDK library API
01211  *                                    documentation.
01212  *
01213  *
01214  * @param  objhashthis  Object table hash of @c @b this object.
01215  *
01216  *
01217  * @returns @link #jtrue jtrue@endlink if thread could be modified,
01218  * else throw @b SecurityException.
01219  *
01220  *
01221  * @throws JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01222  *         @link #JVMCLASS_JAVA_LANG_SECURITYEXCEPTION
01223            if could not suspend thread@endlink.
01224  *
01225  * @todo Add logic to detect @b SecurityException beyond passing in
01226  * an invalid @b objhashthis.
01227  *
01228  */
01229 
01230 jvoid jlThread_resume(jvm_object_hash objhashthis)
01231 {
01232     if ((rtrue == VERIFY_OBJECT_THREAD_LINKAGE(objhashthis)) &&
01233         (rtrue == VERIFY_THREAD_LINKAGE(
01234                       OBJECT_THREAD_LINKAGE(objhashthis)->thridx)))
01235     {
01236         jvm_thread_index thridx =
01237                              OBJECT_THREAD_LINKAGE(objhashthis)->thridx;
01238 
01239         if (THREAD_STATUS_SUSPEND & THREAD(thridx).status)
01240         {
01241             /*
01242              * Move back out into @b UNBLOCKED state.  Don't care how
01243              * far into process the @c @b Thread.suspend() went,
01244              * since this implementation, using jlThread_suspend() only
01245              * puts in the first request (for @b BLOCKINGEVENT).
01246              * Wherever the state machine is in its paces, the thread
01247              * will be moved forward to requesting @b UNBLOCKED.
01248              */
01249             switch (THREAD(thridx).this_state)
01250             {
01251                 case THREAD_STATE_BADLOGIC:
01252                     (rvoid) threadstate_request_blockingevent(thridx);
01253                     (rvoid) threadstate_activate_blockingevent(thridx);
01254                     (rvoid) threadstate_process_blockingevent(thridx);
01255                     /* ... continue with next 'case' */
01256 
01257                 case THREAD_STATE_BLOCKINGEVENT:
01258                     (rvoid) threadstate_request_blocked(thridx);
01259                     (rvoid) threadstate_activate_blocked(thridx);
01260                     (rvoid) threadstate_process_blocked(thridx);
01261                     /* ... continue with next 'case' */
01262 
01263                 case THREAD_STATE_BLOCKED:
01264                     (rvoid) threadstate_request_unblocked(thridx);
01265 
01266                     return;
01267 
01268                 /* Anything else is invalid */
01269                 default:
01270                     break; /* Continue w/ thread_throw_exception()... */
01271             }
01272         }
01273     }
01274 
01275     /* Could not resume this thread */
01276     thread_throw_exception(CURRENT_THREAD,
01277                            THREAD_STATUS_THREW_EXCEPTION,
01278                            JVMCLASS_JAVA_LANG_SECURITYEXCEPTION);
01279 /*NOTREACHED*/
01280     return; /* Satisfy compiler */
01281 
01282 } /* END of jlThread_resume() */
01283 
01284 
01285 /*@} */ /* End of grouped definitions */
01286 
01287 /* EOF */
01288 

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