Description
Re:
We check pContext->initialized
with an ordinary read, before accessing the static fields. There is a possibility that we will read the fields before reading the flag on weak-ordered architectures.
The code orders the write to the flag after running constructors by doing full memory fence, but that is both too much and not sufficient.
Too much is because just doing Volatile.Write(ref pContext->initialized, 1)
is enough to guarantee the order of writes.
Not sufficient because the read side can still read ahead of the flag check.
A simple fix would be to do volatile read of the flag when checking.
However the same flag check is emitted by the JIT. Not sure if we emit ldar
there. I suspect we do not. If that is a case, emitting ldar
would be a simple solution.
If ultimately, we do not want to emit ldar
, an alternative could be using a slightly different pattern where initialized
instead of being a condition flag, could be a pointer used to access the statics. I.E. if it is null
the cctor has not run yet, and if it is not null
, use it as a pointer (or an offset even if it is fixed, as long as it is used to compute the address) to access static state, then we could benefit from data dependency ordering the reads.
Replacing Interlocked.MemoryBarrier()
with a process-wide barrier would work too, but seems too heavy.
Metadata
Metadata
Assignees
Type
Projects
Status