Question:
There are patterns (for example, here C # / CLR: MemoryBarrier and torn reads ) that can perform read breaks, but never use the resulting value if a break read can occur.
Is this behavior undefined in C #?
Related: How can I determine for myself if this behavior is undefined or not?
Failed to determine the answer:
My understanding (correct if I'm wrong) is that in C ++ 11 this will be undefined behavior, because it is not defined by the memory model that was added in C ++ 11 (in older versions, everything is multi - threading was a specific implementation behavior). Theoretically, I could determine this from the specification.
I tried to do this for C # and could not. I could not find the memory model in the specification. Below are some notes from my failed trip to the C # language specification ( http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf ), trying to track the semantics of assigning one structure to another in case when there may be a data race (one reader, one writer recording data that is being copied). I was unable to find even the semantics for assigning or reading from any variable in any scenario. Either I missed something (almost certainly) or I used undefined variables.
My notes on reading the relevant parts of the C # spec:
The C # language specification says which types are atomic, but never interferes with atomic and non-atomic reads and writes:
12.5 Atomicity of variable references
Reading and writing of the following data types should be atomic: bool, char, byte, sbyte, short, ushort, uint, int, float and reference. In addition, enumeration type entries with a base type in the previous list must also be atomic. Reads and writes about other types, including long, ulong, double, and decimal, as well as custom types, which do not have to be atomic. In addition to library functions intended for this purpose, there is no guarantee of atomic read-modify-write, for example, in the case of an increase or decrease.
He does not say that if “atomic” (which he does not define) here means any barriers (I suppose not), but is more relevant for this question, he does not even determine what reading and writing are doing (which is not - trivial in multithreaded programs).
View 14.14.1 Simple assignment , this is apparently the degree of specification of the record (explanation of "x = y"):
The value obtained by evaluating and transforming y is stored at the location specified by the estimate x.
8.3 Variables and parameters :
A variable must be assigned before its value can be obtained.
but does not determine the receipt of a value. No, where do I see the specification for what reads (it would be possible to assume that the last thing you wrote in the single-threaded case, so I cannot find it in the specification).
10.10 Execution order , apparently, unnecessarily limits (compared with the usual receipt and release semantics used in the MSDN article below) to the variable with respect to the record (no record can be moved in any direction by reference to the volatile), and with limited reading (they can move in both directions through volatile operations. He also does not mention Thread.MemoryBarrier (Who the documentation seems to prevent the processor, but not reordering the compiler, is therefore too weak). It also does not refer to the fact that loading from P belt / field means so much trouble offtopicheskih questions, but no answers.
I read all the parts of the specification that I could find that are relevant. Nowhere is reading from a field / memory / variable (looks like a "variable" - this is the correct term here).
Perhaps somewhere in the language specification there is a specification for the behavior of reading / loading and writing / storing variables (aka: memory model), but if there is (I could not find it), this is not an atomic link (I searched for it for an atom : section 12.5 is the only use). I don’t see how any C # code can be defined, so I’m obviously missing something: I don’t think that a real C # implementation can just exit (due to the fact that it is undefined behavior!) On any reading or value records.
If multi-threaded (and possibly even single-threaded) C # is actually terribly incomplete, without a memory model, is there any place for viewing specifications for specific implementations? Example: If C # does not define the semantics of reading and writing, perhaps Microsoft of various C # compilers (now at least 3) provide specifications and Mono? Is it safe in any of the implementations and what can I say?
Perhaps there are some unofficial (not in the specification) rules that are considered safe (all major implementations are consistent)? That would be scary, but if everything we get, I will take it.
Some relevant but insufficient sources:
I found this article claiming to be a C # memory model, but it is implementation specific (refers to the CLR) and does not apply to the case in question. It also gives a good clean explanation of what I would like to get volatile semantics (C ++ 11 style acquires release), but to some extent stronger and weaker than 10.10 Execution order from the language specification, so I think that this wrong: https://msdn.microsoft.com/magazine/jj863136
This article has a lot of good information comparing the C # memory model with C ++ 11, but also does not address this specific problem, as far as I can tell: http://blog.alexrp.com/2014/03/30/dot- net-atomics-and-memory-model-semantics /
Good article on reordering issues. The update at the end mentions that “volatile reading can be moved backward in time relative to a volatile record”, which is not consistent with the 10.10 Execution order from the specification, but is consistent with the fact that most people think that semantics should be (which means consistent with MSDN article and volatile class, but not a keyword, as far as I can tell): http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/#.VoSyfhXhDGg
With a quick browse, this article mainly deals with instability and how it prevents excessive load shedding and why it is needed: https://blogs.msdn.microsoft.com/ericlippert/2011/06/16/atomicity-volatility-and- immutability-are-different-part-three /