Atomic Operation Thread Safety - Do I need a mirrored Atomic Read?

Is the following code safe (given in isolation) from torn reads?

private static double flopsErrorMargin = 0.01d;

public static double FlopsErrorMargin {
    get {
        double result = flopsErrorMargin;
        Thread.MemoryBarrier();
        return result;
    }
    set {
        Interlocked.Exchange(ref flopsErrorMargin, value);
    }
}

      

An atomic write operation ( Interlocked.Exchange()

) is required because double cannot be written in a single operation on the .NET platform (except for implementation details in 64-bit environments).

However, I also need a read-side mirror operation? For example. am I still at risk of getting a broken read because I am not reading the value atomically?

My guess is that I won't, because I think that other memory access (like reading) cannot happen concurrently with any other atomic operation, even if that other access is not an atom. But I would like to receive confirmation!

+3


source to share


2 answers


No, breaks are possible. Suppose your field access reads data and is interleaved partially with Interlocked.Exchange

, then the remaining 32 bits will be the updated value Exchange

and thus give a broken read.

For atomic reading, you need to use Interlocked.Read (on 32 bit machines).

The read method is not needed on 64-bit systems, since 64-bit read operations are already atoms. On 32-bit systems 64-bit read operations are not atomic unless done using Read

This also means that breaks are possible.



You can define your own atomic Read

for double

as follows

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

      

This is how it Interlocked.Read(long)

is implemented internally.

+3


source


Am I still at risk of getting a broken read because I am not reading the value atomically?



Yes. The return value Interlocked.Exchange

will not be torn, and the value that flopsErrorMargin

will eventually end up as it will value

(these are the two guarantees it provides Interlocked.Exchange

), but the unsynchronized read access may be torn.

+2


source







All Articles