comparison src/share/vm/utilities/yieldingWorkgroup.cpp @ 4095:bca17e38de00

6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads Summary: Select number of GC threads dynamically based on heap usage and number of Java threads Reviewed-by: johnc, ysr, jcoomes
author jmasa
date Tue, 09 Aug 2011 10:16:01 -0700
parents 3be7439273c5
children 441e946dc1af
comparison
equal deleted inserted replaced
4094:3a298e04d914 4095:bca17e38de00
123 int requested_size = new_task->requested_size(); 123 int requested_size = new_task->requested_size();
124 assert(requested_size >= 0, "Should be non-negative"); 124 assert(requested_size >= 0, "Should be non-negative");
125 if (requested_size != 0) { 125 if (requested_size != 0) {
126 _active_workers = MIN2(requested_size, total_workers()); 126 _active_workers = MIN2(requested_size, total_workers());
127 } else { 127 } else {
128 _active_workers = total_workers(); 128 _active_workers = active_workers();
129 } 129 }
130 new_task->set_actual_size(_active_workers); 130 new_task->set_actual_size(_active_workers);
131 new_task->set_for_termination(_active_workers); 131 new_task->set_for_termination(_active_workers);
132 132
133 assert(_started_workers == 0, "Tabula rasa non"); 133 assert(_started_workers == 0, "Tabula rasa non");
146 assert(monitor()->owned_by_self(), "Data race"); 146 assert(monitor()->owned_by_self(), "Data race");
147 // Wait for task to complete or yield 147 // Wait for task to complete or yield
148 for (Status status = yielding_task()->status(); 148 for (Status status = yielding_task()->status();
149 status != COMPLETED && status != YIELDED && status != ABORTED; 149 status != COMPLETED && status != YIELDED && status != ABORTED;
150 status = yielding_task()->status()) { 150 status = yielding_task()->status()) {
151 assert(started_workers() <= total_workers(), "invariant"); 151 assert(started_workers() <= active_workers(), "invariant");
152 assert(finished_workers() <= total_workers(), "invariant"); 152 assert(finished_workers() <= active_workers(), "invariant");
153 assert(yielded_workers() <= total_workers(), "invariant"); 153 assert(yielded_workers() <= active_workers(), "invariant");
154 monitor()->wait(Mutex::_no_safepoint_check_flag); 154 monitor()->wait(Mutex::_no_safepoint_check_flag);
155 } 155 }
156 switch (yielding_task()->status()) { 156 switch (yielding_task()->status()) {
157 case COMPLETED: 157 case COMPLETED:
158 case ABORTED: { 158 case ABORTED: {
159 assert(finished_workers() == total_workers(), "Inconsistent status"); 159 assert(finished_workers() == active_workers(), "Inconsistent status");
160 assert(yielded_workers() == 0, "Invariant"); 160 assert(yielded_workers() == 0, "Invariant");
161 reset(); // for next task; gang<->task binding released 161 reset(); // for next task; gang<->task binding released
162 break; 162 break;
163 } 163 }
164 case YIELDED: { 164 case YIELDED: {
165 assert(yielded_workers() > 0, "Invariant"); 165 assert(yielded_workers() > 0, "Invariant");
166 assert(yielded_workers() + finished_workers() == total_workers(), 166 assert(yielded_workers() + finished_workers() == active_workers(),
167 "Inconsistent counts"); 167 "Inconsistent counts");
168 break; 168 break;
169 } 169 }
170 case ACTIVE: 170 case ACTIVE:
171 case INACTIVE: 171 case INACTIVE:
180 void YieldingFlexibleWorkGang::continue_task( 180 void YieldingFlexibleWorkGang::continue_task(
181 YieldingFlexibleGangTask* gang_task) { 181 YieldingFlexibleGangTask* gang_task) {
182 182
183 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); 183 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
184 assert(task() != NULL && task() == gang_task, "Incorrect usage"); 184 assert(task() != NULL && task() == gang_task, "Incorrect usage");
185 // assert(_active_workers == total_workers(), "For now");
186 assert(_started_workers == _active_workers, "Precondition"); 185 assert(_started_workers == _active_workers, "Precondition");
187 assert(_yielded_workers > 0 && yielding_task()->status() == YIELDED, 186 assert(_yielded_workers > 0 && yielding_task()->status() == YIELDED,
188 "Else why are we calling continue_task()"); 187 "Else why are we calling continue_task()");
189 // Restart the yielded gang workers 188 // Restart the yielded gang workers
190 yielding_task()->set_status(ACTIVE); 189 yielding_task()->set_status(ACTIVE);
200 } 199 }
201 200
202 void YieldingFlexibleWorkGang::yield() { 201 void YieldingFlexibleWorkGang::yield() {
203 assert(task() != NULL, "Inconsistency; should have task binding"); 202 assert(task() != NULL, "Inconsistency; should have task binding");
204 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); 203 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag);
205 assert(yielded_workers() < total_workers(), "Consistency check"); 204 assert(yielded_workers() < active_workers(), "Consistency check");
206 if (yielding_task()->status() == ABORTING) { 205 if (yielding_task()->status() == ABORTING) {
207 // Do not yield; we need to abort as soon as possible 206 // Do not yield; we need to abort as soon as possible
208 // XXX NOTE: This can cause a performance pathology in the 207 // XXX NOTE: This can cause a performance pathology in the
209 // current implementation in Mustang, as of today, and 208 // current implementation in Mustang, as of today, and
210 // pre-Mustang in that as soon as an overflow occurs, 209 // pre-Mustang in that as soon as an overflow occurs,
211 // yields will not be honoured. The right way to proceed 210 // yields will not be honoured. The right way to proceed
212 // of course is to fix bug # TBF, so that abort's cause 211 // of course is to fix bug # TBF, so that abort's cause
213 // us to return at each potential yield point. 212 // us to return at each potential yield point.
214 return; 213 return;
215 } 214 }
216 if (++_yielded_workers + finished_workers() == total_workers()) { 215 if (++_yielded_workers + finished_workers() == active_workers()) {
217 yielding_task()->set_status(YIELDED); 216 yielding_task()->set_status(YIELDED);
218 monitor()->notify_all(); 217 monitor()->notify_all();
219 } else { 218 } else {
220 yielding_task()->set_status(YIELDING); 219 yielding_task()->set_status(YIELDING);
221 } 220 }