Mercurial > hg > graal-jvmci-8
comparison src/share/vm/utilities/workgroup.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 | 92da084fefc9 |
children | 441e946dc1af |
comparison
equal
deleted
inserted
replaced
4094:3a298e04d914 | 4095:bca17e38de00 |
---|---|
55 WorkGang::WorkGang(const char* name, | 55 WorkGang::WorkGang(const char* name, |
56 int workers, | 56 int workers, |
57 bool are_GC_task_threads, | 57 bool are_GC_task_threads, |
58 bool are_ConcurrentGC_threads) : | 58 bool are_ConcurrentGC_threads) : |
59 AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) { | 59 AbstractWorkGang(name, are_GC_task_threads, are_ConcurrentGC_threads) { |
60 // Save arguments. | |
61 _total_workers = workers; | 60 _total_workers = workers; |
62 } | 61 } |
63 | 62 |
64 GangWorker* WorkGang::allocate_worker(int which) { | 63 GangWorker* WorkGang::allocate_worker(int which) { |
65 GangWorker* new_worker = new GangWorker(this, which); | 64 GangWorker* new_worker = new GangWorker(this, which); |
125 assert(result != NULL, "Indexing to null worker"); | 124 assert(result != NULL, "Indexing to null worker"); |
126 return result; | 125 return result; |
127 } | 126 } |
128 | 127 |
129 void WorkGang::run_task(AbstractGangTask* task) { | 128 void WorkGang::run_task(AbstractGangTask* task) { |
129 run_task(task, total_workers()); | |
130 } | |
131 | |
132 void WorkGang::run_task(AbstractGangTask* task, uint no_of_parallel_workers) { | |
133 task->set_for_termination(no_of_parallel_workers); | |
134 | |
130 // This thread is executed by the VM thread which does not block | 135 // This thread is executed by the VM thread which does not block |
131 // on ordinary MutexLocker's. | 136 // on ordinary MutexLocker's. |
132 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); | 137 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); |
133 if (TraceWorkGang) { | 138 if (TraceWorkGang) { |
134 tty->print_cr("Running work gang %s task %s", name(), task->name()); | 139 tty->print_cr("Running work gang %s task %s", name(), task->name()); |
141 _started_workers = 0; | 146 _started_workers = 0; |
142 _finished_workers = 0; | 147 _finished_workers = 0; |
143 // Tell the workers to get to work. | 148 // Tell the workers to get to work. |
144 monitor()->notify_all(); | 149 monitor()->notify_all(); |
145 // Wait for them to be finished | 150 // Wait for them to be finished |
146 while (finished_workers() < total_workers()) { | 151 while (finished_workers() < (int) no_of_parallel_workers) { |
147 if (TraceWorkGang) { | 152 if (TraceWorkGang) { |
148 tty->print_cr("Waiting in work gang %s: %d/%d finished sequence %d", | 153 tty->print_cr("Waiting in work gang %s: %d/%d finished sequence %d", |
149 name(), finished_workers(), total_workers(), | 154 name(), finished_workers(), no_of_parallel_workers, |
150 _sequence_number); | 155 _sequence_number); |
151 } | 156 } |
152 monitor()->wait(/* no_safepoint_check */ true); | 157 monitor()->wait(/* no_safepoint_check */ true); |
153 } | 158 } |
154 _task = NULL; | 159 _task = NULL; |
155 if (TraceWorkGang) { | 160 if (TraceWorkGang) { |
156 tty->print_cr("/nFinished work gang %s: %d/%d sequence %d", | 161 tty->print_cr("\nFinished work gang %s: %d/%d sequence %d", |
157 name(), finished_workers(), total_workers(), | 162 name(), finished_workers(), no_of_parallel_workers, |
158 _sequence_number); | 163 _sequence_number); |
159 } | 164 Thread* me = Thread::current(); |
165 tty->print_cr(" T: 0x%x VM_thread: %d", me, me->is_VM_thread()); | |
166 } | |
167 } | |
168 | |
169 void FlexibleWorkGang::run_task(AbstractGangTask* task) { | |
170 // If active_workers() is passed, _finished_workers | |
171 // must only be incremented for workers that find non_null | |
172 // work (as opposed to all those that just check that the | |
173 // task is not null). | |
174 WorkGang::run_task(task, (uint) active_workers()); | |
160 } | 175 } |
161 | 176 |
162 void AbstractWorkGang::stop() { | 177 void AbstractWorkGang::stop() { |
163 // Tell all workers to terminate, then wait for them to become inactive. | 178 // Tell all workers to terminate, then wait for them to become inactive. |
164 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); | 179 MutexLockerEx ml(monitor(), Mutex::_no_safepoint_check_flag); |
166 tty->print_cr("Stopping work gang %s task %s", name(), task()->name()); | 181 tty->print_cr("Stopping work gang %s task %s", name(), task()->name()); |
167 } | 182 } |
168 _task = NULL; | 183 _task = NULL; |
169 _terminate = true; | 184 _terminate = true; |
170 monitor()->notify_all(); | 185 monitor()->notify_all(); |
171 while (finished_workers() < total_workers()) { | 186 while (finished_workers() < active_workers()) { |
172 if (TraceWorkGang) { | 187 if (TraceWorkGang) { |
173 tty->print_cr("Waiting in work gang %s: %d/%d finished", | 188 tty->print_cr("Waiting in work gang %s: %d/%d finished", |
174 name(), finished_workers(), total_workers()); | 189 name(), finished_workers(), active_workers()); |
175 } | 190 } |
176 monitor()->wait(/* no_safepoint_check */ true); | 191 monitor()->wait(/* no_safepoint_check */ true); |
177 } | 192 } |
178 } | 193 } |
179 | 194 |
273 return; | 288 return; |
274 } | 289 } |
275 // Check for new work. | 290 // Check for new work. |
276 if ((data.task() != NULL) && | 291 if ((data.task() != NULL) && |
277 (data.sequence_number() != previous_sequence_number)) { | 292 (data.sequence_number() != previous_sequence_number)) { |
278 gang()->internal_note_start(); | 293 if (gang()->needs_more_workers()) { |
279 gang_monitor->notify_all(); | 294 gang()->internal_note_start(); |
280 part = gang()->started_workers() - 1; | 295 gang_monitor->notify_all(); |
281 break; | 296 part = gang()->started_workers() - 1; |
297 break; | |
298 } | |
282 } | 299 } |
283 // Nothing to do. | 300 // Nothing to do. |
284 gang_monitor->wait(/* no_safepoint_check */ true); | 301 gang_monitor->wait(/* no_safepoint_check */ true); |
285 gang()->internal_worker_poll(&data); | 302 gang()->internal_worker_poll(&data); |
286 if (TraceWorkGang) { | 303 if (TraceWorkGang) { |
348 return _name; | 365 return _name; |
349 } | 366 } |
350 | 367 |
351 #endif /* PRODUCT */ | 368 #endif /* PRODUCT */ |
352 | 369 |
370 // FlexibleWorkGang | |
371 | |
372 | |
353 // *** WorkGangBarrierSync | 373 // *** WorkGangBarrierSync |
354 | 374 |
355 WorkGangBarrierSync::WorkGangBarrierSync() | 375 WorkGangBarrierSync::WorkGangBarrierSync() |
356 : _monitor(Mutex::safepoint, "work gang barrier sync", true), | 376 : _monitor(Mutex::safepoint, "work gang barrier sync", true), |
357 _n_workers(0), _n_completed(0), _should_reset(false) { | 377 _n_workers(0), _n_completed(0), _should_reset(false) { |
409 bool SubTasksDone::valid() { | 429 bool SubTasksDone::valid() { |
410 return _tasks != NULL; | 430 return _tasks != NULL; |
411 } | 431 } |
412 | 432 |
413 void SubTasksDone::set_n_threads(int t) { | 433 void SubTasksDone::set_n_threads(int t) { |
414 #ifdef ASSERT | |
415 assert(_claimed == 0 || _threads_completed == _n_threads, | 434 assert(_claimed == 0 || _threads_completed == _n_threads, |
416 "should not be called while tasks are being processed!"); | 435 "should not be called while tasks are being processed!"); |
417 #endif | |
418 _n_threads = (t == 0 ? 1 : t); | 436 _n_threads = (t == 0 ? 1 : t); |
419 } | 437 } |
420 | 438 |
421 void SubTasksDone::clear() { | 439 void SubTasksDone::clear() { |
422 for (int i = 0; i < _n_tasks; i++) { | 440 for (int i = 0; i < _n_tasks; i++) { |