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.
Let's assume (these restrictions are not fundamental, just to simplify illustration) that
currentFlags
is 0
,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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With