As for .NET, entering the monitor (the lock
statement) acquires semantics because it implicitly performs volatile reads and exiting the monitor (end of the lock
block) has release semantics because it implicitly performs volatile writes (see §12.6.5 "Locks and flows "to the" Language Infrastructure Separation "(CLI) I).
volatile bool areWeThereYet = false; // In thread 1 // Accesses, usually writes: create objects, initialize them areWeThereYet = true; // In thread 2 if (areWeThereYet) { // Accesses, usually reads: use created and initialized objects }
When you write a value before areWeThereYet
, all calls to it are executed and do not reorder after an unstable write.
When you read from areWeThereYet
, subsequent calls are not reordered until the volatile read is modified.
In this case, when thread 2 notices that areWeThereYet
has changed, it has the guarantee that the following calls, as a rule, are read, will observe other calls of the flows, as a rule, writes. Assuming there is no other code with the affected variables.
As with other synchronization primitives in .NET such as SemaphoreSlim
, although this is not explicitly documented, it would be useless if they did not have similar semantics. Programs based on them may, in fact, not even work correctly in platforms or hardware architectures with a weaker memory model.
Many people share the idea that Microsoft should provide a strong memory model on such architectures, similar to x86 / amd64, in order to maintain the current code base (compatible with Microsoft and its clients).
I can’t test myself, because I don’t have an ARM device with Microsoft Windows, much less with the .NET Framework for ARM, but at least one MSDN magazine article from Andrew Pardoe, CLR-.NET Development for ARM processors , says:
The CLR is allowed to expose a stronger memory model than the CLI ECMA specification. For example, on x86, the CLR memory model is strong because the processor memory model is strong. The .NET team could make the memory model on ARM as strong as the x86 model, but providing perfect ordering whenever possible could have a significant impact on code execution performance. Weve did targeted work to strengthen the memory model on ARM - in particular, we inserted memory barriers at key points when writing to a managed heap to guarantee type safety, but we did this only with minimal impact on performance. The team conducted several project reviews with experts to ensure that the methods used in the CLR ARM were correct. Moreover, performance tests show that .NET code execution performance is evaluated in the same way as native C ++ code when compared between x86, x64, and ARM.