468 return new_list; |
468 return new_list; |
469 } |
469 } |
470 |
470 |
471 ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) { |
471 ThreadsListHandle::ThreadsListHandle(Thread *self) : _list(ThreadsSMRSupport::acquire_stable_list(self, /* is_ThreadsListSetter */ false)), _self(self) { |
472 assert(self == Thread::current(), "sanity check"); |
472 assert(self == Thread::current(), "sanity check"); |
473 // Threads::threads_do() is used by the Thread-SMR protocol to visit all |
|
474 // Threads in the system which ensures the safety of the ThreadsList |
|
475 // managed by this ThreadsListHandle, but JavaThreads that are not on |
|
476 // the Threads list cannot be included in that visit. The JavaThread that |
|
477 // calls Threads::destroy_vm() is exempt from this check because it has |
|
478 // to logically exit as part of the shutdown procedure. This is safe |
|
479 // because VM_Exit::_shutdown_thread is not set until after the VMThread |
|
480 // has started the final safepoint which holds the Threads_lock for the |
|
481 // remainder of the VM's life. |
|
482 assert(!self->is_Java_thread() || self == VM_Exit::shutdown_thread() || (((JavaThread*)self)->on_thread_list() && !((JavaThread*)self)->is_terminated()), "JavaThread must be on the Threads list to use a ThreadsListHandle"); |
|
483 if (EnableThreadSMRStatistics) { |
473 if (EnableThreadSMRStatistics) { |
484 _timer.start(); |
474 _timer.start(); |
485 } |
475 } |
486 } |
476 } |
487 |
477 |
549 ThreadsListSetter::~ThreadsListSetter() { |
539 ThreadsListSetter::~ThreadsListSetter() { |
550 if (_target_needs_release) { |
540 if (_target_needs_release) { |
551 // The hazard ptr in the target needs to be released. |
541 // The hazard ptr in the target needs to be released. |
552 ThreadsSMRSupport::release_stable_list(_target); |
542 ThreadsSMRSupport::release_stable_list(_target); |
553 } |
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 |
554 } |
614 } |
555 |
615 |
556 void ThreadsListSetter::set() { |
616 void ThreadsListSetter::set() { |
557 assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set"); |
617 assert(_target->get_threads_hazard_ptr() == NULL, "hazard ptr should not already be set"); |
558 (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true); |
618 (void) ThreadsSMRSupport::acquire_stable_list(_target, /* is_ThreadsListSetter */ true); |
660 } |
722 } |
661 } |
723 } |
662 } |
724 } |
663 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())); |
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())); |
664 |
726 |
|
727 verify_hazard_pointer_scanned(self, node->t_list()); |
|
728 |
665 return node->t_list(); |
729 return node->t_list(); |
666 } |
730 } |
667 |
731 |
668 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
732 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
669 ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_java_thread_list(), thread); |
733 ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_java_thread_list(), thread); |
720 hash_table_size++; |
784 hash_table_size++; |
721 |
785 |
722 // Gather a hash table of the current hazard ptrs: |
786 // Gather a hash table of the current hazard ptrs: |
723 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
787 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
724 ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); |
788 ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); |
725 Threads::threads_do(&scan_cl); |
789 threads_do(&scan_cl); |
726 |
790 |
727 // Walk through the linked list of pending freeable ThreadsLists |
791 // Walk through the linked list of pending freeable ThreadsLists |
728 // and free the ones that are not referenced from hazard ptrs. |
792 // and free the ones that are not referenced from hazard ptrs. |
729 ThreadsList* current = _to_delete_list; |
793 ThreadsList* current = _to_delete_list; |
730 ThreadsList* prev = NULL; |
794 ThreadsList* prev = NULL; |
782 |
846 |
783 // Gather a hash table of the JavaThreads indirectly referenced by |
847 // Gather a hash table of the JavaThreads indirectly referenced by |
784 // hazard ptrs. |
848 // hazard ptrs. |
785 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
849 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
786 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
850 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
787 Threads::threads_do(&scan_cl); |
851 threads_do(&scan_cl); |
788 |
852 |
789 bool thread_is_protected = false; |
853 bool thread_is_protected = false; |
790 if (scan_table->has_entry((void*)thread)) { |
854 if (scan_table->has_entry((void*)thread)) { |
791 thread_is_protected = true; |
855 thread_is_protected = true; |
792 } |
856 } |
947 if (!has_logged_once) { |
1011 if (!has_logged_once) { |
948 has_logged_once = true; |
1012 has_logged_once = true; |
949 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread)); |
1013 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is not deleted.", os::current_thread_id(), p2i(thread)); |
950 if (log_is_enabled(Debug, os, thread)) { |
1014 if (log_is_enabled(Debug, os, thread)) { |
951 ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread); |
1015 ScanHazardPtrPrintMatchingThreadsClosure scan_cl(thread); |
952 Threads::threads_do(&scan_cl); |
1016 threads_do(&scan_cl); |
953 } |
1017 } |
954 } |
1018 } |
955 } // We have to drop the Threads_lock to wait or delete the thread |
1019 } // We have to drop the Threads_lock to wait or delete the thread |
956 |
1020 |
957 if (EnableThreadSMRStatistics) { |
1021 if (EnableThreadSMRStatistics) { |