Reputation: 7963
Is the following code safe (considering it in isolation) from a torn read?
private static double flopsErrorMargin = 0.01d;
public static double FlopsErrorMargin {
get {
double result = flopsErrorMargin;
Thread.MemoryBarrier();
return result;
}
set {
Interlocked.Exchange(ref flopsErrorMargin, value);
}
}
The atomic write operation (Interlocked.Exchange()
) is required because a double is not guaranteed to be written in a single operation on the .NET platform (excepting implementation details on 64-bit environments).
However, do I also need a 'mirror' operation on the read side? E.g. am I still at risk of getting a torn read because I do not read the value atomically?
My hunch is that I will not, because I think that another memory access (e.g. a read) can not happen concurrently with any other atomic operation, even if that other access is not itself atomic. But I would like some confirmation!
Upvotes: 3
Views: 145
Reputation: 73452
No, Torn reads are possible. Assume your field access is reading the data and interleaved partway by the Interlocked.Exchange
, then other 32 bits will be the updated value of Exchange
and thus produces torn read.
For atomic read, you need to use Interlocked.Read (in 32 bit machines).
The Read method is unnecessary on 64-bit systems, because 64-bit read operations are already atomic. On 32-bit systems, 64-bit read operations are not atomic unless performed using Read
Which also means that torn values are possible.
You could 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 Interlocked.Read(long)
is implemented internally.
Upvotes: 3
Reputation: 203811
am I still at risk of getting a torn read because I do not read the value atomically?
Yes. The return value of Interlocked.Exchange
won't be torn, and the value that flopsErrorMargin
eventually ends up as will be value
(those are the two guarantees that Interlocked.Exchange
give you), but an unsynchronized read access could be torn.
Upvotes: 2