29 #include "runtime/threadSMR.inline.hpp" |
29 #include "runtime/threadSMR.inline.hpp" |
30 #include "services/threadService.hpp" |
30 #include "services/threadService.hpp" |
31 #include "utilities/globalDefinitions.hpp" |
31 #include "utilities/globalDefinitions.hpp" |
32 #include "utilities/resourceHash.hpp" |
32 #include "utilities/resourceHash.hpp" |
33 |
33 |
34 Monitor* ThreadsSMRSupport::_smr_delete_lock = |
34 Monitor* ThreadsSMRSupport::_delete_lock = |
35 new Monitor(Monitor::special, "smr_delete_lock", |
35 new Monitor(Monitor::special, "Thread_SMR_delete_lock", |
36 false /* allow_vm_block */, |
36 false /* allow_vm_block */, |
37 Monitor::_safepoint_check_never); |
37 Monitor::_safepoint_check_never); |
38 // The '_cnt', '_max' and '_times" fields are enabled via |
38 // The '_cnt', '_max' and '_times" fields are enabled via |
39 // -XX:+EnableThreadSMRStatistics: |
39 // -XX:+EnableThreadSMRStatistics: |
40 |
40 |
41 // # of parallel threads in _smr_delete_lock->wait(). |
41 // # of parallel threads in _delete_lock->wait(). |
42 // Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit, |
42 // Impl note: Hard to imagine > 64K waiting threads so this could be 16-bit, |
43 // but there is no nice 16-bit _FORMAT support. |
43 // but there is no nice 16-bit _FORMAT support. |
44 uint ThreadsSMRSupport::_smr_delete_lock_wait_cnt = 0; |
44 uint ThreadsSMRSupport::_delete_lock_wait_cnt = 0; |
45 |
45 |
46 // Max # of parallel threads in _smr_delete_lock->wait(). |
46 // Max # of parallel threads in _delete_lock->wait(). |
47 // Impl note: See _smr_delete_lock_wait_cnt note. |
47 // Impl note: See _delete_lock_wait_cnt note. |
48 uint ThreadsSMRSupport::_smr_delete_lock_wait_max = 0; |
48 uint ThreadsSMRSupport::_delete_lock_wait_max = 0; |
49 |
49 |
50 // Flag to indicate when an _smr_delete_lock->notify() is needed. |
50 // Flag to indicate when an _delete_lock->notify() is needed. |
51 // Impl note: See _smr_delete_lock_wait_cnt note. |
51 // Impl note: See _delete_lock_wait_cnt note. |
52 volatile uint ThreadsSMRSupport::_smr_delete_notify = 0; |
52 volatile uint ThreadsSMRSupport::_delete_notify = 0; |
53 |
53 |
54 // # of threads deleted over VM lifetime. |
54 // # of threads deleted over VM lifetime. |
55 // Impl note: Atomically incremented over VM lifetime so use unsigned for more |
55 // Impl note: Atomically incremented over VM lifetime so use unsigned for more |
56 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
56 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
57 // isn't available everywhere (or is it?). |
57 // isn't available everywhere (or is it?). |
58 volatile uint ThreadsSMRSupport::_smr_deleted_thread_cnt = 0; |
58 volatile uint ThreadsSMRSupport::_deleted_thread_cnt = 0; |
59 |
59 |
60 // Max time in millis to delete a thread. |
60 // Max time in millis to delete a thread. |
61 // Impl note: 16-bit might be too small on an overloaded machine. Use |
61 // Impl note: 16-bit might be too small on an overloaded machine. Use |
62 // unsigned since this is a time value. Set via Atomic::cmpxchg() in a |
62 // unsigned since this is a time value. Set via Atomic::cmpxchg() in a |
63 // loop for correctness. |
63 // loop for correctness. |
64 volatile uint ThreadsSMRSupport::_smr_deleted_thread_time_max = 0; |
64 volatile uint ThreadsSMRSupport::_deleted_thread_time_max = 0; |
65 |
65 |
66 // Cumulative time in millis to delete threads. |
66 // Cumulative time in millis to delete threads. |
67 // Impl note: Atomically added to over VM lifetime so use unsigned for more |
67 // Impl note: Atomically added to over VM lifetime so use unsigned for more |
68 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
68 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
69 // isn't available everywhere (or is it?). |
69 // isn't available everywhere (or is it?). |
70 volatile uint ThreadsSMRSupport::_smr_deleted_thread_times = 0; |
70 volatile uint ThreadsSMRSupport::_deleted_thread_times = 0; |
71 |
71 |
72 ThreadsList* volatile ThreadsSMRSupport::_smr_java_thread_list = new ThreadsList(0); |
72 ThreadsList* volatile ThreadsSMRSupport::_java_thread_list = new ThreadsList(0); |
73 |
73 |
74 // # of ThreadsLists allocated over VM lifetime. |
74 // # of ThreadsLists allocated over VM lifetime. |
75 // Impl note: We allocate a new ThreadsList for every thread create and |
75 // Impl note: We allocate a new ThreadsList for every thread create and |
76 // every thread delete so we need a bigger type than the |
76 // every thread delete so we need a bigger type than the |
77 // _smr_deleted_thread_cnt field. |
77 // _deleted_thread_cnt field. |
78 uint64_t ThreadsSMRSupport::_smr_java_thread_list_alloc_cnt = 1; |
78 uint64_t ThreadsSMRSupport::_java_thread_list_alloc_cnt = 1; |
79 |
79 |
80 // # of ThreadsLists freed over VM lifetime. |
80 // # of ThreadsLists freed over VM lifetime. |
81 // Impl note: See _smr_java_thread_list_alloc_cnt note. |
81 // Impl note: See _java_thread_list_alloc_cnt note. |
82 uint64_t ThreadsSMRSupport::_smr_java_thread_list_free_cnt = 0; |
82 uint64_t ThreadsSMRSupport::_java_thread_list_free_cnt = 0; |
83 |
83 |
84 // Max size ThreadsList allocated. |
84 // Max size ThreadsList allocated. |
85 // Impl note: Max # of threads alive at one time should fit in unsigned 32-bit. |
85 // Impl note: Max # of threads alive at one time should fit in unsigned 32-bit. |
86 uint ThreadsSMRSupport::_smr_java_thread_list_max = 0; |
86 uint ThreadsSMRSupport::_java_thread_list_max = 0; |
87 |
87 |
88 // Max # of nested ThreadsLists for a thread. |
88 // Max # of nested ThreadsLists for a thread. |
89 // Impl note: Hard to imagine > 64K nested ThreadsLists so this could be |
89 // Impl note: Hard to imagine > 64K nested ThreadsLists so this could be |
90 // 16-bit, but there is no nice 16-bit _FORMAT support. |
90 // 16-bit, but there is no nice 16-bit _FORMAT support. |
91 uint ThreadsSMRSupport::_smr_nested_thread_list_max = 0; |
91 uint ThreadsSMRSupport::_nested_thread_list_max = 0; |
92 |
92 |
93 // # of ThreadsListHandles deleted over VM lifetime. |
93 // # of ThreadsListHandles deleted over VM lifetime. |
94 // Impl note: Atomically incremented over VM lifetime so use unsigned for |
94 // Impl note: Atomically incremented over VM lifetime so use unsigned for |
95 // more range. There will be fewer ThreadsListHandles than threads so |
95 // more range. There will be fewer ThreadsListHandles than threads so |
96 // unsigned 32-bit should be fine. |
96 // unsigned 32-bit should be fine. |
97 volatile uint ThreadsSMRSupport::_smr_tlh_cnt = 0; |
97 volatile uint ThreadsSMRSupport::_tlh_cnt = 0; |
98 |
98 |
99 // Max time in millis to delete a ThreadsListHandle. |
99 // Max time in millis to delete a ThreadsListHandle. |
100 // Impl note: 16-bit might be too small on an overloaded machine. Use |
100 // Impl note: 16-bit might be too small on an overloaded machine. Use |
101 // unsigned since this is a time value. Set via Atomic::cmpxchg() in a |
101 // unsigned since this is a time value. Set via Atomic::cmpxchg() in a |
102 // loop for correctness. |
102 // loop for correctness. |
103 volatile uint ThreadsSMRSupport::_smr_tlh_time_max = 0; |
103 volatile uint ThreadsSMRSupport::_tlh_time_max = 0; |
104 |
104 |
105 // Cumulative time in millis to delete ThreadsListHandles. |
105 // Cumulative time in millis to delete ThreadsListHandles. |
106 // Impl note: Atomically added to over VM lifetime so use unsigned for more |
106 // Impl note: Atomically added to over VM lifetime so use unsigned for more |
107 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
107 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc |
108 // isn't available everywhere (or is it?). |
108 // isn't available everywhere (or is it?). |
109 volatile uint ThreadsSMRSupport::_smr_tlh_times = 0; |
109 volatile uint ThreadsSMRSupport::_tlh_times = 0; |
110 |
110 |
111 ThreadsList* ThreadsSMRSupport::_smr_to_delete_list = NULL; |
111 ThreadsList* ThreadsSMRSupport::_to_delete_list = NULL; |
112 |
112 |
113 // # of parallel ThreadsLists on the to-delete list. |
113 // # of parallel ThreadsLists on the to-delete list. |
114 // Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so |
114 // Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so |
115 // this could be 16-bit, but there is no nice 16-bit _FORMAT support. |
115 // this could be 16-bit, but there is no nice 16-bit _FORMAT support. |
116 uint ThreadsSMRSupport::_smr_to_delete_list_cnt = 0; |
116 uint ThreadsSMRSupport::_to_delete_list_cnt = 0; |
117 |
117 |
118 // Max # of parallel ThreadsLists on the to-delete list. |
118 // Max # of parallel ThreadsLists on the to-delete list. |
119 // Impl note: See _smr_to_delete_list_cnt note. |
119 // Impl note: See _to_delete_list_cnt note. |
120 uint ThreadsSMRSupport::_smr_to_delete_list_max = 0; |
120 uint ThreadsSMRSupport::_to_delete_list_max = 0; |
121 |
121 |
122 |
122 |
123 // 'inline' functions first so the definitions are before first use: |
123 // 'inline' functions first so the definitions are before first use: |
124 |
124 |
125 inline void ThreadsSMRSupport::add_smr_deleted_thread_times(uint add_value) { |
125 inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) { |
126 Atomic::add(add_value, &_smr_deleted_thread_times); |
126 Atomic::add(add_value, &_deleted_thread_times); |
127 } |
127 } |
128 |
128 |
129 inline void ThreadsSMRSupport::inc_smr_deleted_thread_cnt() { |
129 inline void ThreadsSMRSupport::inc_deleted_thread_cnt() { |
130 Atomic::inc(&_smr_deleted_thread_cnt); |
130 Atomic::inc(&_deleted_thread_cnt); |
131 } |
131 } |
132 |
132 |
133 inline void ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt() { |
133 inline void ThreadsSMRSupport::inc_java_thread_list_alloc_cnt() { |
134 _smr_java_thread_list_alloc_cnt++; |
134 _java_thread_list_alloc_cnt++; |
135 } |
135 } |
136 |
136 |
137 inline void ThreadsSMRSupport::update_smr_deleted_thread_time_max(uint new_value) { |
137 inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) { |
138 while (true) { |
138 while (true) { |
139 uint cur_value = _smr_deleted_thread_time_max; |
139 uint cur_value = _deleted_thread_time_max; |
140 if (new_value <= cur_value) { |
140 if (new_value <= cur_value) { |
141 // No need to update max value so we're done. |
141 // No need to update max value so we're done. |
142 break; |
142 break; |
143 } |
143 } |
144 if (Atomic::cmpxchg(new_value, &_smr_deleted_thread_time_max, cur_value) == cur_value) { |
144 if (Atomic::cmpxchg(new_value, &_deleted_thread_time_max, cur_value) == cur_value) { |
145 // Updated max value so we're done. Otherwise try it all again. |
145 // Updated max value so we're done. Otherwise try it all again. |
146 break; |
146 break; |
147 } |
147 } |
148 } |
148 } |
149 } |
149 } |
150 |
150 |
151 inline void ThreadsSMRSupport::update_smr_java_thread_list_max(uint new_value) { |
151 inline void ThreadsSMRSupport::update_java_thread_list_max(uint new_value) { |
152 if (new_value > _smr_java_thread_list_max) { |
152 if (new_value > _java_thread_list_max) { |
153 _smr_java_thread_list_max = new_value; |
153 _java_thread_list_max = new_value; |
154 } |
154 } |
155 } |
155 } |
156 |
156 |
157 inline ThreadsList* ThreadsSMRSupport::xchg_smr_java_thread_list(ThreadsList* new_list) { |
157 inline ThreadsList* ThreadsSMRSupport::xchg_java_thread_list(ThreadsList* new_list) { |
158 return (ThreadsList*)Atomic::xchg(new_list, &_smr_java_thread_list); |
158 return (ThreadsList*)Atomic::xchg(new_list, &_java_thread_list); |
159 } |
159 } |
160 |
160 |
161 |
161 |
162 // Hash table of pointers found by a scan. Used for collecting hazard |
162 // Hash table of pointers found by a scan. Used for collecting hazard |
163 // pointers (ThreadsList references). Also used for collecting JavaThreads |
163 // pointers (ThreadsList references). Also used for collecting JavaThreads |
572 "cannot have a nested hazard ptr with a NULL regular hazard ptr"); |
572 "cannot have a nested hazard ptr with a NULL regular hazard ptr"); |
573 |
573 |
574 ThreadsList* threads; |
574 ThreadsList* threads; |
575 |
575 |
576 // Stable recording of a hazard ptr for SMR. This code does not use |
576 // Stable recording of a hazard ptr for SMR. This code does not use |
577 // locks so its use of the _smr_java_thread_list & _threads_hazard_ptr |
577 // locks so its use of the _java_thread_list & _threads_hazard_ptr |
578 // fields is racy relative to code that uses those fields with locks. |
578 // fields is racy relative to code that uses those fields with locks. |
579 // OrderAccess and Atomic functions are used to deal with those races. |
579 // OrderAccess and Atomic functions are used to deal with those races. |
580 // |
580 // |
581 while (true) { |
581 while (true) { |
582 threads = get_smr_java_thread_list(); |
582 threads = get_java_thread_list(); |
583 |
583 |
584 // Publish a tagged hazard ptr to denote that the hazard ptr is not |
584 // Publish a tagged hazard ptr to denote that the hazard ptr is not |
585 // yet verified as being stable. Due to the fence after the hazard |
585 // yet verified as being stable. Due to the fence after the hazard |
586 // ptr write, it will be sequentially consistent w.r.t. the |
586 // ptr write, it will be sequentially consistent w.r.t. the |
587 // sequentially consistent writes of the ThreadsList, even on |
587 // sequentially consistent writes of the ThreadsList, even on |
588 // non-multiple copy atomic machines where stores can be observed |
588 // non-multiple copy atomic machines where stores can be observed |
589 // in different order from different observer threads. |
589 // in different order from different observer threads. |
590 ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); |
590 ThreadsList* unverified_threads = Thread::tag_hazard_ptr(threads); |
591 self->set_threads_hazard_ptr(unverified_threads); |
591 self->set_threads_hazard_ptr(unverified_threads); |
592 |
592 |
593 // If _smr_java_thread_list has changed, we have lost a race with |
593 // If _java_thread_list has changed, we have lost a race with |
594 // Threads::add() or Threads::remove() and have to try again. |
594 // Threads::add() or Threads::remove() and have to try again. |
595 if (get_smr_java_thread_list() != threads) { |
595 if (get_java_thread_list() != threads) { |
596 continue; |
596 continue; |
597 } |
597 } |
598 |
598 |
599 // We try to remove the tag which will verify the hazard ptr as |
599 // We try to remove the tag which will verify the hazard ptr as |
600 // being stable. This exchange can race with a scanning thread |
600 // being stable. This exchange can race with a scanning thread |
632 |
632 |
633 NestedThreadsList* node; |
633 NestedThreadsList* node; |
634 { |
634 { |
635 // Only grab the Threads_lock if we don't already own it. |
635 // Only grab the Threads_lock if we don't already own it. |
636 MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); |
636 MutexLockerEx ml(Threads_lock->owned_by_self() ? NULL : Threads_lock); |
637 node = new NestedThreadsList(get_smr_java_thread_list()); |
637 node = new NestedThreadsList(get_java_thread_list()); |
638 // We insert at the front of the list to match up with the delete |
638 // We insert at the front of the list to match up with the delete |
639 // in release_stable_list(). |
639 // in release_stable_list(). |
640 node->set_next(self->get_nested_threads_hazard_ptr()); |
640 node->set_next(self->get_nested_threads_hazard_ptr()); |
641 self->set_nested_threads_hazard_ptr(node); |
641 self->set_nested_threads_hazard_ptr(node); |
642 if (EnableThreadSMRStatistics) { |
642 if (EnableThreadSMRStatistics) { |
643 self->inc_nested_threads_hazard_ptr_cnt(); |
643 self->inc_nested_threads_hazard_ptr_cnt(); |
644 if (self->nested_threads_hazard_ptr_cnt() > _smr_nested_thread_list_max) { |
644 if (self->nested_threads_hazard_ptr_cnt() > _nested_thread_list_max) { |
645 _smr_nested_thread_list_max = self->nested_threads_hazard_ptr_cnt(); |
645 _nested_thread_list_max = self->nested_threads_hazard_ptr_cnt(); |
646 } |
646 } |
647 } |
647 } |
648 } |
648 } |
649 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())); |
649 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())); |
650 |
650 |
651 return node->t_list(); |
651 return node->t_list(); |
652 } |
652 } |
653 |
653 |
654 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
654 void ThreadsSMRSupport::add_thread(JavaThread *thread){ |
655 ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread); |
655 ThreadsList *new_list = ThreadsList::add_thread(ThreadsSMRSupport::get_java_thread_list(), thread); |
656 if (EnableThreadSMRStatistics) { |
656 if (EnableThreadSMRStatistics) { |
657 ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt(); |
657 ThreadsSMRSupport::inc_java_thread_list_alloc_cnt(); |
658 ThreadsSMRSupport::update_smr_java_thread_list_max(new_list->length()); |
658 ThreadsSMRSupport::update_java_thread_list_max(new_list->length()); |
659 } |
659 } |
660 // Initial _smr_java_thread_list will not generate a "Threads::add" mesg. |
660 // Initial _java_thread_list will not generate a "Threads::add" mesg. |
661 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
661 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::add: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
662 |
662 |
663 ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list); |
663 ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list); |
664 ThreadsSMRSupport::smr_free_list(old_list); |
664 ThreadsSMRSupport::free_list(old_list); |
665 } |
665 } |
666 |
666 |
667 // set_smr_delete_notify() and clear_smr_delete_notify() are called |
667 // set_delete_notify() and clear_delete_notify() are called |
668 // under the protection of the smr_delete_lock, but we also use an |
668 // under the protection of the delete_lock, but we also use an |
669 // Atomic operation to ensure the memory update is seen earlier than |
669 // Atomic operation to ensure the memory update is seen earlier than |
670 // when the smr_delete_lock is dropped. |
670 // when the delete_lock is dropped. |
671 // |
671 // |
672 void ThreadsSMRSupport::clear_smr_delete_notify() { |
672 void ThreadsSMRSupport::clear_delete_notify() { |
673 Atomic::dec(&_smr_delete_notify); |
673 Atomic::dec(&_delete_notify); |
674 } |
674 } |
675 |
675 |
676 // Return true if the specified JavaThread is protected by a hazard |
676 bool ThreadsSMRSupport::delete_notify() { |
677 // pointer (ThreadsList reference). Otherwise, returns false. |
677 // Use load_acquire() in order to see any updates to _delete_notify |
678 // |
678 // earlier than when delete_lock is grabbed. |
679 bool ThreadsSMRSupport::is_a_protected_JavaThread(JavaThread *thread) { |
679 return (OrderAccess::load_acquire(&_delete_notify) != 0); |
|
680 } |
|
681 |
|
682 // Safely free a ThreadsList after a Threads::add() or Threads::remove(). |
|
683 // The specified ThreadsList may not get deleted during this call if it |
|
684 // is still in-use (referenced by a hazard ptr). Other ThreadsLists |
|
685 // in the chain may get deleted by this call if they are no longer in-use. |
|
686 void ThreadsSMRSupport::free_list(ThreadsList* threads) { |
680 assert_locked_or_safepoint(Threads_lock); |
687 assert_locked_or_safepoint(Threads_lock); |
681 |
688 |
682 // Hash table size should be first power of two higher than twice |
689 threads->set_next_list(_to_delete_list); |
683 // the length of the Threads list. |
690 _to_delete_list = threads; |
684 int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1; |
691 if (EnableThreadSMRStatistics) { |
|
692 _to_delete_list_cnt++; |
|
693 if (_to_delete_list_cnt > _to_delete_list_max) { |
|
694 _to_delete_list_max = _to_delete_list_cnt; |
|
695 } |
|
696 } |
|
697 |
|
698 // Hash table size should be first power of two higher than twice the length of the ThreadsList |
|
699 int hash_table_size = MIN2((int)get_java_thread_list()->length(), 32) << 1; |
685 hash_table_size--; |
700 hash_table_size--; |
686 hash_table_size |= hash_table_size >> 1; |
701 hash_table_size |= hash_table_size >> 1; |
687 hash_table_size |= hash_table_size >> 2; |
702 hash_table_size |= hash_table_size >> 2; |
688 hash_table_size |= hash_table_size >> 4; |
703 hash_table_size |= hash_table_size >> 4; |
689 hash_table_size |= hash_table_size >> 8; |
704 hash_table_size |= hash_table_size >> 8; |
690 hash_table_size |= hash_table_size >> 16; |
705 hash_table_size |= hash_table_size >> 16; |
691 hash_table_size++; |
706 hash_table_size++; |
692 |
707 |
|
708 // Gather a hash table of the current hazard ptrs: |
|
709 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
|
710 ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); |
|
711 Threads::threads_do(&scan_cl); |
|
712 |
|
713 // Walk through the linked list of pending freeable ThreadsLists |
|
714 // and free the ones that are not referenced from hazard ptrs. |
|
715 ThreadsList* current = _to_delete_list; |
|
716 ThreadsList* prev = NULL; |
|
717 ThreadsList* next = NULL; |
|
718 bool threads_is_freed = false; |
|
719 while (current != NULL) { |
|
720 next = current->next_list(); |
|
721 if (!scan_table->has_entry((void*)current)) { |
|
722 // This ThreadsList is not referenced by a hazard ptr. |
|
723 if (prev != NULL) { |
|
724 prev->set_next_list(next); |
|
725 } |
|
726 if (_to_delete_list == current) { |
|
727 _to_delete_list = next; |
|
728 } |
|
729 |
|
730 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current)); |
|
731 if (current == threads) threads_is_freed = true; |
|
732 delete current; |
|
733 if (EnableThreadSMRStatistics) { |
|
734 _java_thread_list_free_cnt++; |
|
735 _to_delete_list_cnt--; |
|
736 } |
|
737 } else { |
|
738 prev = current; |
|
739 } |
|
740 current = next; |
|
741 } |
|
742 |
|
743 if (!threads_is_freed) { |
|
744 // Only report "is not freed" on the original call to |
|
745 // free_list() for this ThreadsList. |
|
746 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads)); |
|
747 } |
|
748 |
|
749 delete scan_table; |
|
750 } |
|
751 |
|
752 // Return true if the specified JavaThread is protected by a hazard |
|
753 // pointer (ThreadsList reference). Otherwise, returns false. |
|
754 // |
|
755 bool ThreadsSMRSupport::is_a_protected_JavaThread(JavaThread *thread) { |
|
756 assert_locked_or_safepoint(Threads_lock); |
|
757 |
|
758 // Hash table size should be first power of two higher than twice |
|
759 // the length of the Threads list. |
|
760 int hash_table_size = MIN2((int)get_java_thread_list()->length(), 32) << 1; |
|
761 hash_table_size--; |
|
762 hash_table_size |= hash_table_size >> 1; |
|
763 hash_table_size |= hash_table_size >> 2; |
|
764 hash_table_size |= hash_table_size >> 4; |
|
765 hash_table_size |= hash_table_size >> 8; |
|
766 hash_table_size |= hash_table_size >> 16; |
|
767 hash_table_size++; |
|
768 |
693 // Gather a hash table of the JavaThreads indirectly referenced by |
769 // Gather a hash table of the JavaThreads indirectly referenced by |
694 // hazard ptrs. |
770 // hazard ptrs. |
695 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
771 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
696 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
772 ScanHazardPtrGatherProtectedThreadsClosure scan_cl(scan_table); |
697 Threads::threads_do(&scan_cl); |
773 Threads::threads_do(&scan_cl); |
770 self->dec_nested_threads_hazard_ptr_cnt(); |
846 self->dec_nested_threads_hazard_ptr_cnt(); |
771 } |
847 } |
772 } |
848 } |
773 |
849 |
774 // An exiting thread might be waiting in smr_delete(); we need to |
850 // An exiting thread might be waiting in smr_delete(); we need to |
775 // check with smr_delete_lock to be sure. |
851 // check with delete_lock to be sure. |
776 release_stable_list_wake_up((char *) "nested hazard ptr"); |
852 release_stable_list_wake_up((char *) "nested hazard ptr"); |
777 |
853 |
778 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())); |
854 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())); |
779 |
855 |
780 delete node; |
856 delete node; |
781 } |
857 } |
782 |
858 |
783 // Wake up portion of the release stable ThreadsList protocol; |
859 // Wake up portion of the release stable ThreadsList protocol; |
784 // uses the smr_delete_lock(). |
860 // uses the delete_lock(). |
785 // |
861 // |
786 void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) { |
862 void ThreadsSMRSupport::release_stable_list_wake_up(char *log_str) { |
787 assert(log_str != NULL, "sanity check"); |
863 assert(log_str != NULL, "sanity check"); |
788 |
864 |
789 // Note: smr_delete_lock is held in smr_delete() for the entire |
865 // Note: delete_lock is held in smr_delete() for the entire |
790 // hazard ptr search so that we do not lose this notify() if |
866 // hazard ptr search so that we do not lose this notify() if |
791 // the exiting thread has to wait. That code path also holds |
867 // the exiting thread has to wait. That code path also holds |
792 // Threads_lock (which was grabbed before smr_delete_lock) so that |
868 // Threads_lock (which was grabbed before delete_lock) so that |
793 // threads_do() can be called. This means the system can't start a |
869 // threads_do() can be called. This means the system can't start a |
794 // safepoint which means this thread can't take too long to get to |
870 // safepoint which means this thread can't take too long to get to |
795 // a safepoint because of being blocked on smr_delete_lock. |
871 // a safepoint because of being blocked on delete_lock. |
796 // |
872 // |
797 MonitorLockerEx ml(ThreadsSMRSupport::smr_delete_lock(), Monitor::_no_safepoint_check_flag); |
873 MonitorLockerEx ml(ThreadsSMRSupport::delete_lock(), Monitor::_no_safepoint_check_flag); |
798 if (ThreadsSMRSupport::smr_delete_notify()) { |
874 if (ThreadsSMRSupport::delete_notify()) { |
799 // Notify any exiting JavaThreads that are waiting in smr_delete() |
875 // Notify any exiting JavaThreads that are waiting in smr_delete() |
800 // that we've released a ThreadsList. |
876 // that we've released a ThreadsList. |
801 ml.notify_all(); |
877 ml.notify_all(); |
802 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list notified %s", os::current_thread_id(), log_str); |
878 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::release_stable_list notified %s", os::current_thread_id(), log_str); |
803 } |
879 } |
804 } |
880 } |
805 |
881 |
806 void ThreadsSMRSupport::remove_thread(JavaThread *thread) { |
882 void ThreadsSMRSupport::remove_thread(JavaThread *thread) { |
807 ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_smr_java_thread_list(), thread); |
883 ThreadsList *new_list = ThreadsList::remove_thread(ThreadsSMRSupport::get_java_thread_list(), thread); |
808 if (EnableThreadSMRStatistics) { |
884 if (EnableThreadSMRStatistics) { |
809 ThreadsSMRSupport::inc_smr_java_thread_list_alloc_cnt(); |
885 ThreadsSMRSupport::inc_java_thread_list_alloc_cnt(); |
810 // This list is smaller so no need to check for a "longest" update. |
886 // This list is smaller so no need to check for a "longest" update. |
811 } |
887 } |
812 |
888 |
813 // Final _smr_java_thread_list will not generate a "Threads::remove" mesg. |
889 // Final _java_thread_list will not generate a "Threads::remove" mesg. |
814 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
890 log_debug(thread, smr)("tid=" UINTX_FORMAT ": Threads::remove: new ThreadsList=" INTPTR_FORMAT, os::current_thread_id(), p2i(new_list)); |
815 |
891 |
816 ThreadsList *old_list = ThreadsSMRSupport::xchg_smr_java_thread_list(new_list); |
892 ThreadsList *old_list = ThreadsSMRSupport::xchg_java_thread_list(new_list); |
817 ThreadsSMRSupport::smr_free_list(old_list); |
893 ThreadsSMRSupport::free_list(old_list); |
818 } |
894 } |
819 |
895 |
820 // See note for clear_smr_delete_notify(). |
896 // See note for clear_delete_notify(). |
821 // |
897 // |
822 void ThreadsSMRSupport::set_smr_delete_notify() { |
898 void ThreadsSMRSupport::set_delete_notify() { |
823 Atomic::inc(&_smr_delete_notify); |
899 Atomic::inc(&_delete_notify); |
824 } |
900 } |
825 |
901 |
826 // Safely delete a JavaThread when it is no longer in use by a |
902 // Safely delete a JavaThread when it is no longer in use by a |
827 // ThreadsListHandle. |
903 // ThreadsListHandle. |
828 // |
904 // |
891 |
967 |
892 delete thread; |
968 delete thread; |
893 if (EnableThreadSMRStatistics) { |
969 if (EnableThreadSMRStatistics) { |
894 timer.stop(); |
970 timer.stop(); |
895 uint millis = (uint)timer.milliseconds(); |
971 uint millis = (uint)timer.milliseconds(); |
896 ThreadsSMRSupport::inc_smr_deleted_thread_cnt(); |
972 ThreadsSMRSupport::inc_deleted_thread_cnt(); |
897 ThreadsSMRSupport::add_smr_deleted_thread_times(millis); |
973 ThreadsSMRSupport::add_deleted_thread_times(millis); |
898 ThreadsSMRSupport::update_smr_deleted_thread_time_max(millis); |
974 ThreadsSMRSupport::update_deleted_thread_time_max(millis); |
899 } |
975 } |
900 |
976 |
901 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); |
977 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_delete: thread=" INTPTR_FORMAT " is deleted.", os::current_thread_id(), p2i(thread)); |
902 } |
978 } |
903 |
979 |
904 bool ThreadsSMRSupport::smr_delete_notify() { |
|
905 // Use load_acquire() in order to see any updates to _smr_delete_notify |
|
906 // earlier than when smr_delete_lock is grabbed. |
|
907 return (OrderAccess::load_acquire(&_smr_delete_notify) != 0); |
|
908 } |
|
909 |
|
910 // Safely free a ThreadsList after a Threads::add() or Threads::remove(). |
|
911 // The specified ThreadsList may not get deleted during this call if it |
|
912 // is still in-use (referenced by a hazard ptr). Other ThreadsLists |
|
913 // in the chain may get deleted by this call if they are no longer in-use. |
|
914 void ThreadsSMRSupport::smr_free_list(ThreadsList* threads) { |
|
915 assert_locked_or_safepoint(Threads_lock); |
|
916 |
|
917 threads->set_next_list(_smr_to_delete_list); |
|
918 _smr_to_delete_list = threads; |
|
919 if (EnableThreadSMRStatistics) { |
|
920 _smr_to_delete_list_cnt++; |
|
921 if (_smr_to_delete_list_cnt > _smr_to_delete_list_max) { |
|
922 _smr_to_delete_list_max = _smr_to_delete_list_cnt; |
|
923 } |
|
924 } |
|
925 |
|
926 // Hash table size should be first power of two higher than twice the length of the ThreadsList |
|
927 int hash_table_size = MIN2((int)get_smr_java_thread_list()->length(), 32) << 1; |
|
928 hash_table_size--; |
|
929 hash_table_size |= hash_table_size >> 1; |
|
930 hash_table_size |= hash_table_size >> 2; |
|
931 hash_table_size |= hash_table_size >> 4; |
|
932 hash_table_size |= hash_table_size >> 8; |
|
933 hash_table_size |= hash_table_size >> 16; |
|
934 hash_table_size++; |
|
935 |
|
936 // Gather a hash table of the current hazard ptrs: |
|
937 ThreadScanHashtable *scan_table = new ThreadScanHashtable(hash_table_size); |
|
938 ScanHazardPtrGatherThreadsListClosure scan_cl(scan_table); |
|
939 Threads::threads_do(&scan_cl); |
|
940 |
|
941 // Walk through the linked list of pending freeable ThreadsLists |
|
942 // and free the ones that are not referenced from hazard ptrs. |
|
943 ThreadsList* current = _smr_to_delete_list; |
|
944 ThreadsList* prev = NULL; |
|
945 ThreadsList* next = NULL; |
|
946 bool threads_is_freed = false; |
|
947 while (current != NULL) { |
|
948 next = current->next_list(); |
|
949 if (!scan_table->has_entry((void*)current)) { |
|
950 // This ThreadsList is not referenced by a hazard ptr. |
|
951 if (prev != NULL) { |
|
952 prev->set_next_list(next); |
|
953 } |
|
954 if (_smr_to_delete_list == current) { |
|
955 _smr_to_delete_list = next; |
|
956 } |
|
957 |
|
958 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is freed.", os::current_thread_id(), p2i(current)); |
|
959 if (current == threads) threads_is_freed = true; |
|
960 delete current; |
|
961 if (EnableThreadSMRStatistics) { |
|
962 _smr_java_thread_list_free_cnt++; |
|
963 _smr_to_delete_list_cnt--; |
|
964 } |
|
965 } else { |
|
966 prev = current; |
|
967 } |
|
968 current = next; |
|
969 } |
|
970 |
|
971 if (!threads_is_freed) { |
|
972 // Only report "is not freed" on the original call to |
|
973 // smr_free_list() for this ThreadsList. |
|
974 log_debug(thread, smr)("tid=" UINTX_FORMAT ": ThreadsSMRSupport::smr_free_list: threads=" INTPTR_FORMAT " is not freed.", os::current_thread_id(), p2i(threads)); |
|
975 } |
|
976 |
|
977 delete scan_table; |
|
978 } |
|
979 |
|
980 |
980 |
981 // Debug, logging, and printing stuff at the end: |
981 // Debug, logging, and printing stuff at the end: |
982 |
982 |
983 // Log Threads class SMR info. |
983 // Log Threads class SMR info. |
984 void ThreadsSMRSupport::log_smr_statistics() { |
984 void ThreadsSMRSupport::log_statistics() { |
985 LogTarget(Info, thread, smr) log; |
985 LogTarget(Info, thread, smr) log; |
986 if (log.is_enabled()) { |
986 if (log.is_enabled()) { |
987 LogStream out(log); |
987 LogStream out(log); |
988 print_smr_info_on(&out); |
988 print_info_on(&out); |
989 } |
989 } |
990 } |
990 } |
991 |
991 |
992 // Print Threads class SMR info. |
992 // Print Threads class SMR info. |
993 void ThreadsSMRSupport::print_smr_info_on(outputStream* st) { |
993 void ThreadsSMRSupport::print_info_on(outputStream* st) { |
994 // Only grab the Threads_lock if we don't already own it |
994 // Only grab the Threads_lock if we don't already own it |
995 // and if we are not reporting an error. |
995 // and if we are not reporting an error. |
996 MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock); |
996 MutexLockerEx ml((Threads_lock->owned_by_self() || VMError::is_error_reported()) ? NULL : Threads_lock); |
997 |
997 |
998 st->print_cr("Threads class SMR info:"); |
998 st->print_cr("Threads class SMR info:"); |
999 st->print_cr("_smr_java_thread_list=" INTPTR_FORMAT ", length=%u, " |
999 st->print_cr("_java_thread_list=" INTPTR_FORMAT ", length=%u, " |
1000 "elements={", p2i(_smr_java_thread_list), |
1000 "elements={", p2i(_java_thread_list), |
1001 _smr_java_thread_list->length()); |
1001 _java_thread_list->length()); |
1002 print_smr_info_elements_on(st, _smr_java_thread_list); |
1002 print_info_elements_on(st, _java_thread_list); |
1003 st->print_cr("}"); |
1003 st->print_cr("}"); |
1004 if (_smr_to_delete_list != NULL) { |
1004 if (_to_delete_list != NULL) { |
1005 st->print_cr("_smr_to_delete_list=" INTPTR_FORMAT ", length=%u, " |
1005 st->print_cr("_to_delete_list=" INTPTR_FORMAT ", length=%u, " |
1006 "elements={", p2i(_smr_to_delete_list), |
1006 "elements={", p2i(_to_delete_list), |
1007 _smr_to_delete_list->length()); |
1007 _to_delete_list->length()); |
1008 print_smr_info_elements_on(st, _smr_to_delete_list); |
1008 print_info_elements_on(st, _to_delete_list); |
1009 st->print_cr("}"); |
1009 st->print_cr("}"); |
1010 for (ThreadsList *t_list = _smr_to_delete_list->next_list(); |
1010 for (ThreadsList *t_list = _to_delete_list->next_list(); |
1011 t_list != NULL; t_list = t_list->next_list()) { |
1011 t_list != NULL; t_list = t_list->next_list()) { |
1012 st->print("next-> " INTPTR_FORMAT ", length=%u, " |
1012 st->print("next-> " INTPTR_FORMAT ", length=%u, " |
1013 "elements={", p2i(t_list), t_list->length()); |
1013 "elements={", p2i(t_list), t_list->length()); |
1014 print_smr_info_elements_on(st, t_list); |
1014 print_info_elements_on(st, t_list); |
1015 st->print_cr("}"); |
1015 st->print_cr("}"); |
1016 } |
1016 } |
1017 } |
1017 } |
1018 if (!EnableThreadSMRStatistics) { |
1018 if (!EnableThreadSMRStatistics) { |
1019 return; |
1019 return; |
1020 } |
1020 } |
1021 st->print_cr("_smr_java_thread_list_alloc_cnt=" UINT64_FORMAT "," |
1021 st->print_cr("_java_thread_list_alloc_cnt=" UINT64_FORMAT "," |
1022 "_smr_java_thread_list_free_cnt=" UINT64_FORMAT "," |
1022 "_java_thread_list_free_cnt=" UINT64_FORMAT "," |
1023 "_smr_java_thread_list_max=%u, " |
1023 "_java_thread_list_max=%u, " |
1024 "_smr_nested_thread_list_max=%u", |
1024 "_nested_thread_list_max=%u", |
1025 _smr_java_thread_list_alloc_cnt, |
1025 _java_thread_list_alloc_cnt, |
1026 _smr_java_thread_list_free_cnt, |
1026 _java_thread_list_free_cnt, |
1027 _smr_java_thread_list_max, |
1027 _java_thread_list_max, |
1028 _smr_nested_thread_list_max); |
1028 _nested_thread_list_max); |
1029 if (_smr_tlh_cnt > 0) { |
1029 if (_tlh_cnt > 0) { |
1030 st->print_cr("_smr_tlh_cnt=%u" |
1030 st->print_cr("_tlh_cnt=%u" |
1031 ", _smr_tlh_times=%u" |
1031 ", _tlh_times=%u" |
1032 ", avg_smr_tlh_time=%0.2f" |
1032 ", avg_tlh_time=%0.2f" |
1033 ", _smr_tlh_time_max=%u", |
1033 ", _tlh_time_max=%u", |
1034 _smr_tlh_cnt, _smr_tlh_times, |
1034 _tlh_cnt, _tlh_times, |
1035 ((double) _smr_tlh_times / _smr_tlh_cnt), |
1035 ((double) _tlh_times / _tlh_cnt), |
1036 _smr_tlh_time_max); |
1036 _tlh_time_max); |
1037 } |
1037 } |
1038 if (_smr_deleted_thread_cnt > 0) { |
1038 if (_deleted_thread_cnt > 0) { |
1039 st->print_cr("_smr_deleted_thread_cnt=%u" |
1039 st->print_cr("_deleted_thread_cnt=%u" |
1040 ", _smr_deleted_thread_times=%u" |
1040 ", _deleted_thread_times=%u" |
1041 ", avg_smr_deleted_thread_time=%0.2f" |
1041 ", avg_deleted_thread_time=%0.2f" |
1042 ", _smr_deleted_thread_time_max=%u", |
1042 ", _deleted_thread_time_max=%u", |
1043 _smr_deleted_thread_cnt, _smr_deleted_thread_times, |
1043 _deleted_thread_cnt, _deleted_thread_times, |
1044 ((double) _smr_deleted_thread_times / _smr_deleted_thread_cnt), |
1044 ((double) _deleted_thread_times / _deleted_thread_cnt), |
1045 _smr_deleted_thread_time_max); |
1045 _deleted_thread_time_max); |
1046 } |
1046 } |
1047 st->print_cr("_smr_delete_lock_wait_cnt=%u, _smr_delete_lock_wait_max=%u", |
1047 st->print_cr("_delete_lock_wait_cnt=%u, _delete_lock_wait_max=%u", |
1048 _smr_delete_lock_wait_cnt, _smr_delete_lock_wait_max); |
1048 _delete_lock_wait_cnt, _delete_lock_wait_max); |
1049 st->print_cr("_smr_to_delete_list_cnt=%u, _smr_to_delete_list_max=%u", |
1049 st->print_cr("_to_delete_list_cnt=%u, _to_delete_list_max=%u", |
1050 _smr_to_delete_list_cnt, _smr_to_delete_list_max); |
1050 _to_delete_list_cnt, _to_delete_list_max); |
1051 } |
1051 } |
1052 |
1052 |
1053 // Print ThreadsList elements (4 per line). |
1053 // Print ThreadsList elements (4 per line). |
1054 void ThreadsSMRSupport::print_smr_info_elements_on(outputStream* st, |
1054 void ThreadsSMRSupport::print_info_elements_on(outputStream* st, ThreadsList* t_list) { |
1055 ThreadsList* t_list) { |
|
1056 uint cnt = 0; |
1055 uint cnt = 0; |
1057 JavaThreadIterator jti(t_list); |
1056 JavaThreadIterator jti(t_list); |
1058 for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) { |
1057 for (JavaThread *jt = jti.first(); jt != NULL; jt = jti.next()) { |
1059 st->print(INTPTR_FORMAT, p2i(jt)); |
1058 st->print(INTPTR_FORMAT, p2i(jt)); |
1060 if (cnt < t_list->length() - 1) { |
1059 if (cnt < t_list->length() - 1) { |