Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are reads and writes to unaligned fields in .NET definitely atomic?

The C# specification (ECMA-334 and ISO/IEC 23270) has a paragraph about the atomicity of reads and writes:

12.5 Atomicity of variable references

Reads and writes of the following data types shall be atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types. In addition, reads and writes of enum types with an underlying type in the previous list shall also be atomic. Reads and writes of other types, including long, ulong, double, and decimal, as well as user-defined types, need not be atomic.

But I have a hard time imagining that to be always true. For example, I can layout a struct using the StructLayout attribute, and force the fields to be unaligned:

// sizeof(MyStruct) == 9
[StructLayout(LayoutKind.Sequential, Pack = 1)]
struct MyStruct
{
    public byte pad;   // Offset: 0
    public int value1; // Offset: 1
    public int value2; // Offset: 5
}

Now when I do this, I would think the write to the int is not atomic, since it is not aligned to the natural boundary:

MyStruct myStruct = new MyStruct();
myStruct.value1 = 20;

So, is it definitely atomic (like the specification says), or is it not guaranteed to be atomic (e.g. on x86)? Either way, do you have any sources to back this up?

like image 638
Daniel A.A. Pelsmaeker Avatar asked Mar 06 '13 14:03

Daniel A.A. Pelsmaeker


1 Answers

I think you're right... there are a few situations where if you deliberately go out of your way, the system won't behave as per the language specification. Importantly, ECMA-335 makes this explicit in partition I section 12.6.6:

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.

(Bold emphasis mine; italics are in the spec.)

like image 194
Jon Skeet Avatar answered Oct 16 '22 09:10

Jon Skeet