Search code examples
c#.netmultithreadingsynchronizationatomic

Atomically exchange value on result of comparison


I have a very simple operation that needs to be done atomically:

if (a > b)
  b = a

where a and b are ints

EDIT: and a is local.

Is there a fast way to do this in C#? I'd like to avoid locking manually if possible. I've looked at Interlocked.CompareExchange, but as I understand it, this only tests for equality.

Thanks!


Solution

  • The canonical way is to use interlocked compare-exchange in a loop:

    int oldvalue, newvalue ;
    do {
      oldvalue = b ; // you'll want to force this to be a volatile read somehow
      if( a > oldvalue )
        newvalue = a ;
      else
        break ;
    } while( interlocked replace oldvalue with newvalue in b does NOT succeed );
    

    (Pseudocode because I don't bother to look up the correct way to do an interlocked exchange in C#).

    As you see, unless you have overriding efficiency concerns, using plain old mutexes is far simpler and more readable.

    Edit: This assumes that a is a local variable or at least not subject to asynchronous writes. It both of a and b can be modified behind your back, then there is no lock-free way of doing this update atomically. (Thanks to silev for pointing this out).