Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing a bitwise operation using the Interlocked class in .NET

I'm trying to set bit flags in a shared variable within a multithreaded .NET application, but couldn't find a parallell to the native InterlockedOr function in the managed Interlocked class. I've come up with the following code for performing a |= assignment, but the theoretical possibility of an infinite loop is making me uncomfortable:

long currentValue;
long updatedValue;

do
{
    // Spin until successful update. Value must be read using Interlocked.Read()
    // to be truly atomic on 32 bit systems (see MSDN).
    currentFlags = Interlocked.Read(ref _currentFlags);
    updatedValue = currentFlags | flag;
} while (currentFlags != Interlocked.CompareExchange(ref _currentFlags, updatedValue, currentFlags));

Can this be implemented in a safer way using only the functions built into the Interlocked class? I'd like to avoid a solution involving an explicit lock if possible.

like image 473
Cryovat Avatar asked Jul 27 '15 15:07

Cryovat


1 Answers

Let's assume (these restrictions are not fundamental, just to simplify illustration) that

  • at the beginning currentFlags is 0,
  • we set at most one flag in one step,
  • we do not touch the sign bit.

Note that if we set bit k to 1 in currentFlags once, we could replace or with + 1L << k. So we can use a helper array set to remember which bits are set already, and do Interlocked.Add if needed.

long currentFlags = 0;
int[] set = new int[sizeof(long) * 8];

....

int k = ...; // bit to set
if(Interlocked.Exchange(ref set[k], 1) == 0)
    Interlocked.Add(ref currentFlags, 1L << k);
like image 198
AlexD Avatar answered Nov 14 '22 23:11

AlexD