@VisibleForTesting public FixedSizedObjectPool(int size, PoolObjectHelper<T> helper, boolean doTraceLog) { if (size > MAX_SIZE) { throw new AssertionError("Size must be <= " + MAX_SIZE); } this.helper = helper; @SuppressWarnings("unchecked") T[] poolTmp = (T[])new Object[size]; pool = poolTmp; // Initially, all deltas and rcs are 0; empty list starts at 0; there are no objects to take. state = new AtomicLong(OBJECTS.setMarker(0, NO_MARKER)); casLog = doTraceLog ? new CasLog() : null; }
private void commitArrayIndex(Marker from, Marker to, long originalMarker) { while (true) { long oldVal = state.get(), rc = from.getRc(oldVal); long newVal = from.setRc(oldVal, rc - 1); // Decrease refcount. assert rc > 0; if (rc == 1) { // We are the last of the concurrent operations to finish. Commit. long marker = from.getMarker(oldVal), delta = from.getDelta(oldVal), otherMarker = to.getMarker(oldVal), otherDelta = to.getDelta(oldVal); assert rc <= delta; // Move marker according to delta, change delta to 0. long newMarker = applyDeltaToMarker(marker, otherMarker, delta); newVal = from.setDelta(from.setMarker(newVal, newMarker), 0); if (otherMarker == NO_MARKER) { // The other list doesn't exist, create it at the first index of our op. assert otherDelta == 0; newVal = to.setMarker(newVal, originalMarker); } else if (otherDelta > 0 && otherDelta != NO_DELTA && applyDeltaToMarker(otherMarker, marker, otherDelta) == NO_MARKER) { // The other list will be exhausted when it commits. Create new one pending that commit. newVal = to.setDelta(to.setMarker(newVal, originalMarker), NO_DELTA); } } if (setState(oldVal, newVal)) return; } }
@VisibleForTesting public FixedSizedObjectPool(int size, PoolObjectHelper<T> helper, boolean doTraceLog) { if (size > MAX_SIZE) { throw new AssertionError("Size must be <= " + MAX_SIZE); } this.helper = helper; @SuppressWarnings("unchecked") T[] poolTmp = (T[])new Object[size]; pool = poolTmp; // Initially, all deltas and rcs are 0; empty list starts at 0; there are no objects to take. state = new AtomicLong(OBJECTS.setMarker(0, NO_MARKER)); casLog = doTraceLog ? new CasLog() : null; }
private void commitArrayIndex(Marker from, Marker to, long originalMarker) { while (true) { long oldVal = state.get(), rc = from.getRc(oldVal); long newVal = from.setRc(oldVal, rc - 1); // Decrease refcount. assert rc > 0; if (rc == 1) { // We are the last of the concurrent operations to finish. Commit. long marker = from.getMarker(oldVal), delta = from.getDelta(oldVal), otherMarker = to.getMarker(oldVal), otherDelta = to.getDelta(oldVal); assert rc <= delta; // Move marker according to delta, change delta to 0. long newMarker = applyDeltaToMarker(marker, otherMarker, delta); newVal = from.setDelta(from.setMarker(newVal, newMarker), 0); if (otherMarker == NO_MARKER) { // The other list doesn't exist, create it at the first index of our op. assert otherDelta == 0; newVal = to.setMarker(newVal, originalMarker); } else if (otherDelta > 0 && otherDelta != NO_DELTA && applyDeltaToMarker(otherMarker, marker, otherDelta) == NO_MARKER) { // The other list will be exhausted when it commits. Create new one pending that commit. newVal = to.setDelta(to.setMarker(newVal, originalMarker), NO_DELTA); } } if (setState(oldVal, newVal)) return; } }