What operations are atomic in C#?
C#.NetMultithreadingAtomicC# Problem Overview
Is there a systematic way to know whether an operation in C# will be atomic or not? Or are there any general guidelines or rules of thumb?
C# Solutions
Solution 1 - C#
For something more complete/detailed:
Reads and writes to 32-bit value types are atomic: This includes the following intrinsic value (struct) types: bool, char, byte, sbyte, short, ushort, int, uint, float
. The following types (amongst others) are not guaranteed to be atomic: decimal, double, long, ulong
.
e.g.
int x;
x = 10; // atomic
decimal d;
d = 10m; // not atomic
Reference assignment is also an atomic operation:
private String _text;
public void Method(String text)
{
_text = text; // atomic
}
Solution 2 - C#
Yes. Read the CLI specification: http://www.ecma-international.org/publications/standards/Ecma-335.htm. For instance:
I.12.6.6 Atomic reads and writes
> A conforming CLI shall guarantee that read and write access to > properly aligned memory locations no larger than the native word size > (the size of type native int) is atomic (see §I.12.6.2) when all the > write accesses to a location are the same size. Atomic writes shall > alter no bits other than those written. Unless explicit layout > control (see Partition II (Controlling Instance Layout)) is used to > alter the default behavior, data elements no larger than the natural > word size (the size of a native int) shall be properly aligned. > Object references shall be treated as though they are stored in the > native word size. > > [Note: There is no guarantee about atomic update > (read-modify-write) of memory, except for methods provided for that > purpose as part of the class library (see Partition IV). An atomic > write of a “small data item” (an item no larger than the native word > size) is required to do an atomic read/modify/write on hardware that > does not support direct writes to small data items. end note] > > [Note: > There is no guaranteed atomic access to 8-byte data when the size of a > native int is 32 bits even though some implementations might perform > atomic operations when the data is aligned on an 8-byte boundary. end > note]
Regarding the 64-bit long question, Eric Lippert answers it here: https://ericlippert.com/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two/
> The CLI specification actually makes stronger guarantees. The CLI > guarantees that reads and writes of variables of value types that are > the size (or smaller) of the processor's natural pointer size are > atomic; if you are running C# code on a 64 bit operating system in a > 64 bit version of the CLR then reads and writes of 64 bit doubles and > long integers are also guaranteed to be atomic. The C# language does > not guarantee that, but the runtime spec does. (If you are running C# > code in some environment that is not implemented by some > implementation of the CLI then of course you cannot rely upon that > guarantee; contact the vendor who sold you the runtime if you want to > know what guarantees they provide.) > > Another subtle point about atomic access is that the underlying > processor only guarantees atomicity when the variable being read or > written is associated with storage that is aligned to the right > location in memory. Ultimately the variable will be implemented as a > pointer to memory somewhere. On a 32 bit operating system, that > pointer has to be evenly divisible by 4 in order for the read or write > to be guaranteed to be atomic, and on a 64 bit operating system it has > to be evenly divisible by 8.
Solution 3 - C#
From the CLI specifications you can get here:
> "A conforming CLI shall guarantee that read and write access to > properly aligned memory locations no larger than the native word size > (the size of type native int) is atomic…”
Section 12.5 from the C# specification here: > “Reads and writes of the following data types shall be atomic: bool, > char, byte, sbyte, short, ushort, uint, int, float, and reference > types.” Also: “…there is no guarantee of atomic read-modify-write, > such as in the case of increment or decrement.”
Make the increment operation atomic with this.