Search code examples
c#.netclrinterlocked

Why Interlocked.Read uses Interlocked.CompareExchange internally?


below is the source code with my comment for Interlocked:

public static class Interlocked {

   // Int32 old = location;
   // if (location == comparand) location = value;
   // return old; 
   public static Int32 CompareExchange(ref Int32 location, Int32 value, Int32 comparand);

   public static long Read(ref long location)
   {
      return Interlocked.CompareExchange(ref location, 0, 0);
   }

}

I don't understand why Read calls Interlocked.CompareExchange(ref location, 0, 0)?

long location can be any number, why it is compared with 0?


Solution

  • Primary reason for use ofInterlocked.CompareExchange() method it is to ensure reading 64-bit value is atomic on 32-bit systems. Reading 64-bit value on 64-bit system is atomic by default.

    That is also why Interlocked.Read() method only accepts Uint64 and Int64 parameters.

    Interlocked.CompareExchange() method is atomic operation that compares original value stored in location1 with comparand parameter to make sure the value we want to exchange was not changed by other thread having access to that variable. If the value was not changed, then it is replaced, otherwise nothing happens, but always the original value stored in location1 is returned.

    So, the Read() method actually leveraging above written by trying to compare 0 with value stored in location1 and based on that comparison either replaces the value or not, but returning the original value.

    Which might be translated into something like

    if(original != comparand) {
        return original;
    } else {
        var temp = original;
        original = value;
        return temp;
    }
    

    That is why Read() method uses CompareExchange() method internally as anytime you use CompareExchange() you get original value and if you pass same values as value and comparand you never get into situation exchange actually happens. Either values are different and exchange is not going to happen at all or values are same and exchange is about to happen, but you are exchanging 0 for 0.