< prev index next >

src/share/vm/gc/shared/workgroup.cpp

Print this page




 484   return true;
 485 }
 486 
 487 bool SequentialSubTasksDone::all_tasks_completed() {
 488   uint* n_completed_ptr = &_n_completed;
 489   uint  complete        = *n_completed_ptr;
 490   while (true) {
 491     uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
 492     if (res == complete) {
 493       break;
 494     }
 495     complete = res;
 496   }
 497   if (complete+1 == _n_threads) {
 498     clear();
 499     return true;
 500   }
 501   return false;
 502 }
 503 
 504 bool FreeIdSet::_stat_init = false;
 505 FreeIdSet* FreeIdSet::_sets[NSets];
 506 bool FreeIdSet::_safepoint;
 507 
 508 FreeIdSet::FreeIdSet(int sz, Monitor* mon) :
 509   _sz(sz), _mon(mon), _hd(0), _waiters(0), _index(-1), _claimed(0)
 510 {
 511   _ids = NEW_C_HEAP_ARRAY(int, sz, mtInternal);
 512   for (int i = 0; i < sz; i++) _ids[i] = i+1;
 513   _ids[sz-1] = end_of_list; // end of list.
 514   if (_stat_init) {
 515     for (int j = 0; j < NSets; j++) _sets[j] = NULL;
 516     _stat_init = true;
 517   }
 518   // Add to sets.  (This should happen while the system is still single-threaded.)
 519   for (int j = 0; j < NSets; j++) {
 520     if (_sets[j] == NULL) {
 521       _sets[j] = this;
 522       _index = j;
 523       break;
 524     }
 525   }
 526   guarantee(_index != -1, "Too many FreeIdSets in use!");
 527 }
 528 
 529 FreeIdSet::~FreeIdSet() {
 530   _sets[_index] = NULL;
 531   FREE_C_HEAP_ARRAY(int, _ids);
 532 }
 533 
 534 void FreeIdSet::set_safepoint(bool b) {
 535   _safepoint = b;
 536   if (b) {
 537     for (int j = 0; j < NSets; j++) {
 538       if (_sets[j] != NULL && _sets[j]->_waiters > 0) {
 539         Monitor* mon = _sets[j]->_mon;
 540         mon->lock_without_safepoint_check();
 541         mon->notify_all();
 542         mon->unlock();
 543       }
 544     }
 545   }
 546 }
 547 
 548 #define FID_STATS 0
 549 
 550 int FreeIdSet::claim_par_id() {
 551 #if FID_STATS
 552   thread_t tslf = thr_self();
 553   tty->print("claim_par_id[%d]: sz = %d, claimed = %d\n", tslf, _sz, _claimed);
 554 #endif
 555   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
 556   while (!_safepoint && _hd == end_of_list) {
 557     _waiters++;
 558 #if FID_STATS
 559     if (_waiters > 5) {
 560       tty->print("claim_par_id waiting[%d]: %d waiters, %d claimed.\n",
 561                  tslf, _waiters, _claimed);
 562     }
 563 #endif
 564     _mon->wait(Mutex::_no_safepoint_check_flag);
 565     _waiters--;
 566   }
 567   if (_hd == end_of_list) {
 568 #if FID_STATS
 569     tty->print("claim_par_id[%d]: returning EOL.\n", tslf);
 570 #endif
 571     return -1;
 572   } else {
 573     int res = _hd;
 574     _hd = _ids[res];
 575     _ids[res] = claimed;  // For debugging.
 576     _claimed++;
 577 #if FID_STATS
 578     tty->print("claim_par_id[%d]: returning %d, claimed = %d.\n",
 579                tslf, res, _claimed);
 580 #endif
 581     return res;
 582   }
 583 }
 584 
 585 bool FreeIdSet::claim_perm_id(int i) {
 586   assert(0 <= i && i < _sz, "Out of range.");
 587   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
 588   int prev = end_of_list;
 589   int cur = _hd;
 590   while (cur != end_of_list) {
 591     if (cur == i) {
 592       if (prev == end_of_list) {
 593         _hd = _ids[cur];
 594       } else {
 595         _ids[prev] = _ids[cur];
 596       }
 597       _ids[cur] = claimed;
 598       _claimed++;
 599       return true;
 600     } else {
 601       prev = cur;
 602       cur = _ids[cur];
 603     }
 604   }
 605   return false;
 606 
 607 }
 608 
 609 void FreeIdSet::release_par_id(int id) {
 610   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
 611   assert(_ids[id] == claimed, "Precondition.");
 612   _ids[id] = _hd;
 613   _hd = id;
 614   _claimed--;
 615 #if FID_STATS
 616   tty->print("[%d] release_par_id(%d), waiters =%d,  claimed = %d.\n",
 617              thr_self(), id, _waiters, _claimed);
 618 #endif
 619   if (_waiters > 0)
 620     // Notify all would be safer, but this is OK, right?
 621     _mon->notify_all();

 622 }


 484   return true;
 485 }
 486 
 487 bool SequentialSubTasksDone::all_tasks_completed() {
 488   uint* n_completed_ptr = &_n_completed;
 489   uint  complete        = *n_completed_ptr;
 490   while (true) {
 491     uint res = Atomic::cmpxchg(complete+1, n_completed_ptr, complete);
 492     if (res == complete) {
 493       break;
 494     }
 495     complete = res;
 496   }
 497   if (complete+1 == _n_threads) {
 498     clear();
 499     return true;
 500   }
 501   return false;
 502 }
 503 
 504 FreeIdSet::FreeIdSet(uint size, Monitor* mon) :
 505   _size(size), _mon(mon), _hd(0), _waiters(0), _claimed(0)




 506 {
 507   guarantee(size != 0, "must be");
 508   _ids = NEW_C_HEAP_ARRAY(uint, size, mtGC);
 509   for (uint i = 0; i < size - 1; i++) {
 510     _ids[i] = i+1;










 511   }
 512   _ids[size-1] = end_of_list; // end of list.
 513 }
 514 
 515 FreeIdSet::~FreeIdSet() {
 516   FREE_C_HEAP_ARRAY(uint, _ids);

 517 }
 518 
 519 uint FreeIdSet::claim_par_id() {




















 520   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
 521   while (_hd == end_of_list) {
 522     _waiters++;






 523     _mon->wait(Mutex::_no_safepoint_check_flag);
 524     _waiters--;
 525   }
 526   if (_hd == end_of_list) {
 527     return UINT_MAX;



 528   } else {
 529     int res = _hd;
 530     _hd = _ids[res];
 531     _ids[res] = claimed;  // For debugging.
 532     _claimed++;




 533     return res;
 534   }
 535 }
 536 
 537 void FreeIdSet::release_par_id(uint id) {
























 538   MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag);
 539   assert(_ids[id] == claimed, "Precondition.");
 540   _ids[id] = _hd;
 541   _hd = id;
 542   _claimed--;
 543   if (_waiters > 0) {




 544     // Notify all would be safer, but this is OK, right?
 545     _mon->notify_all();
 546   }
 547 }
< prev index next >