src/hotspot/share/runtime/thread.cpp
changeset 54385 9559ba212c18
parent 54366 2b48cedce327
child 54416 b788c494aa46
equal deleted inserted replaced
54384:cd3b7ad53265 54385:9559ba212c18
   236   set_active_handles(NULL);
   236   set_active_handles(NULL);
   237   set_free_handle_block(NULL);
   237   set_free_handle_block(NULL);
   238   set_last_handle_mark(NULL);
   238   set_last_handle_mark(NULL);
   239   DEBUG_ONLY(_missed_ic_stub_refill_verifier = NULL);
   239   DEBUG_ONLY(_missed_ic_stub_refill_verifier = NULL);
   240 
   240 
   241   // This initial value ==> never claimed.
   241   // Initial value of zero ==> never claimed.
   242   _oops_do_parity = 0;
   242   _threads_do_token = 0;
   243   _threads_hazard_ptr = NULL;
   243   _threads_hazard_ptr = NULL;
   244   _threads_list_ptr = NULL;
   244   _threads_list_ptr = NULL;
   245   _nested_threads_hazard_ptr_cnt = 0;
   245   _nested_threads_hazard_ptr_cnt = 0;
   246   _rcu_counter = 0;
   246   _rcu_counter = 0;
   247 
   247 
   883   return os::is_interrupted(thread, clear_interrupted);
   883   return os::is_interrupted(thread, clear_interrupted);
   884 }
   884 }
   885 
   885 
   886 
   886 
   887 // GC Support
   887 // GC Support
   888 bool Thread::claim_oops_do_par_case(int strong_roots_parity) {
   888 bool Thread::claim_par_threads_do(uintx claim_token) {
   889   int thread_parity = _oops_do_parity;
   889   uintx token = _threads_do_token;
   890   if (thread_parity != strong_roots_parity) {
   890   if (token != claim_token) {
   891     jint res = Atomic::cmpxchg(strong_roots_parity, &_oops_do_parity, thread_parity);
   891     uintx res = Atomic::cmpxchg(claim_token, &_threads_do_token, token);
   892     if (res == thread_parity) {
   892     if (res == token) {
   893       return true;
   893       return true;
   894     } else {
   894     }
   895       guarantee(res == strong_roots_parity, "Or else what?");
   895     guarantee(res == claim_token, "invariant");
   896       return false;
       
   897     }
       
   898   }
   896   }
   899   return false;
   897   return false;
   900 }
   898 }
   901 
   899 
   902 void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
   900 void Thread::oops_do(OopClosure* f, CodeBlobClosure* cf) {
  3470 
  3468 
  3471 JavaThread* Threads::_thread_list = NULL;
  3469 JavaThread* Threads::_thread_list = NULL;
  3472 int         Threads::_number_of_threads = 0;
  3470 int         Threads::_number_of_threads = 0;
  3473 int         Threads::_number_of_non_daemon_threads = 0;
  3471 int         Threads::_number_of_non_daemon_threads = 0;
  3474 int         Threads::_return_code = 0;
  3472 int         Threads::_return_code = 0;
  3475 int         Threads::_thread_claim_parity = 0;
  3473 uintx       Threads::_thread_claim_token = 1; // Never zero.
  3476 size_t      JavaThread::_stack_size_at_create = 0;
  3474 size_t      JavaThread::_stack_size_at_create = 0;
  3477 
  3475 
  3478 #ifdef ASSERT
  3476 #ifdef ASSERT
  3479 bool        Threads::_vm_complete = false;
  3477 bool        Threads::_vm_complete = false;
  3480 #endif
  3478 #endif
  3530   java_threads_do(tc);
  3528   java_threads_do(tc);
  3531   non_java_threads_do(tc);
  3529   non_java_threads_do(tc);
  3532 }
  3530 }
  3533 
  3531 
  3534 void Threads::possibly_parallel_threads_do(bool is_par, ThreadClosure* tc) {
  3532 void Threads::possibly_parallel_threads_do(bool is_par, ThreadClosure* tc) {
  3535   int cp = Threads::thread_claim_parity();
  3533   uintx claim_token = Threads::thread_claim_token();
  3536   ALL_JAVA_THREADS(p) {
  3534   ALL_JAVA_THREADS(p) {
  3537     if (p->claim_oops_do(is_par, cp)) {
  3535     if (p->claim_threads_do(is_par, claim_token)) {
  3538       tc->do_thread(p);
  3536       tc->do_thread(p);
  3539     }
  3537     }
  3540   }
  3538   }
  3541   VMThread* vmt = VMThread::vm_thread();
  3539   VMThread* vmt = VMThread::vm_thread();
  3542   if (vmt->claim_oops_do(is_par, cp)) {
  3540   if (vmt->claim_threads_do(is_par, claim_token)) {
  3543     tc->do_thread(vmt);
  3541     tc->do_thread(vmt);
  3544   }
  3542   }
  3545 }
  3543 }
  3546 
  3544 
  3547 // The system initialization in the library has three phases.
  3545 // The system initialization in the library has three phases.
  4523     p->oops_do(f, cf);
  4521     p->oops_do(f, cf);
  4524   }
  4522   }
  4525   VMThread::vm_thread()->oops_do(f, cf);
  4523   VMThread::vm_thread()->oops_do(f, cf);
  4526 }
  4524 }
  4527 
  4525 
  4528 void Threads::change_thread_claim_parity() {
  4526 void Threads::change_thread_claim_token() {
  4529   // Set the new claim parity.
  4527   if (++_thread_claim_token == 0) {
  4530   assert(_thread_claim_parity >= 0 && _thread_claim_parity <= 2,
  4528     // On overflow of the token counter, there is a risk of future
  4531          "Not in range.");
  4529     // collisions between a new global token value and a stale token
  4532   _thread_claim_parity++;
  4530     // for a thread, because not all iterations visit all threads.
  4533   if (_thread_claim_parity == 3) _thread_claim_parity = 1;
  4531     // (Though it's pretty much a theoretical concern for non-trivial
  4534   assert(_thread_claim_parity >= 1 && _thread_claim_parity <= 2,
  4532     // token counter sizes.)  To deal with the possibility, reset all
  4535          "Not in range.");
  4533     // the thread tokens to zero on global token overflow.
       
  4534     struct ResetClaims : public ThreadClosure {
       
  4535       virtual void do_thread(Thread* t) {
       
  4536         t->claim_threads_do(false, 0);
       
  4537       }
       
  4538     } reset_claims;
       
  4539     Threads::threads_do(&reset_claims);
       
  4540     // On overflow, update the global token to non-zero, to
       
  4541     // avoid the special "never claimed" initial thread value.
       
  4542     _thread_claim_token = 1;
       
  4543   }
  4536 }
  4544 }
  4537 
  4545 
  4538 #ifdef ASSERT
  4546 #ifdef ASSERT
       
  4547 void assert_thread_claimed(const char* kind, Thread* t, uintx expected) {
       
  4548   const uintx token = t->threads_do_token();
       
  4549   assert(token == expected,
       
  4550          "%s " PTR_FORMAT " has incorrect value " UINTX_FORMAT " != "
       
  4551          UINTX_FORMAT, kind, p2i(t), token, expected);
       
  4552 }
       
  4553 
  4539 void Threads::assert_all_threads_claimed() {
  4554 void Threads::assert_all_threads_claimed() {
  4540   ALL_JAVA_THREADS(p) {
  4555   ALL_JAVA_THREADS(p) {
  4541     const int thread_parity = p->oops_do_parity();
  4556     assert_thread_claimed("Thread", p, _thread_claim_token);
  4542     assert((thread_parity == _thread_claim_parity),
  4557   }
  4543            "Thread " PTR_FORMAT " has incorrect parity %d != %d", p2i(p), thread_parity, _thread_claim_parity);
  4558   assert_thread_claimed("VMThread", VMThread::vm_thread(), _thread_claim_token);
  4544   }
       
  4545   VMThread* vmt = VMThread::vm_thread();
       
  4546   const int thread_parity = vmt->oops_do_parity();
       
  4547   assert((thread_parity == _thread_claim_parity),
       
  4548          "VMThread " PTR_FORMAT " has incorrect parity %d != %d", p2i(vmt), thread_parity, _thread_claim_parity);
       
  4549 }
  4559 }
  4550 #endif // ASSERT
  4560 #endif // ASSERT
  4551 
  4561 
  4552 class ParallelOopsDoThreadClosure : public ThreadClosure {
  4562 class ParallelOopsDoThreadClosure : public ThreadClosure {
  4553 private:
  4563 private: