private void rotateCycle(
        final long claimCycleId,
        final int cycleIdBitShift,
        final long maxCycleId)
    {
        if (claimCycleId >= maxCycleId)
        {
            throw new IllegalStateException("Exhausted cycle id space!");
        }
        final long nextCycleId = claimCycleId + 1;
        final int nextActiveCycleIndex = activeCycleIndex(nextCycleId);
        // it points at the beginning of the next cycle
        soProducerCycleClaim(nextActiveCycleIndex, nextCycleId << cycleIdBitShift);
        //Following this initialisation, a sequence of slow producers claims could trigger several new cycle rotations
        //before having changed the activeCycleId from claimCycleId to nextCycleId:
        //detect (and warn) a slow rotation, but enabling the faster ones to make progress, allows the q to not being blocked
        long cycleId = claimCycleId;
        //the rotation claimCycleId -> nextCycleId is unique between producers
        while (!casActiveCycleId(cycleId, nextCycleId))
        {
            cycleId = detectSlowRotation(claimCycleId, nextCycleId);
        }
    }
Given the nature of getAndAdd progress on producerPosition and given the potential risk for over claiming it is
quite possible for this method to report a queue which is not full as full.
jctools-experimental/src/main/java/org/jctools/queues/MpscRelaxedArrayQueue.java