void ConcurrentG1Refine::reset_threshold_step() { if (FLAG_IS_DEFAULT(G1ConcRefinementThresholdStep)) { _thread_threshold_step = (yellow_zone() - green_zone()) / (worker_thread_num() + 1); } else { _thread_threshold_step = G1ConcRefinementThresholdStep; } }
void ConcurrentG1Refine::adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms) { DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); if (G1UseAdaptiveConcRefinement) { update_zones(update_rs_time, update_rs_processed_buffers, goal_ms); update_thread_thresholds(); // Change the barrier params if (_n_worker_threads == 0) { // Disable dcqs notification when there are no threads to notify. dcqs.set_process_completed_threshold(INT_MAX); } else { // Worker 0 is the primary; wakeup is via dcqs notification. STATIC_ASSERT(max_yellow_zone <= INT_MAX); size_t activate = _threads[0]->activation_threshold(); dcqs.set_process_completed_threshold((int)activate); } dcqs.set_max_completed_queue((int)red_zone()); } size_t curr_queue_size = dcqs.completed_buffers_num(); if (curr_queue_size >= yellow_zone()) { dcqs.set_completed_queue_padding(curr_queue_size); } else { dcqs.set_completed_queue_padding(0); } dcqs.notify_if_necessary(); }
ConcurrentG1Refine::ConcurrentG1Refine(G1CollectedHeap* g1h, CardTableEntryClosure* refine_closure) : _threads(NULL), _n_threads(0), _hot_card_cache(g1h) { // Ergomonically select initial concurrent refinement parameters if (FLAG_IS_DEFAULT(G1ConcRefinementGreenZone)) { FLAG_SET_DEFAULT(G1ConcRefinementGreenZone, MAX2<int>(ParallelGCThreads, 1)); } set_green_zone(G1ConcRefinementGreenZone); if (FLAG_IS_DEFAULT(G1ConcRefinementYellowZone)) { FLAG_SET_DEFAULT(G1ConcRefinementYellowZone, green_zone() * 3); } set_yellow_zone(MAX2<int>(G1ConcRefinementYellowZone, green_zone())); if (FLAG_IS_DEFAULT(G1ConcRefinementRedZone)) { FLAG_SET_DEFAULT(G1ConcRefinementRedZone, yellow_zone() * 2); } set_red_zone(MAX2<int>(G1ConcRefinementRedZone, yellow_zone())); _n_worker_threads = thread_num(); // We need one extra thread to do the young gen rset size sampling. _n_threads = _n_worker_threads + 1; reset_threshold_step(); _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads, mtGC); uint worker_id_offset = DirtyCardQueueSet::num_par_ids(); ConcurrentG1RefineThread *next = NULL; for (uint i = _n_threads - 1; i != UINT_MAX; i--) { ConcurrentG1RefineThread* t = new ConcurrentG1RefineThread(this, next, refine_closure, worker_id_offset, i); assert(t != NULL, "Conc refine should have been created"); if (t->osthread() == NULL) { vm_shutdown_during_initialization("Could not create ConcurrentG1RefineThread"); } assert(t->cg1r() == this, "Conc refine thread should refer to this"); _threads[i] = t; next = t; } }