src/share/vm/utilities/workgroup.cpp

Print this page
rev 6345 : 8040803: G1: Concurrent mark hangs when mark stack overflows
Reviewed-by: TDB


 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 }