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 uint res = _hd; 527 _hd = _ids[res]; 528 _ids[res] = claimed; // For debugging. 529 _claimed++; 530 return res; 531 } 532 533 void FreeIdSet::release_par_id(uint id) { 534 MutexLockerEx x(_mon, Mutex::_no_safepoint_check_flag); 535 assert(_ids[id] == claimed, "Precondition."); 536 _ids[id] = _hd; 537 _hd = id; 538 _claimed--; 539 if (_waiters > 0) { 540 _mon->notify_all(); 541 } 542 } |