private int ClaimCapacity(IAtomicBuffer buffer, int requiredCapacity) { var capacity = _capacity; var tailPositionIndex = _tailPositionIndex; var headCachePositionIndex = _headCachePositionIndex; var mask = capacity - 1; var head = buffer.GetLongVolatile(headCachePositionIndex); long tail; int tailIndex; int padding; do { tail = buffer.GetLongVolatile(tailPositionIndex); var availableCapacity = capacity - (int)(tail - head); if (requiredCapacity > availableCapacity) { head = buffer.GetLongVolatile(_headPositionIndex); if (requiredCapacity > (capacity - (int)(tail - head))) { return(InsufficientCapacity); } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = 0; tailIndex = (int)tail & mask; var toBufferEndLength = capacity - tailIndex; if (requiredCapacity > toBufferEndLength) { var headIndex = (int)head & mask; if (requiredCapacity > headIndex) { head = buffer.GetLongVolatile(_headPositionIndex); headIndex = (int)head & mask; if (requiredCapacity > headIndex) { return(InsufficientCapacity); } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = toBufferEndLength; } } while (!buffer.CompareAndSetLong(tailPositionIndex, tail, tail + requiredCapacity + padding)); if (0 != padding) { buffer.PutLongOrdered(tailIndex, RecordDescriptor.MakeHeader(padding, PaddingMsgTypeId)); tailIndex = 0; } return(tailIndex); }
private int ClaimCapacity(IAtomicBuffer buffer, int requiredCapacity) { var capacity = _capacity; var tailPositionIndex = _tailPositionIndex; var headCachePositionIndex = _headCachePositionIndex; var mask = capacity - 1; var head = buffer.GetLongVolatile(headCachePositionIndex); long tail; int tailIndex; int padding; do { tail = buffer.GetLongVolatile(tailPositionIndex); var availableCapacity = capacity - (int) (tail - head); if (requiredCapacity > availableCapacity) { head = buffer.GetLongVolatile(_headPositionIndex); if (requiredCapacity > (capacity - (int) (tail - head))) { return InsufficientCapacity; } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = 0; tailIndex = (int) tail & mask; var toBufferEndLength = capacity - tailIndex; if (requiredCapacity > toBufferEndLength) { var headIndex = (int) head & mask; if (requiredCapacity > headIndex) { head = buffer.GetLongVolatile(_headPositionIndex); headIndex = (int) head & mask; if (requiredCapacity > headIndex) { return InsufficientCapacity; } buffer.PutLongOrdered(headCachePositionIndex, head); } padding = toBufferEndLength; } } while (!buffer.CompareAndSetLong(tailPositionIndex, tail, tail + requiredCapacity + padding)); if (0 != padding) { buffer.PutLongOrdered(tailIndex, RecordDescriptor.MakeHeader(padding, PaddingMsgTypeId)); tailIndex = 0; } return tailIndex; }
/// <summary> /// Compare the current value to expected and if true then set to the update value atomically. /// </summary> /// <param name="expectedValue"> for the counter. </param> /// <param name="updateValue"> for the counter. </param> /// <returns> true if successful otherwise false. </returns> public bool CompareAndSet(long expectedValue, long updateValue) { return(_buffer.CompareAndSetLong(_offset, expectedValue, updateValue)); }