360 if (p == _thread) { |
338 if (p == _thread) { |
361 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); |
339 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); |
362 break; |
340 break; |
363 } |
341 } |
364 } |
342 } |
365 |
|
366 // Any NestedThreadsLists are also protecting JavaThreads so |
|
367 // check those also; the ThreadsLists may be different. |
|
368 for (NestedThreadsList* node = thread->get_nested_threads_hazard_ptr(); |
|
369 node != NULL; node = node->next()) { |
|
370 JavaThreadIterator jti(node->t_list()); |
|
371 for (JavaThread *p = jti.first(); p != NULL; p = jti.next()) { |
|
372 if (p == _thread) { |
|
373 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread1=" INTPTR_FORMAT " has a nested hazard pointer for thread2=" INTPTR_FORMAT, os::current_thread_id(), p2i(thread), p2i(_thread)); |
|
374 return; |
|
375 } |
|
376 } |
|
377 } |
|
378 } |
343 } |
379 }; |
344 }; |
380 |
345 |
|
346 // Closure to determine if the specified JavaThread is found by |
|
347 // threads_do(). |
|
348 // |
|
349 class VerifyHazardPtrThreadClosure : public ThreadClosure { |
|
350 private: |
|
351 bool _found; |
|
352 Thread *_self; |
|
353 |
|
354 public: |
|
355 VerifyHazardPtrThreadClosure(Thread *self) : _found(false), _self(self) {} |
|
356 |
|
357 bool found() const { return _found; } |
|
358 |
|
359 virtual void do_thread(Thread *thread) { |
|
360 if (thread == _self) { |
|
361 _found = true; |
|
362 } |
|
363 } |
|
364 }; |
|
365 |
|
366 |
|
367 // Acquire a stable ThreadsList. |
|
368 // |
|
369 void SafeThreadsListPtr::acquire_stable_list() { |
|
370 assert(_thread != NULL, "sanity check"); |
|
371 _needs_release = true; |
|
372 _previous = _thread->_threads_list_ptr; |
|
373 _thread->_threads_list_ptr = this; |
|
374 |
|
375 if (_thread->get_threads_hazard_ptr() == NULL) { |
|
376 // The typical case is first. |
|
377 acquire_stable_list_fast_path(); |
|
378 return; |
|
379 } |
|
380 |
|
381 // The nested case is rare. |
|
382 acquire_stable_list_nested_path(); |
|
383 } |
|
384 |
|
385 // Fast path way to acquire a stable ThreadsList. |
|
386 // |
|
387 void SafeThreadsListPtr::acquire_stable_list_fast_path() { |
|
388 assert(_thread != NULL, "sanity check"); |
|
389 assert(_thread->get_threads_hazard_ptr() == NULL, "sanity check"); |
|
390 |
|
391 ThreadsList* threads; |
|
392 |
|
393 // Stable recording of a hazard ptr for SMR. This code does not use |
|
394 // locks so its use of the _smr_java_thread_list & _threads_hazard_ptr |
|
395 // fields is racy relative to code that uses those fields with locks. |
|
396 // OrderAccess and Atomic functions are used to deal with those races. |
|
397 // |
|
398 while (true) { |
|
399 threads = ThreadsSMRSupport::get_java_thread_list(); |
|
400 |
|
401 // Publish a tagged hazard ptr to denote that the hazard ptr is not |
|
402 // yet verified as being stable. Due to the fence after the hazard |
|
403 // ptr write, it will be sequentially consistent w.r.t. the |
|
404 // sequentially consistent writes of the ThreadsList, even on |
|
405 // non-multiple copy atomic machines where stores can be observed |
|
406 // in different order from different observer threads. |
|
407 ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); |
|
408 _thread->set_threads_hazard_ptr(unverified_threads); |
|
409 |
|
410 // If _smr_java_thread_list has changed, we have lost a race with |
|
411 // Threads::add() or Threads::remove() and have to try again. |
|
412 if (ThreadsSMRSupport::get_java_thread_list() != threads) { |
|
413 continue; |
|
414 } |
|
415 |
|
416 // We try to remove the tag which will verify the hazard ptr as |
|
417 // being stable. This exchange can race with a scanning thread |
|
418 // which might invalidate the tagged hazard ptr to keep it from |
|
419 // being followed to access JavaThread ptrs. If we lose the race, |
|
420 // we simply retry. If we win the race, then the stable hazard |
|
421 // ptr is officially published. |
|
422 if (_thread->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) { |
|
423 break; |
|
424 } |
|
425 } |
|
426 |
|
427 // A stable hazard ptr has been published letting other threads know |
|
428 // that the ThreadsList and the JavaThreads reachable from this list |
|
429 // are protected and hence they should not be deleted until everyone |
|
430 // agrees it is safe to do so. |
|
431 |
|
432 _list = threads; |
|
433 |
|
434 verify_hazard_ptr_scanned(); |
|
435 } |
|
436 |
|
437 // Acquire a nested stable ThreadsList; this is rare so it uses |
|
438 // reference counting. |
|
439 // |
|
440 void SafeThreadsListPtr::acquire_stable_list_nested_path() { |
|
441 assert(_thread != NULL, "sanity check"); |
|
442 assert(_thread->get_threads_hazard_ptr() != NULL, |
|
443 "cannot have a NULL regular hazard ptr when acquiring a nested hazard ptr"); |
|
444 |
|
445 // The thread already has a hazard ptr (ThreadsList ref) so we need |
|
446 // to create a nested ThreadsListHandle with the current ThreadsList |
|
447 // since it might be different than our current hazard ptr. To remedy |
|
448 // the situation, the ThreadsList pointed to by the pre-existing |
|
449 // stable hazard ptr is reference counted before the hazard ptr may |
|
450 // be released and moved to a new ThreadsList. The old ThreadsList |
|
451 // is remembered in the ThreadsListHandle. |
|
452 |
|
453 ThreadsList* current_list = _previous->_list; |
|
454 if (EnableThreadSMRStatistics) { |
|
455 _thread->inc_nested_threads_hazard_ptr_cnt(); |
|
456 } |
|
457 current_list->inc_nested_handle_cnt(); |
|
458 _previous->_has_ref_count = true; // promote SafeThreadsListPtr to be reference counted |
|
459 _thread->_threads_hazard_ptr = NULL; // clear the hazard ptr so we can go through the fast path below |
|
460 |
|
461 if (EnableThreadSMRStatistics && _thread->nested_threads_hazard_ptr_cnt() > ThreadsSMRSupport::_nested_thread_list_max) { |
|
462 ThreadsSMRSupport::_nested_thread_list_max = _thread->nested_threads_hazard_ptr_cnt(); |
|
463 } |
|
464 |
|
465 acquire_stable_list_fast_path(); |
|
466 |
|
467 verify_hazard_ptr_scanned(); |
|
468 |
|
469 log_debug(thread, smr)("tid=" UINTX_FORMAT ": SafeThreadsListPtr::acquire_stable_list: add nested list pointer to ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(_list)); |
|
470 } |
|
471 |
|
472 // Release a stable ThreadsList. |
|
473 // |
|
474 void SafeThreadsListPtr::release_stable_list() { |
|
475 assert(_thread != NULL, "sanity check"); |
|
476 assert(_thread->_threads_list_ptr == this, "sanity check"); |
|
477 _thread->_threads_list_ptr = _previous; |
|
478 |
|
479 if (_has_ref_count) { |
|
480 // If a SafeThreadsListPtr has been promoted to use reference counting |
|
481 // due to nesting of ThreadsListHandles, then the reference count must be |
|
482 // decremented, at which point it may be freed. The forgotten value of |
|
483 // the list no longer matters at this point and should already be NULL. |
|
484 assert(_thread->get_threads_hazard_ptr() == NULL, "sanity check"); |
|
485 if (EnableThreadSMRStatistics) { |
|
486 _thread->dec_nested_threads_hazard_ptr_cnt(); |
|
487 } |
|
488 _list->dec_nested_handle_cnt(); |
|
489 |
|
490 log_debug(thread, smr)("tid=" UINTX_FORMAT ": SafeThreadsListPtr::release_stable_list: delete nested list pointer to ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(_list)); |
|
491 } else { |
|
492 // The normal case: a leaf ThreadsListHandle. This merely requires setting |
|
493 // the thread hazard ptr back to NULL. |
|
494 assert(_thread->get_threads_hazard_ptr() != NULL, "sanity check"); |
|
495 _thread->set_threads_hazard_ptr(NULL); |
|
496 } |
|
497 |
|
498 // After releasing the hazard ptr, other threads may go ahead and |
|
499 // free up some memory temporarily used by a ThreadsList snapshot. |
|
500 |
|
501 // We use double-check locking to reduce traffic on the system |
|
502 // wide Thread-SMR delete_lock. |
|
503 if (ThreadsSMRSupport::delete_notify()) { |
|
504 // An exiting thread might be waiting in smr_delete(); we need to |
|
505 // check with delete_lock to be sure. |
|
506 ThreadsSMRSupport::release_stable_list_wake_up(_has_ref_count); |
|
507 } |
|
508 } |
|
509 |
|
510 // Verify that the stable hazard ptr used to safely keep threads |
|
511 // alive is scanned by threads_do() which is a key piece of honoring |
|
512 // the Thread-SMR protocol. |
|
513 void SafeThreadsListPtr::verify_hazard_ptr_scanned() { |
|
514 #ifdef ASSERT |
|
515 assert(_list != NULL, "_list must not be NULL"); |
|
516 |
|
517 // The closure will attempt to verify that the calling thread can |
|
518 // be found by threads_do() on the specified ThreadsList. If it |
|
519 // is successful, then the specified ThreadsList was acquired as |
|
520 // a stable hazard ptr by the calling thread in a way that honored |
|
521 // the Thread-SMR protocol. |
|
522 // |
|
523 // If the calling thread cannot be found by threads_do() and if |
|
524 // it is not the shutdown thread, then the calling thread is not |
|
525 // honoring the Thread-SMR ptotocol. This means that the specified |
|
526 // ThreadsList is not a stable hazard ptr and can be freed by |
|
527 // another thread from the to-be-deleted list at any time. |
|
528 // |
|
529 // Note: The shutdown thread has removed itself from the Threads |
|
530 // list and is safe to have a waiver from this check because |
|
531 // VM_Exit::_shutdown_thread is not set until after the VMThread |
|
532 // has started the final safepoint which holds the Threads_lock |
|
533 // for the remainder of the VM's life. |
|
534 // |
|
535 VerifyHazardPtrThreadClosure cl(_thread); |
|
536 ThreadsSMRSupport::threads_do(&cl, _list); |
|
537 |
|
538 // If the calling thread is not honoring the Thread-SMR protocol, |
|
539 // then we will either crash in threads_do() above because 'threads' |
|
540 // was freed by another thread or we will fail the assert() below. |
|
541 // In either case, we won't get past this point with a badly placed |
|
542 // ThreadsListHandle. |
|
543 |
|
544 assert(cl.found() || _thread == VM_Exit::shutdown_thread(), "Acquired a ThreadsList snapshot from a thread not recognized by the Thread-SMR protocol."); |
|
545 #endif |
|
546 } |
381 |
547 |
382 // 'entries + 1' so we always have at least one entry. |
548 // 'entries + 1' so we always have at least one entry. |
383 ThreadsList::ThreadsList(int entries) : _length(entries), _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), _next_list(NULL) { |
549 ThreadsList::ThreadsList(int entries) : |
|
550 _length(entries), |
|
551 _next_list(NULL), |
|
552 _threads(NEW_C_HEAP_ARRAY(JavaThread*, entries + 1, mtThread)), |
|
553 _nested_handle_cnt(0) |
|
554 { |
384 *(JavaThread**)(_threads + entries) = NULL; // Make sure the extra entry is NULL. |
555 *(JavaThread**)(_threads + entries) = NULL; // Make sure the extra entry is NULL. |
385 } |
556 } |
386 |
557 |
387 ThreadsList::~ThreadsList() { |
558 ThreadsList::~ThreadsList() { |
388 FREE_C_HEAP_ARRAY(JavaThread*, _threads); |
559 FREE_C_HEAP_ARRAY(JavaThread*, _threads); |
534 // ThreadsListHandle in the caller. |
729 // ThreadsListHandle in the caller. |
535 *jt_pp = java_thread; |
730 *jt_pp = java_thread; |
536 return true; |
731 return true; |
537 } |
732 } |
538 |
733 |
539 ThreadsListSetter::~ThreadsListSetter() { |
|
540 if (_target_needs_release) { |
|
541 // The hazard ptr in the target needs to be released. |
|
542 ThreadsSMRSupport::release_stable_list(_target); |
|
543 } |
|
544 } |
|
545 |
|
546 // Closure to determine if the specified JavaThread is found by |
|
547 // threads_do(). |
|
548 // |
|
549 class VerifyHazardPointerThreadClosure : public ThreadClosure { |
|
550 private: |
|
551 bool _found; |
|
552 Thread *_self; |
|
553 |
|
554 public: |
|
555 VerifyHazardPointerThreadClosure(Thread *self) : _found(false), _self(self) {} |
|
556 |
|
557 bool found() const { return _found; } |
|
558 |
|
559 virtual void do_thread(Thread *thread) { |
|
560 if (thread == _self) { |
|
561 _found = true; |
|
562 } |
|
563 } |
|
564 }; |
|
565 |
|
566 // Apply the closure to all threads in the system, with a snapshot of |
|
567 // all JavaThreads provided by the list parameter. |
|
568 void ThreadsSMRSupport::threads_do(ThreadClosure *tc, ThreadsList *list) { |
|
569 list->threads_do(tc); |
|
570 Threads::non_java_threads_do(tc); |
|
571 } |
|
572 |
|
573 // Apply the closure to all threads in the system. |
|
574 void ThreadsSMRSupport::threads_do(ThreadClosure *tc) { |
|
575 threads_do(tc, _java_thread_list); |
|
576 } |
|
577 |
|
578 // Verify that the stable hazard pointer used to safely keep threads |
|
579 // alive is scanned by threads_do() which is a key piece of honoring |
|
580 // the Thread-SMR protocol. |
|
581 void ThreadsSMRSupport::verify_hazard_pointer_scanned(Thread *self, ThreadsList *threads) { |
|
582 #ifdef ASSERT |
|
583 assert(threads != NULL, "threads must not be NULL"); |
|
584 |
|
585 // The closure will attempt to verify that the calling thread can |
|
586 // be found by threads_do() on the specified ThreadsList. If it |
|
587 // is successful, then the specified ThreadsList was acquired as |
|
588 // a stable hazard pointer by the calling thread in a way that |
|
589 // honored the Thread-SMR protocol. |
|
590 // |
|
591 // If the calling thread cannot be found by threads_do() and if |
|
592 // it is not the shutdown thread, then the calling thread is not |
|
593 // honoring the Thread-SMR ptotocol. This means that the specified |
|
594 // ThreadsList is not a stable hazard pointer and can be freed |
|
595 // by another thread from the to-be-deleted list at any time. |
|
596 // |
|
597 // Note: The shutdown thread has removed itself from the Threads |
|
598 // list and is safe to have a waiver from this check because |
|
599 // VM_Exit::_shutdown_thread is not set until after the VMThread |
|
600 // has started the final safepoint which holds the Threads_lock |
|
601 // for the remainder of the VM's life. |
|
602 // |
|
603 VerifyHazardPointerThreadClosure cl(self); |
|
604 threads_do(&cl, threads); |
|
605 |
|
606 // If the calling thread is not honoring the Thread-SMR protocol, |
|
607 // then we will either crash in threads_do() above because 'threads' |
|
608 // was freed by another thread or we will fail the assert() below. |
|
609 // In either case, we won't get past this point with a badly placed |
|
610 // ThreadsListHandle. |
|
611 |
|
612 assert(cl.found() || self == VM_Exit::shutdown_thread(), "Acquired a ThreadsList snapshot from a thread not recognized by the Thread-SMR protocol."); |
|
613 #endif |
|
614 } |
|
615 |
|
616 void ThreadsListSetter::set() { |
|
617 assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set"); |
|
618 (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true); |
|
619 _target_needs_release = true; |
|
620 } |
|
621 |
|
622 // Acquire a stable ThreadsList. |
|
623 // |
|
624 ThreadsList *ThreadsSMRSupport::acquire_stable_list(Thread *self, bool is_ThreadsListSetter) { |
|
625 assert(self != NULL, "sanity check"); |
|
626 // acquire_stable_list_nested_path() will grab the Threads_lock |
|
627 // so let's make sure the ThreadsListHandle is in a safe place. |
|
628 // ThreadsListSetter cannot make this check on this code path. |
|
629 debug_only(if (!is_ThreadsListSetter && StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) |
|
630 |
|
631 if (self->get_threads_hazard_ptr() == NULL) { |
|
632 // The typical case is first. |
|
633 return acquire_stable_list_fast_path(self); |
|
634 } |
|
635 |
|
636 // The nested case is rare. |
|
637 return acquire_stable_list_nested_path(self); |
|
638 } |
|
639 |
|
640 // Fast path (and lock free) way to acquire a stable ThreadsList. |
|
641 // |
|
642 ThreadsList *ThreadsSMRSupport::acquire_stable_list_fast_path(Thread *self) { |
|
643 assert(self != NULL, "sanity check"); |
|
644 assert(self->get_threads_hazard_ptr() == NULL, "sanity check"); |
|
645 assert(self->get_nested_threads_hazard_ptr() == NULL, |
|
646 "cannot have a nested hazard ptr with a NULL regular hazard ptr"); |
|
647 |
|
648 ThreadsList* threads; |
|
649 |
|
650 // Stable recording of a hazard ptr for SMR. This code does not use |
|
651 // locks so its use of the _java_thread_list & _threads_hazard_ptr |
|
652 // fields is racy relative to code that uses those fields with locks. |
|
653 // OrderAccess and Atomic functions are used to deal with those races. |
|
654 // |
|
655 while (true) { |
|
656 threads = get_java_thread_list(); |
|
657 |
|
658 // Publish a tagged hazard ptr to denote that the hazard ptr is not |
|
659 // yet verified as being stable. Due to the fence after the hazard |
|
660 // ptr write, it will be sequentially consistent w.r.t. the |
|
661 // sequentially consistent writes of the ThreadsList, even on |
|
662 // non-multiple copy atomic machines where stores can be observed |
|
663 // in different order from different observer threads. |
|
664 ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); |
|
665 self->set_threads_hazard_ptr(unverified_threads); |
|
666 |
|
667 // If _java_thread_list has changed, we have lost a race with |
|
668 // Threads::add() or Threads::remove() and have to try again. |
|
669 if (get_java_thread_list() != threads) { |
|
670 continue; |
|
671 } |
|
672 |
|
673 // We try to remove the tag which will verify the hazard ptr as |
|
674 // being stable. This exchange can race with a scanning thread |
|
675 // which might invalidate the tagged hazard ptr to keep it from |
|
676 // being followed to access JavaThread ptrs. If we lose the race, |
|
677 // we simply retry. If we win the race, then the stable hazard |
|
678 // ptr is officially published. |
|
679 if (self->cmpxchg_threads_hazard_ptr(threads, unverified_threads) == unverified_threads) { |
|
680 break; |
|
681 } |
|
682 } |
|
683 |
|
684 // A stable hazard ptr has been published letting other threads know |
|
685 // that the ThreadsList and the JavaThreads reachable from this list |
|
686 // are protected and hence they should not be deleted until everyone |
|
687 // agrees it is safe to do so. |
|
688 |
|
689 verify_hazard_pointer_scanned(self, threads); |
|
690 |
|
691 return threads; |
|
692 } |
|
693 |
|
694 // Acquire a nested stable ThreadsList; this is rare so it uses |
|
695 // Threads_lock. |
|
696 // |
|
697 ThreadsList *ThreadsSMRSupport::acquire_stable_list_nested_path(Thread *self) { |
|
698 assert(self != NULL, "sanity check"); |
|
699 assert(self->get_threads_hazard_ptr() != NULL, |
|
700 "cannot have a NULL regular hazard ptr when acquiring a nested hazard ptr"); |
|
701 |
|
702 // The thread already has a hazard ptr (ThreadsList ref) so we need |
|
703 // to create a nested ThreadsListHandle with the current ThreadsList |
|
704 // since it might be different than our current hazard ptr. The need |
|
705 // for a nested ThreadsListHandle is rare so we do this while holding |
|
706 // the Threads_lock so we don't race with the scanning code; the code |
|
707 // is so much simpler this way. |
|
708 |
|
709 NestedThreadsList* node; |
|
710 { |
|
711 // Only grab the Threads_lock if we don't already own it. |
|
712 MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); |
|
713 node = new NestedThreadsList(get_java_thread_list()); |
|
714 // We insert at the front of the list to match up with the delete |
|
715 // in release_stable_list(). |
|
716 node->set_next(self->get_nested_threads_hazard_ptr()); |
|
717 self->set_nested_threads_hazard_ptr(node); |
|
718 if (EnableThreadSMRStatistics) { |
|
719 self->inc_nested_threads_hazard_ptr_cnt(); |
|
720 if (self->nested_threads_hazard_ptr_cnt() > _nested_thread_list_max) { |
|
721 _nested_thread_list_max = self->nested_threads_hazard_ptr_cnt(); |
|
722 } |
|
723 } |
|
724 } |
|
725 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::acquire_stable_list: add NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); |
|
726 |
|
727 verify_hazard_pointer_scanned(self, node->t_list()); |
|
728 |
|
729 return node->t_list(); |
|
730 } |
|
731 |
|
732 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
734 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
733 ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_java_thread_list(), thread); |
735 ThreadsList *new_list = ThreadsList::add_thread(get_java_thread_list(), thread); |
734 if (EnableThreadSMRStatistics) { |
736 if (EnableThreadSMRStatistics) { |
735 ThreadsSMRSupport::inc_java_thread_list_alloc_cnt(); |
737 inc_java_thread_list_alloc_cnt(); |
736 ThreadsSMRSupport::update_java_thread_list_max(new_list->length()); |
738 update_java_thread_list_max(new_list->length()); |
737 } |
739 } |
738 // Initial _java_thread_list will not generate a "Threads::add" mesg. |
740 // Initial _java_thread_list will not generate a "Threads::add" mesg. |
739 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
741 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
740 |
742 |
741 ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list); |
743 ThreadsList *old_list = xchg_java_thread_list(new_list); |
742 ThreadsSMRSupport::free_list(old_list); |
744 free_list(old_list); |
743 } |
745 } |
744 |
746 |
745 // set_delete_notify() and clear_delete_notify() are called |
747 // set_delete_notify() and clear_delete_notify() are called |
746 // under the protection of the delete_lock, but we also use an |
748 // under the protection of the delete_lock, but we also use an |
747 // Atomic operation to ensure the memory update is seen earlier than |
749 // Atomic operation to ensure the memory update is seen earlier than |
847 // Gather a hash table of the JavaThreads indirectly referenced by |
851 // Gather a hash table of the JavaThreads indirectly referenced by |
848 // hazard ptrs. |
852 // hazard ptrs. |
849 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
853 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
850 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
854 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
851 threads_do(&scan_cl); |
855 threads_do(&scan_cl); |
|
856 OrderAccess::acquire(); // Must order reads of hazard ptr before reads of |
|
857 // nested reference counters |
|
858 |
|
859 // Walk through the linked list of pending freeable ThreadsLists |
|
860 // and include the ones that are currently in use by a nested |
|
861 // ThreadsListHandle in the search set. |
|
862 ThreadsList* current = _to_delete_list; |
|
863 while (current != NULL) { |
|
864 if (current->_nested_handle_cnt != 0) { |
|
865 // 'current' is in use by a nested ThreadsListHandle so the hazard |
|
866 // ptr is protecting all the JavaThreads on that ThreadsList. |
|
867 AddThreadHazardPointerThreadClosure add_cl(scan_table); |
|
868 current->threads_do(&add_cl); |
|
869 } |
|
870 current = current->next_list(); |
|
871 } |
852 |
872 |
853 bool thread_is_protected = false; |
873 bool thread_is_protected = false; |
854 if (scan_table->has_entry((void*)thread)) { |
874 if (scan_table->has_entry((void*)thread)) { |
855 thread_is_protected = true; |
875 thread_is_protected = true; |
856 } |
876 } |
857 delete scan_table; |
877 delete scan_table; |
858 return thread_is_protected; |
878 return thread_is_protected; |
859 } |
879 } |
860 |
880 |
861 // Release a stable ThreadsList. |
|
862 // |
|
863 void ThreadsSMRSupport::release_stable_list(Thread *self) { |
|
864 assert(self != NULL, "sanity check"); |
|
865 // release_stable_list_nested_path() will grab the Threads_lock |
|
866 // so let's make sure the ThreadsListHandle is in a safe place. |
|
867 debug_only(if (StrictSafepointChecks) self->check_for_valid_safepoint_state(/* potential_vm_operation */ false);) |
|
868 |
|
869 if (self->get_nested_threads_hazard_ptr() == NULL) { |
|
870 // The typical case is first. |
|
871 release_stable_list_fast_path(self); |
|
872 return; |
|
873 } |
|
874 |
|
875 // The nested case is rare. |
|
876 release_stable_list_nested_path(self); |
|
877 } |
|
878 |
|
879 // Fast path way to release a stable ThreadsList. The release portion |
|
880 // is lock-free, but the wake up portion is not. |
|
881 // |
|
882 void ThreadsSMRSupport::release_stable_list_fast_path(Thread *self) { |
|
883 assert(self != NULL, "sanity check"); |
|
884 assert(self->get_threads_hazard_ptr() != NULL, "sanity check"); |
|
885 assert(self->get_nested_threads_hazard_ptr() == NULL, |
|
886 "cannot have a nested hazard ptr when releasing a regular hazard ptr"); |
|
887 |
|
888 // After releasing the hazard ptr, other threads may go ahead and |
|
889 // free up some memory temporarily used by a ThreadsList snapshot. |
|
890 self->set_threads_hazard_ptr(NULL); |
|
891 |
|
892 // We use double-check locking to reduce traffic on the system |
|
893 // wide Thread-SMR delete_lock. |
|
894 if (ThreadsSMRSupport::delete_notify()) { |
|
895 // An exiting thread might be waiting in smr_delete(); we need to |
|
896 // check with delete_lock to be sure. |
|
897 release_stable_list_wake_up((char *) "regular hazard ptr"); |
|
898 } |
|
899 } |
|
900 |
|
901 // Release a nested stable ThreadsList; this is rare so it uses |
|
902 // Threads_lock. |
|
903 // |
|
904 void ThreadsSMRSupport::release_stable_list_nested_path(Thread *self) { |
|
905 assert(self != NULL, "sanity check"); |
|
906 assert(self->get_nested_threads_hazard_ptr() != NULL, "sanity check"); |
|
907 assert(self->get_threads_hazard_ptr() != NULL, |
|
908 "must have a regular hazard ptr to have nested hazard ptrs"); |
|
909 |
|
910 // We have a nested ThreadsListHandle so we have to release it first. |
|
911 // The need for a nested ThreadsListHandle is rare so we do this while |
|
912 // holding the Threads_lock so we don't race with the scanning code; |
|
913 // the code is so much simpler this way. |
|
914 |
|
915 NestedThreadsList *node; |
|
916 { |
|
917 // Only grab the Threads_lock if we don't already own it. |
|
918 MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); |
|
919 // We remove from the front of the list to match up with the insert |
|
920 // in acquire_stable_list(). |
|
921 node = self->get_nested_threads_hazard_ptr(); |
|
922 self->set_nested_threads_hazard_ptr(node->next()); |
|
923 if (EnableThreadSMRStatistics) { |
|
924 self->dec_nested_threads_hazard_ptr_cnt(); |
|
925 } |
|
926 } |
|
927 |
|
928 // An exiting thread might be waiting in smr_delete(); we need to |
|
929 // check with delete_lock to be sure. |
|
930 release_stable_list_wake_up((char *) "nested hazard ptr"); |
|
931 |
|
932 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list: delete NestedThreadsList node containing ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(node->t_list())); |
|
933 |
|
934 delete node; |
|
935 } |
|
936 |
|
937 // Wake up portion of the release stable ThreadsList protocol; |
881 // Wake up portion of the release stable ThreadsList protocol; |
938 // uses the delete_lock(). |
882 // uses the delete_lock(). |
939 // |
883 // |
940 void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) { |
884 void ThreadsSMRSupport::release_stable_list_wake_up(bool is_nested) { |
941 assert(log_str != NULL, "sanity check"); |
885 const char* log_str = is_nested ? "nested hazard ptr" : "regular hazard ptr"; |
942 |
886 |
943 // Note: delete_lock is held in smr_delete() for the entire |
887 // Note: delete_lock is held in smr_delete() for the entire |
944 // hazard ptr search so that we do not lose this notify() if |
888 // hazard ptr search so that we do not lose this notify() if |
945 // the exiting thread has to wait. That code path also holds |
889 // the exiting thread has to wait. That code path also holds |
946 // Threads_lock (which was grabbed before delete_lock) so that |
890 // Threads_lock (which was grabbed before delete_lock) so that |
1053 } |
1004 } |
1054 |
1005 |
1055 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); |
1006 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); |
1056 } |
1007 } |
1057 |
1008 |
|
1009 // Apply the closure to all threads in the system, with a snapshot of |
|
1010 // all JavaThreads provided by the list parameter. |
|
1011 void ThreadsSMRSupport::threads_do(ThreadClosure *tc, ThreadsList *list) { |
|
1012 list->threads_do(tc); |
|
1013 Threads::non_java_threads_do(tc); |
|
1014 } |
|
1015 |
|
1016 // Apply the closure to all threads in the system. |
|
1017 void ThreadsSMRSupport::threads_do(ThreadClosure *tc) { |
|
1018 threads_do(tc, _java_thread_list); |
|
1019 } |
|
1020 |
1058 |
1021 |
1059 // Debug, logging, and printing stuff at the end: |
1022 // Debug, logging, and printing stuff at the end: |
|
1023 |
|
1024 // Print SMR info for a SafeThreadsListPtr to a given output stream. |
|
1025 void SafeThreadsListPtr::print_on(outputStream* st) { |
|
1026 if (this == _thread->_threads_list_ptr) { |
|
1027 // The top level hazard ptr. |
|
1028 st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(_list)); |
|
1029 } else { |
|
1030 // Nested hazard ptrs. |
|
1031 st->print(", _nested_threads_hazard_ptr=" INTPTR_FORMAT, p2i(_list)); |
|
1032 } |
|
1033 } |
1060 |
1034 |
1061 // Log Threads class SMR info. |
1035 // Log Threads class SMR info. |
1062 void ThreadsSMRSupport::log_statistics() { |
1036 void ThreadsSMRSupport::log_statistics() { |
1063 LogTarget(Info, thread, smr) log; |
1037 LogTarget(Info, thread, smr) log; |
1064 if (log.is_enabled()) { |
1038 if (log.is_enabled()) { |
1065 LogStream out(log); |
1039 LogStream out(log); |
1066 print_info_on(&out); |
1040 print_info_on(&out); |
|
1041 } |
|
1042 } |
|
1043 |
|
1044 // Print SMR info for a thread to a given output stream. |
|
1045 void ThreadsSMRSupport::print_info_on(const Thread* thread, outputStream* st) { |
|
1046 if (thread->_threads_hazard_ptr != NULL) { |
|
1047 st->print(" _threads_hazard_ptr=" INTPTR_FORMAT, p2i(thread->_threads_hazard_ptr)); |
|
1048 } |
|
1049 if (EnableThreadSMRStatistics && thread->_threads_list_ptr != NULL) { |
|
1050 // The count is only interesting if we have a _threads_list_ptr. |
|
1051 st->print(", _nested_threads_hazard_ptr_cnt=%u", thread->_nested_threads_hazard_ptr_cnt); |
|
1052 } |
|
1053 if (SafepointSynchronize::is_at_safepoint() || Thread::current() == thread) { |
|
1054 // It is only safe to walk the list if we're at a safepoint or the |
|
1055 // calling thread is walking its own list. |
|
1056 SafeThreadsListPtr* current = thread->_threads_list_ptr; |
|
1057 if (current != NULL) { |
|
1058 // Skip the top nesting level as it is always printed above. |
|
1059 current = current->previous(); |
|
1060 } |
|
1061 while (current != NULL) { |
|
1062 current->print_on(st); |
|
1063 current = current->previous(); |
|
1064 } |
1067 } |
1065 } |
1068 } |
1066 } |
1069 |
1067 |
1070 // Print Threads class SMR info. |
1068 // Print Threads class SMR info. |
1071 void ThreadsSMRSupport::print_info_on(outputStream* st) { |
1069 void ThreadsSMRSupport::print_info_on(outputStream* st) { |