117 // Cumulative time in millis to delete ThreadsListHandles. 118 // Impl note: Atomically added to over VM lifetime so use unsigned for more 119 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc 120 // isn't available everywhere (or is it?). 121 volatile uint ThreadsSMRSupport::_tlh_times = 0; 122 123 ThreadsList* ThreadsSMRSupport::_to_delete_list = NULL; 124 125 // # of parallel ThreadsLists on the to-delete list. 126 // Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so 127 // this could be 16-bit, but there is no nice 16-bit _FORMAT support. 128 uint ThreadsSMRSupport::_to_delete_list_cnt = 0; 129 130 // Max # of parallel ThreadsLists on the to-delete list. 131 // Impl note: See _to_delete_list_cnt note. 132 uint ThreadsSMRSupport::_to_delete_list_max = 0; 133 134 // 'inline' functions first so the definitions are before first use: 135 136 inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) { 137 Atomic::add(add_value, &_deleted_thread_times); 138 } 139 140 inline void ThreadsSMRSupport::inc_deleted_thread_cnt() { 141 Atomic::inc(&_deleted_thread_cnt); 142 } 143 144 inline void ThreadsSMRSupport::inc_java_thread_list_alloc_cnt() { 145 _java_thread_list_alloc_cnt++; 146 } 147 148 inline bool ThreadsSMRSupport::is_bootstrap_list(ThreadsList* list) { 149 return list == &_bootstrap_list; 150 } 151 152 inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) { 153 while (true) { 154 uint cur_value = _deleted_thread_time_max; 155 if (new_value <= cur_value) { 156 // No need to update max value so we're done. 157 break; 158 } 159 if (Atomic::cmpxchg(new_value, &_deleted_thread_time_max, cur_value) == cur_value) { 160 // Updated max value so we're done. Otherwise try it all again. 161 break; 162 } 163 } 164 } 165 166 inline void ThreadsSMRSupport::update_java_thread_list_max(uint new_value) { 167 if (new_value > _java_thread_list_max) { 168 _java_thread_list_max = new_value; 169 } 170 } 171 172 inline ThreadsList* ThreadsSMRSupport::xchg_java_thread_list(ThreadsList* new_list) { 173 return (ThreadsList*)Atomic::xchg(new_list, &_java_thread_list); 174 } 175 176 // Hash table of pointers found by a scan. Used for collecting hazard 177 // pointers (ThreadsList references). Also used for collecting JavaThreads 178 // that are indirectly referenced by hazard ptrs. An instance of this 179 // class only contains one type of pointer. 180 // 181 class ThreadScanHashtable : public CHeapObj<mtThread> { 182 private: 183 static bool ptr_equals(void * const& s1, void * const& s2) { 184 return s1 == s2; 185 } 186 187 static unsigned int ptr_hash(void * const& s1) { 188 // 2654435761 = 2^32 * Phi (golden ratio) 189 return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u); 190 } 191 192 int _table_size; 193 // ResourceHashtable SIZE is specified at compile time so our | 117 // Cumulative time in millis to delete ThreadsListHandles. 118 // Impl note: Atomically added to over VM lifetime so use unsigned for more 119 // range. Unsigned 64-bit would be more future proof, but 64-bit atomic inc 120 // isn't available everywhere (or is it?). 121 volatile uint ThreadsSMRSupport::_tlh_times = 0; 122 123 ThreadsList* ThreadsSMRSupport::_to_delete_list = NULL; 124 125 // # of parallel ThreadsLists on the to-delete list. 126 // Impl note: Hard to imagine > 64K ThreadsLists needing to be deleted so 127 // this could be 16-bit, but there is no nice 16-bit _FORMAT support. 128 uint ThreadsSMRSupport::_to_delete_list_cnt = 0; 129 130 // Max # of parallel ThreadsLists on the to-delete list. 131 // Impl note: See _to_delete_list_cnt note. 132 uint ThreadsSMRSupport::_to_delete_list_max = 0; 133 134 // 'inline' functions first so the definitions are before first use: 135 136 inline void ThreadsSMRSupport::add_deleted_thread_times(uint add_value) { 137 Atomic::add(&_deleted_thread_times, add_value); 138 } 139 140 inline void ThreadsSMRSupport::inc_deleted_thread_cnt() { 141 Atomic::inc(&_deleted_thread_cnt); 142 } 143 144 inline void ThreadsSMRSupport::inc_java_thread_list_alloc_cnt() { 145 _java_thread_list_alloc_cnt++; 146 } 147 148 inline bool ThreadsSMRSupport::is_bootstrap_list(ThreadsList* list) { 149 return list == &_bootstrap_list; 150 } 151 152 inline void ThreadsSMRSupport::update_deleted_thread_time_max(uint new_value) { 153 while (true) { 154 uint cur_value = _deleted_thread_time_max; 155 if (new_value <= cur_value) { 156 // No need to update max value so we're done. 157 break; 158 } 159 if (Atomic::cmpxchg(&_deleted_thread_time_max, cur_value, new_value) == cur_value) { 160 // Updated max value so we're done. Otherwise try it all again. 161 break; 162 } 163 } 164 } 165 166 inline void ThreadsSMRSupport::update_java_thread_list_max(uint new_value) { 167 if (new_value > _java_thread_list_max) { 168 _java_thread_list_max = new_value; 169 } 170 } 171 172 inline ThreadsList* ThreadsSMRSupport::xchg_java_thread_list(ThreadsList* new_list) { 173 return (ThreadsList*)Atomic::xchg(&_java_thread_list, new_list); 174 } 175 176 // Hash table of pointers found by a scan. Used for collecting hazard 177 // pointers (ThreadsList references). Also used for collecting JavaThreads 178 // that are indirectly referenced by hazard ptrs. An instance of this 179 // class only contains one type of pointer. 180 // 181 class ThreadScanHashtable : public CHeapObj<mtThread> { 182 private: 183 static bool ptr_equals(void * const& s1, void * const& s2) { 184 return s1 == s2; 185 } 186 187 static unsigned int ptr_hash(void * const& s1) { 188 // 2654435761 = 2^32 * Phi (golden ratio) 189 return (unsigned int)(((uint32_t)(uintptr_t)s1) * 2654435761u); 190 } 191 192 int _table_size; 193 // ResourceHashtable SIZE is specified at compile time so our |