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: |