G
Guest
Section 17.4.3 of the ECMA-334 C# Language Specification says
1 When a field-declaration includes a volatile modifier, the fields introduced by that declaration are volatile fields. 2 For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the lock-statement (15.12). 3 These optimizations can be performed by the compiler, by the runtime system, or by hardware. 4 For volatile fields, such reordering optimizations are restricted: 5 A read of a volatile field is called a volatile read. 6 A volatile read has "acquire semantics"; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence. 7 A write of a volatile field is called a volatile write. 8 A volatile write has "release semantics"; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.
A literal reading of part 6 is that a read of a volatile field "x" is guaranteed to occur before all other references to memory after the read in the instruction sequence, including references to fields other than "x"
Similarly, a literal reading of part 7 is that a write to a volatile field "x" is guaranteed to happen after all memory references prior to the write in the instruction sequence, including references to fields other than "x"
Are the literal readings correct, or are the guarantees only with respect to a single field at one time ("x")? For example, suppose we have two field
volatile int x
int y
and y is initialized to 0, a long time goes by, and some thread A executes this
y = 3
and then a different thread B executes this
x = x + 1
Console.WriteLine("x={0} y={1}", x, y)
Is guaranteed that the value printed for y is 3
1 When a field-declaration includes a volatile modifier, the fields introduced by that declaration are volatile fields. 2 For non-volatile fields, optimization techniques that reorder instructions can lead to unexpected and unpredictable results in multi-threaded programs that access fields without synchronization such as that provided by the lock-statement (15.12). 3 These optimizations can be performed by the compiler, by the runtime system, or by hardware. 4 For volatile fields, such reordering optimizations are restricted: 5 A read of a volatile field is called a volatile read. 6 A volatile read has "acquire semantics"; that is, it is guaranteed to occur prior to any references to memory that occur after it in the instruction sequence. 7 A write of a volatile field is called a volatile write. 8 A volatile write has "release semantics"; that is, it is guaranteed to happen after any memory references prior to the write instruction in the instruction sequence.
A literal reading of part 6 is that a read of a volatile field "x" is guaranteed to occur before all other references to memory after the read in the instruction sequence, including references to fields other than "x"
Similarly, a literal reading of part 7 is that a write to a volatile field "x" is guaranteed to happen after all memory references prior to the write in the instruction sequence, including references to fields other than "x"
Are the literal readings correct, or are the guarantees only with respect to a single field at one time ("x")? For example, suppose we have two field
volatile int x
int y
and y is initialized to 0, a long time goes by, and some thread A executes this
y = 3
and then a different thread B executes this
x = x + 1
Console.WriteLine("x={0} y={1}", x, y)
Is guaranteed that the value printed for y is 3