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