Skip to content

Commit

Permalink
Pick out the MonotonicUpdate function into utility
Browse files Browse the repository at this point in the history
  • Loading branch information
tli2 committed Jul 10, 2019
1 parent 77ec994 commit 0a87422
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 38 deletions.
51 changes: 13 additions & 38 deletions cs/src/core/Allocator/AllocatorBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ public void ShiftReadOnlyToTail(out long tailAddress)
tailAddress = GetTailAddress();
long localTailAddress = tailAddress;
long currentReadOnlyOffset = ReadOnlyAddress;
if (MonotonicUpdate(ref ReadOnlyAddress, tailAddress, out long oldReadOnlyOffset))
if (Utility.MonotonicUpdate(ref ReadOnlyAddress, tailAddress, out long oldReadOnlyOffset))
{
epoch.BumpCurrentEpoch(() => OnPagesMarkedReadOnly(localTailAddress, false));
}
Expand All @@ -882,7 +882,7 @@ public void ShiftReadOnlyToTail(out long tailAddress)
/// <param name="newReadOnlyAddress"></param>
public bool ShiftReadOnlyAddress(long newReadOnlyAddress)
{
if (MonotonicUpdate(ref ReadOnlyAddress, newReadOnlyAddress, out long oldReadOnlyOffset))
if (Utility.MonotonicUpdate(ref ReadOnlyAddress, newReadOnlyAddress, out long oldReadOnlyOffset))
{
epoch.BumpCurrentEpoch(() => OnPagesMarkedReadOnly(newReadOnlyAddress, false));
return true;
Expand All @@ -897,19 +897,19 @@ public bool ShiftReadOnlyAddress(long newReadOnlyAddress)
public void ShiftBeginAddress(long newBeginAddress)
{
// First update the begin address
MonotonicUpdate(ref BeginAddress, newBeginAddress, out long oldBeginAddress);
Utility.MonotonicUpdate(ref BeginAddress, newBeginAddress, out long oldBeginAddress);
// Then the head address
var h = MonotonicUpdate(ref HeadAddress, newBeginAddress, out long old);
var h = Utility.MonotonicUpdate(ref HeadAddress, newBeginAddress, out long old);
// Finally the read-only address
var r = MonotonicUpdate(ref ReadOnlyAddress, newBeginAddress, out old);
var r = Utility.MonotonicUpdate(ref ReadOnlyAddress, newBeginAddress, out old);

// Clean up until begin address
epoch.BumpCurrentEpoch(() =>
{
if (r)
{
MonotonicUpdate(ref SafeReadOnlyAddress, newBeginAddress, out long _old);
MonotonicUpdate(ref FlushedUntilAddress, newBeginAddress, out _old);
Utility.MonotonicUpdate(ref SafeReadOnlyAddress, newBeginAddress, out long _old);
Utility.MonotonicUpdate(ref FlushedUntilAddress, newBeginAddress, out _old);
}
if (h) OnPagesClosed(newBeginAddress);

Expand All @@ -935,7 +935,7 @@ protected virtual void DeleteAddressRange(long fromAddress, long toAddress)
/// <param name="waitForPendingFlushComplete"></param>
public void OnPagesMarkedReadOnly(long newSafeReadOnlyAddress, bool waitForPendingFlushComplete = false)
{
if (MonotonicUpdate(ref SafeReadOnlyAddress, newSafeReadOnlyAddress, out long oldSafeReadOnlyAddress))
if (Utility.MonotonicUpdate(ref SafeReadOnlyAddress, newSafeReadOnlyAddress, out long oldSafeReadOnlyAddress))
{
Debug.WriteLine("SafeReadOnly shifted from {0:X} to {1:X}", oldSafeReadOnlyAddress, newSafeReadOnlyAddress);
long startPage = oldSafeReadOnlyAddress >> LogPageSizeBits;
Expand Down Expand Up @@ -964,7 +964,7 @@ public void OnPagesMarkedReadOnly(long newSafeReadOnlyAddress, bool waitForPendi
/// <param name="newSafeHeadAddress"></param>
public void OnPagesClosed(long newSafeHeadAddress)
{
if (MonotonicUpdate(ref SafeHeadAddress, newSafeHeadAddress, out long oldSafeHeadAddress))
if (Utility.MonotonicUpdate(ref SafeHeadAddress, newSafeHeadAddress, out long oldSafeHeadAddress))
{
Debug.WriteLine("SafeHeadOffset shifted from {0:X} to {1:X}", oldSafeHeadAddress, newSafeHeadAddress);

Expand Down Expand Up @@ -1020,7 +1020,7 @@ private void PageAlignedShiftReadOnlyAddress(long currentTailAddress)
long currentReadOnlyAddress = ReadOnlyAddress;
long pageAlignedTailAddress = currentTailAddress & ~PageSizeMask;
long desiredReadOnlyAddress = (pageAlignedTailAddress - ReadOnlyLagAddress);
if (MonotonicUpdate(ref ReadOnlyAddress, desiredReadOnlyAddress, out long oldReadOnlyAddress))
if (Utility.MonotonicUpdate(ref ReadOnlyAddress, desiredReadOnlyAddress, out long oldReadOnlyAddress))
{
Debug.WriteLine("Allocate: Moving read-only offset from {0:X} to {1:X}", oldReadOnlyAddress, desiredReadOnlyAddress);
epoch.BumpCurrentEpoch(() => OnPagesMarkedReadOnly(desiredReadOnlyAddress));
Expand Down Expand Up @@ -1050,7 +1050,7 @@ private void PageAlignedShiftHeadAddress(long currentTailAddress)
if (ReadCache && (newHeadAddress > HeadAddress))
EvictCallback(HeadAddress, newHeadAddress);

if (MonotonicUpdate(ref HeadAddress, newHeadAddress, out long oldHeadAddress))
if (Utility.MonotonicUpdate(ref HeadAddress, newHeadAddress, out long oldHeadAddress))
{
Debug.WriteLine("Allocate: Moving head offset from {0:X} to {1:X}", oldHeadAddress, newHeadAddress);
epoch.BumpCurrentEpoch(() => OnPagesClosed(newHeadAddress));
Expand All @@ -1075,7 +1075,7 @@ public long ShiftHeadAddress(long desiredHeadAddress)
if (ReadCache && (newHeadAddress > HeadAddress))
EvictCallback(HeadAddress, newHeadAddress);

if (MonotonicUpdate(ref HeadAddress, newHeadAddress, out long oldHeadAddress))
if (Utility.MonotonicUpdate(ref HeadAddress, newHeadAddress, out long oldHeadAddress))
{
Debug.WriteLine("Allocate: Moving head offset from {0:X} to {1:X}", oldHeadAddress, newHeadAddress);
epoch.BumpCurrentEpoch(() => OnPagesClosed(newHeadAddress));
Expand Down Expand Up @@ -1104,35 +1104,10 @@ protected void ShiftFlushedUntilAddress()

if (update)
{
MonotonicUpdate(ref FlushedUntilAddress, currentFlushedUntilAddress, out long oldFlushedUntilAddress);
Utility.MonotonicUpdate(ref FlushedUntilAddress, currentFlushedUntilAddress, out long oldFlushedUntilAddress);
}
}



/// <summary>
/// Used by several functions to update the variable to newValue. Ignores if newValue is smaller or
/// than the current value.
/// </summary>
/// <param name="variable"></param>
/// <param name="newValue"></param>
/// <param name="oldValue"></param>
/// <returns></returns>
private bool MonotonicUpdate(ref long variable, long newValue, out long oldValue)
{
oldValue = variable;
while (oldValue < newValue)
{
var foundValue = Interlocked.CompareExchange(ref variable, newValue, oldValue);
if (foundValue == oldValue)
{
return true;
}
oldValue = foundValue;
}
return false;
}

/// <summary>
/// Reset for recovery
/// </summary>
Expand Down
34 changes: 34 additions & 0 deletions cs/src/core/Utilities/Utility.cs
Original file line number Diff line number Diff line change
Expand Up @@ -223,5 +223,39 @@ internal static int Murmur3(int h)
a ^= a >> 16;
return (int)a;
}

/// <summary>
/// Updates the variable to newValue only if the current value is smaller than the new value.
/// </summary>
/// <param name="variable"> The variable to possibly replace</param>
/// <param name="newValue">The value that replaces the variable if successful</param>
/// <param name="oldValue">The orignal value in the variable</param>
/// <returns> if oldValue less than newValue </returns>
public static bool MonotonicUpdate(ref long variable, long newValue, out long oldValue)
{
do
{
oldValue = variable;
if (oldValue > newValue) return false;
} while (Interlocked.CompareExchange(ref variable, newValue, oldValue) != oldValue);
return true;
}
/// <summary>
/// Updates the variable to newValue only if the current value is smaller than the new value.
/// </summary>
/// <param name="variable"> The variable to possibly replace</param>
/// <param name="newValue">The value that replaces the variable if successful</param>
/// <param name="oldValue">The orignal value in the variable</param>
/// <returns>if oldValue less than newValue</returns>
public static bool MonotonicUpdate(ref int variable, int newValue, out int oldValue)
{
do
{
oldValue = variable;
if (oldValue > newValue) return false;
} while (Interlocked.CompareExchange(ref variable, newValue, oldValue) != oldValue);
return true;
}

}
}

0 comments on commit 0a87422

Please sign in to comment.