< prev index next >

src/hotspot/share/utilities/concurrentHashTable.inline.hpp

Print this page

        

*** 483,492 **** --- 483,493 ---- } // Publish the deletion. GlobalCounter::write_synchronize(); delete_f(rem_n->value()); Node::destroy_node(rem_n); + _stats_rate.remove(); return true; } template <typename VALUE, typename CONFIG, MEMFLAGS F> template <typename EVALUATE_FUNC, typename DELETE_FUNC>
*** 531,540 **** --- 532,542 ---- write_synchonize_on_visible_epoch(thread); } for (size_t node_it = 0; node_it < nd; node_it++) { del_f(ndel[node_it]->value()); Node::destroy_node(ndel[node_it]); + _stats_rate.remove(); DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } cs_context = GlobalCounter::critical_section_begin(thread); } GlobalCounter::critical_section_end(thread, cs_context);
*** 569,578 **** --- 571,581 ---- } if (dels > 0) { GlobalCounter::write_synchronize(); for (size_t node_it = 0; node_it < dels; node_it++) { Node::destroy_node(ndel[node_it]); + _stats_rate.remove(); DEBUG_ONLY(ndel[node_it] = (Node*)POISON_PTR;) } } }
*** 898,907 **** --- 901,911 ---- Node* first_at_start = bucket->first(); Node* old = get_node(bucket, lookup_f, &clean, &loops); if (old == NULL) { new_node->set_next(first_at_start); if (bucket->cas_first(new_node, first_at_start)) { + _stats_rate.add(); new_node = NULL; ret = true; break; /* leave critical section */ } // CAS failed we must leave critical section and retry.
*** 1006,1015 **** --- 1010,1020 ---- : _new_table(NULL), _log2_size_limit(log2size_limit), _log2_start_size(log2size), _grow_hint(grow_hint), _size_limit_reached(false), _resize_lock_owner(NULL), _invisible_epoch(0) { + _stats_rate = TableRateStatistics(); _resize_lock = new Mutex(Mutex::leaf, "ConcurrentHashTable", false, Monitor::_safepoint_check_never); _table = new InternalTable(log2size); assert(log2size_limit >= log2size, "bad ergo");
*** 1079,1088 **** --- 1084,1094 ---- assert(!bucket->have_redirect() && !bucket->is_locked(), "bad"); Node* new_node = Node::create_node(value, bucket->first()); if (!bucket->cas_first(new_node, bucket->first())) { assert(false, "bad"); } + _stats_rate.add(); return true; } template <typename VALUE, typename CONFIG, MEMFLAGS F> template <typename SCAN_FUNC>
*** 1178,1248 **** lock_resize_lock(thread); do_bulk_delete_locked(thread, eval_f, del_f); unlock_resize_lock(thread); } template <typename VALUE, typename CONFIG, MEMFLAGS F> template <typename VALUE_SIZE_FUNC> ! inline void ConcurrentHashTable<VALUE, CONFIG, F>:: ! statistics_to(Thread* thread, VALUE_SIZE_FUNC& vs_f, ! outputStream* st, const char* table_name) { - NumberSeq summary; - size_t literal_bytes = 0; if (!try_resize_lock(thread)) { ! st->print_cr("statistics unavailable at this moment"); ! return; } InternalTable* table = get_table(); for (size_t bucket_it = 0; bucket_it < table->_size; bucket_it++) { ScopedCS cs(thread, this); size_t count = 0; Bucket* bucket = table->get_bucket(bucket_it); if (bucket->have_redirect() || bucket->is_locked()) { ! continue; } Node* current_node = bucket->first(); while (current_node != NULL) { ++count; literal_bytes += vs_f(current_node->value()); current_node = current_node->next(); } summary.add((double)count); } - double num_buckets = summary.num(); - double num_entries = summary.sum(); - - size_t bucket_bytes = num_buckets * sizeof(Bucket); - size_t entry_bytes = num_entries * sizeof(Node); - size_t total_bytes = literal_bytes + bucket_bytes + entry_bytes; - - size_t bucket_size = (num_buckets <= 0) ? 0 : (bucket_bytes / num_buckets); - size_t entry_size = (num_entries <= 0) ? 0 : (entry_bytes / num_entries); - - st->print_cr("%s statistics:", table_name); - st->print_cr("Number of buckets : %9" PRIuPTR " = %9" PRIuPTR - " bytes, each " SIZE_FORMAT, - (size_t)num_buckets, bucket_bytes, bucket_size); - st->print_cr("Number of entries : %9" PRIuPTR " = %9" PRIuPTR - " bytes, each " SIZE_FORMAT, - (size_t)num_entries, entry_bytes, entry_size); - if (literal_bytes != 0) { - double literal_avg = (num_entries <= 0) ? 0 : (literal_bytes / num_entries); - st->print_cr("Number of literals : %9" PRIuPTR " = %9" PRIuPTR - " bytes, avg %7.3f", - (size_t)num_entries, literal_bytes, literal_avg); - } - st->print_cr("Total footprsize_t : %9s = %9" PRIuPTR " bytes", "" - , total_bytes); - st->print_cr("Average bucket size : %9.3f", summary.avg()); - st->print_cr("Variance of bucket size : %9.3f", summary.variance()); - st->print_cr("Std. dev. of bucket size: %9.3f", summary.sd()); - st->print_cr("Maximum bucket size : %9" PRIuPTR, - (size_t)summary.maximum()); unlock_resize_lock(thread); } template <typename VALUE, typename CONFIG, MEMFLAGS F> inline bool ConcurrentHashTable<VALUE, CONFIG, F>:: try_move_nodes_to(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* to_cht) --- 1184,1240 ---- lock_resize_lock(thread); do_bulk_delete_locked(thread, eval_f, del_f); unlock_resize_lock(thread); } + // Calcuate statistics. Item sizes are calculated with VALUE_SIZE_FUNC. template <typename VALUE, typename CONFIG, MEMFLAGS F> template <typename VALUE_SIZE_FUNC> ! inline TableStatistics ConcurrentHashTable<VALUE, CONFIG, F>:: ! statistics_calculate(Thread* thread, VALUE_SIZE_FUNC& vs_f) { if (!try_resize_lock(thread)) { ! return TableStatistics(); } + NumberSeq summary; + size_t literal_bytes = 0; InternalTable* table = get_table(); for (size_t bucket_it = 0; bucket_it < table->_size; bucket_it++) { ScopedCS cs(thread, this); size_t count = 0; Bucket* bucket = table->get_bucket(bucket_it); if (bucket->have_redirect() || bucket->is_locked()) { ! continue; } Node* current_node = bucket->first(); while (current_node != NULL) { ++count; literal_bytes += vs_f(current_node->value()); current_node = current_node->next(); } summary.add((double)count); } unlock_resize_lock(thread); + + return TableStatistics(_stats_rate, summary, literal_bytes, sizeof(Bucket), sizeof(Node)); + } + + template <typename VALUE, typename CONFIG, MEMFLAGS F> + template <typename VALUE_SIZE_FUNC> + inline void ConcurrentHashTable<VALUE, CONFIG, F>:: + statistics_to(Thread* thread, VALUE_SIZE_FUNC& vs_f, + outputStream* st, const char* table_name) + { + TableStatistics ts = statistics_calculate(thread, vs_f); + if (!ts._owned) { + st->print_cr("statistics unavailable at this moment"); + return; + } + + ts.print(st, table_name); } template <typename VALUE, typename CONFIG, MEMFLAGS F> inline bool ConcurrentHashTable<VALUE, CONFIG, F>:: try_move_nodes_to(Thread* thread, ConcurrentHashTable<VALUE, CONFIG, F>* to_cht)
< prev index next >