In order to perform interlocked reads I have used InterlockedCompareExchange
function a la
value = InterlockedCompareExchange(ptr, 0, 0);
Now I stumbled upon unusual situation.
I want to use this interlocked "read" on a read-only (write-protected) memory page. The result is "Access violation writing location x"...
So I guess this is by design? I understand that InterlockedCompareExchange
is often a used as a "write" instruction. But why is access violation trigger included in this particular case?
What are the alternatives to InterlockedCompareExchange
in order to perform interlocked read?
Update: I tried using
value = InterlockedCompareExchange(ptr, 0, -1);
when I know that the value at ptr is never negative, but this triggers the access violation also, even though in this case there certainly isn't any writing going on. So I guess this is by design with this instruction...
But why and how to get around that?
Update2: More details about why I started using interlocked reads.
I left my question intentionally vague. I am generally interested in the topic, that is - both skipping the cache and having atomic reads, including atomic 64-bit reads.
The reason why I started wondering is that .NET uses CompareExchange
for interlocked reading inside System.Threading.Interlocked.Read(ref Int64 location)
method.
The MSDN states for this .NET Interlocked.Read
method: "The Read method is unnecessary on 64-bit systems, because 64-bit read operations are already atomic. On 32-bit systems, 64-bit read operations are not atomic unless performed using Read."
Also, MSDN states for (C-language) InterlockedCompareExchange64
function that unaligned operations are not permitted in any case: "The variables for this function must be aligned on a 64-bit boundary; otherwise, this function will behave unpredictably on multiprocessor x86 systems and any non-x86 systems".
So according to that text also .NET should never have unaligned Int64 variables. But then why interlocked reading?