Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpinWait in lockless update

While reading Albahari's Threading in C#, I've noticed that the "lock free update" pattern uses a SpinWait at the end of the cycle:

static void LockFreeUpdate<T> (ref T field, Func <T, T> updateFunction)
  where T : class
{
    var spinWait = new SpinWait();
    while (true)
    {
        // read
        T snapshot1 = field;

        // apply transformation
        T calc = updateFunction (snapshot1);

        // compare if not preempted
        T snapshot2 = Interlocked.CompareExchange (ref field, calc, snapshot1);

        // if succeeded, we're done
        if (snapshot1 == snapshot2) return;

        // otherwise spin
        spinWait.SpinOnce();
    }
}

Note the spinWait.SpinOnce() call at the end. Is this call needed only to yield the thread in a single-threaded environment, or does it have an additional purpose?

like image 642
Lou Avatar asked Oct 22 '25 03:10

Lou


1 Answers

Short answer... Yes. The intent of SpinWait is to allow yielding the thread to the System so as not to starve processing due to SpinLock.

From MSDN

https://msdn.microsoft.com/en-us/library/system.threading.spinwait(v=vs.110).aspx

SpinWait encapsulates common spinning logic. On single-processor machines, yields are always used instead of busy waits, and on computers with Intel processors employing Hyper-Threading technology, it helps to prevent hardware thread starvation. SpinWait encapsulates a good mixture of spinning and true yielding.

SpinWait is a value type, which means that low-level code can utilize SpinWait without fear of unnecessary allocation overheads. SpinWait is not generally useful for ordinary applications. In most cases, you should use the synchronization classes provided by the .NET Framework, such as Monitor. For most purposes where spin waiting is required, however, the SpinWait type should be preferred over the SpinWait method.

like image 115
Matthew Whited Avatar answered Oct 24 '25 17:10

Matthew Whited