359
360 const char* AbstractWorkGang::name() const {
361 return _name;
362 }
363
364 #ifndef PRODUCT
365
366 const char* AbstractGangTask::name() const {
367 return _name;
368 }
369
370 #endif /* PRODUCT */
371
372 // FlexibleWorkGang
373
374
375 // *** WorkGangBarrierSync
376
377 WorkGangBarrierSync::WorkGangBarrierSync()
378 : _monitor(Mutex::safepoint, "work gang barrier sync", true),
379 _n_workers(0), _n_completed(0), _should_reset(false) {
380 }
381
382 WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
383 : _monitor(Mutex::safepoint, name, true),
384 _n_workers(n_workers), _n_completed(0), _should_reset(false) {
385 }
386
387 void WorkGangBarrierSync::set_n_workers(uint n_workers) {
388 _n_workers = n_workers;
389 _n_completed = 0;
390 _should_reset = false;
391 }
392
393 void WorkGangBarrierSync::enter() {
394 MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
395 if (should_reset()) {
396 // The should_reset() was set and we are the first worker to enter
397 // the sync barrier. We will zero the n_completed() count which
398 // effectively resets the barrier.
399 zero_completed();
400 set_should_reset(false);
401 }
402 inc_completed();
403 if (n_completed() == n_workers()) {
404 // At this point we would like to reset the barrier to be ready in
405 // case it is used again. However, we cannot set n_completed() to
406 // 0, even after the notify_all(), given that some other workers
407 // might still be waiting for n_completed() to become ==
408 // n_workers(). So, if we set n_completed() to 0, those workers
409 // will get stuck (as they will wake up, see that n_completed() !=
410 // n_workers() and go back to sleep). Instead, we raise the
411 // should_reset() flag and the barrier will be reset the first
412 // time a worker enters it again.
413 set_should_reset(true);
414 monitor()->notify_all();
415 } else {
416 while (n_completed() != n_workers()) {
417 monitor()->wait(/* no_safepoint_check */ true);
418 }
419 }
420 }
421
422 // SubTasksDone functions.
423
424 SubTasksDone::SubTasksDone(uint n) :
425 _n_tasks(n), _n_threads(1), _tasks(NULL) {
426 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
427 guarantee(_tasks != NULL, "alloc failure");
428 clear();
429 }
430
431 bool SubTasksDone::valid() {
432 return _tasks != NULL;
433 }
434
435 void SubTasksDone::set_n_threads(uint t) {
436 assert(_claimed == 0 || _threads_completed == _n_threads,
437 "should not be called while tasks are being processed!");
438 _n_threads = (t == 0 ? 1 : t);
439 }
|
359
360 const char* AbstractWorkGang::name() const {
361 return _name;
362 }
363
364 #ifndef PRODUCT
365
366 const char* AbstractGangTask::name() const {
367 return _name;
368 }
369
370 #endif /* PRODUCT */
371
372 // FlexibleWorkGang
373
374
375 // *** WorkGangBarrierSync
376
377 WorkGangBarrierSync::WorkGangBarrierSync()
378 : _monitor(Mutex::safepoint, "work gang barrier sync", true),
379 _n_workers(0), _n_completed(0), _should_reset(false), _aborted(false) {
380 }
381
382 WorkGangBarrierSync::WorkGangBarrierSync(uint n_workers, const char* name)
383 : _monitor(Mutex::safepoint, name, true),
384 _n_workers(n_workers), _n_completed(0), _should_reset(false), _aborted(false) {
385 }
386
387 void WorkGangBarrierSync::set_n_workers(uint n_workers) {
388 _n_workers = n_workers;
389 _n_completed = 0;
390 _should_reset = false;
391 _aborted = false;
392 }
393
394 bool WorkGangBarrierSync::enter() {
395 MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
396 if (should_reset()) {
397 // The should_reset() was set and we are the first worker to enter
398 // the sync barrier. We will zero the n_completed() count which
399 // effectively resets the barrier.
400 zero_completed();
401 set_should_reset(false);
402 }
403 inc_completed();
404 if (n_completed() == n_workers()) {
405 // At this point we would like to reset the barrier to be ready in
406 // case it is used again. However, we cannot set n_completed() to
407 // 0, even after the notify_all(), given that some other workers
408 // might still be waiting for n_completed() to become ==
409 // n_workers(). So, if we set n_completed() to 0, those workers
410 // will get stuck (as they will wake up, see that n_completed() !=
411 // n_workers() and go back to sleep). Instead, we raise the
412 // should_reset() flag and the barrier will be reset the first
413 // time a worker enters it again.
414 set_should_reset(true);
415 monitor()->notify_all();
416 } else {
417 while (n_completed() != n_workers() && !aborted()) {
418 monitor()->wait(/* no_safepoint_check */ true);
419 }
420 }
421 return !aborted();
422 }
423
424 void WorkGangBarrierSync::abort() {
425 MutexLockerEx x(monitor(), Mutex::_no_safepoint_check_flag);
426 set_aborted();
427 monitor()->notify_all();
428 }
429
430 // SubTasksDone functions.
431
432 SubTasksDone::SubTasksDone(uint n) :
433 _n_tasks(n), _n_threads(1), _tasks(NULL) {
434 _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
435 guarantee(_tasks != NULL, "alloc failure");
436 clear();
437 }
438
439 bool SubTasksDone::valid() {
440 return _tasks != NULL;
441 }
442
443 void SubTasksDone::set_n_threads(uint t) {
444 assert(_claimed == 0 || _threads_completed == _n_threads,
445 "should not be called while tasks are being processed!");
446 _n_threads = (t == 0 ? 1 : t);
447 }
|