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++) { |