0

I have written two lock-free update helper methods inspired by Joseph Albahari & Marc Gravell

Looking at the 2nd implementation why would I need the SpinWait in the 1st implementation? What are the advantables/disadvantages of one over the other?

Please note this question is not about what SpinWait does but rather specific to how these two methods differ in execution.

public static void LockFreeUpdate1<T>(ref T field, Func<T, T> updater) where T : class
{
    var spinner = new SpinWait();

    T snapshot;    
    while (true)
    {
        snapshot = field;

        if (snapshot.Equals(
               Interlocked.CompareExchange(ref field, updater(snapshot), snapshot))) { return; }

        spinner.SpinOnce();
    }
}


public static void LockFreeUpdate2<T>(ref T field, Func<T, T> updater) where T : class
{
    T snapshot;
    do
    {
        snapshot = field;                

    } while(
        snapshot.Equals(
           Interlocked.CompareExchange(ref field, updater(snapshot), snapshot)));
}
Community
  • 1
  • 1
MaYaN
  • 6,683
  • 12
  • 57
  • 109
  • 1
    Note that due to CPU caching, the `snapshot = field;` might not notice changes to the field - if you *expect* it to, you should use `Volatile.Read`. The only reason for a spin-wait here is that if you're *actively competing* (and losing) with another thread: you might as well give it a picosecond to finish what it is doing. Note that `updater` could be called multiple times, which may be unexpected – Marc Gravell Jun 29 '15 at 08:46
  • 2
    Tnx Marc, `Interlocked.CompareExchange` generates a memory barrier so we will just end up with an extra loop iteration if stale value is read, no? – MaYaN Jun 29 '15 at 08:59

0 Answers0