< prev index next >

src/hotspot/share/gc/g1/g1FreeIdSet.cpp

Print this page




  62 }
  63 
  64 uintx G1FreeIdSet::make_head(uint index, uintx old_head) const {
  65   // Include incremented old update counter to avoid ABA problem.
  66   return index | ((old_head & ~_head_index_mask) + 1 + _head_index_mask);
  67 }
  68 
  69 const uint Claimed = UINT_MAX;
  70 
  71 uint G1FreeIdSet::claim_par_id() {
  72   _sem.wait();
  73   // Semaphore gate permits passage by no more than the number of
  74   // available ids, so there must be one that we can claim.  But there
  75   // may be multiple threads trying to claim ids at the same time.
  76   uintx old_head = Atomic::load(&_head);
  77   uint index;
  78   while (true) {
  79     index = head_index(old_head);
  80     assert(index < _size, "invariant");
  81     uintx new_head = make_head(_next[index], old_head);
  82     new_head = Atomic::cmpxchg(new_head, &_head, old_head);
  83     if (new_head == old_head) break;
  84     old_head = new_head;
  85   }
  86   DEBUG_ONLY(_next[index] = Claimed;)
  87   return _start + index;
  88 }
  89 
  90 void G1FreeIdSet::release_par_id(uint id) {
  91   uint index = id - _start;
  92   assert(index < _size, "invalid id %u", id);
  93   assert(_next[index] == Claimed, "precondition");
  94   uintx old_head = Atomic::load(&_head);
  95   while (true) {
  96     _next[index] = head_index(old_head);
  97     uintx new_head = make_head(index, old_head);
  98     new_head = Atomic::cmpxchg(new_head, &_head, old_head);
  99     if (new_head == old_head) break;
 100     old_head = new_head;
 101   }
 102   // Now that id has been released, permit another thread through the gate.
 103   _sem.signal();
 104 }


  62 }
  63 
  64 uintx G1FreeIdSet::make_head(uint index, uintx old_head) const {
  65   // Include incremented old update counter to avoid ABA problem.
  66   return index | ((old_head & ~_head_index_mask) + 1 + _head_index_mask);
  67 }
  68 
  69 const uint Claimed = UINT_MAX;
  70 
  71 uint G1FreeIdSet::claim_par_id() {
  72   _sem.wait();
  73   // Semaphore gate permits passage by no more than the number of
  74   // available ids, so there must be one that we can claim.  But there
  75   // may be multiple threads trying to claim ids at the same time.
  76   uintx old_head = Atomic::load(&_head);
  77   uint index;
  78   while (true) {
  79     index = head_index(old_head);
  80     assert(index < _size, "invariant");
  81     uintx new_head = make_head(_next[index], old_head);
  82     new_head = Atomic::cmpxchg(&_head, old_head, new_head);
  83     if (new_head == old_head) break;
  84     old_head = new_head;
  85   }
  86   DEBUG_ONLY(_next[index] = Claimed;)
  87   return _start + index;
  88 }
  89 
  90 void G1FreeIdSet::release_par_id(uint id) {
  91   uint index = id - _start;
  92   assert(index < _size, "invalid id %u", id);
  93   assert(_next[index] == Claimed, "precondition");
  94   uintx old_head = Atomic::load(&_head);
  95   while (true) {
  96     _next[index] = head_index(old_head);
  97     uintx new_head = make_head(index, old_head);
  98     new_head = Atomic::cmpxchg(&_head, old_head, new_head);
  99     if (new_head == old_head) break;
 100     old_head = new_head;
 101   }
 102   // Now that id has been released, permit another thread through the gate.
 103   _sem.signal();
 104 }
< prev index next >