On Wed, Oct 10, 2012 at 10:42:53AM +0200, Joerg-Cyril.Hoehle@t-systems.com wrote:
Hi,
David Laight wrote:
Better to code as: status = wmm->dwStatus; if (...)
Incidentally, that's what I did tonight in patch 20/25 try 2.
but even then I think the compiler is allowed to perform extra reads. It might, for example, do so if the condition was complicayted and there was a lot of pressure on registers - so instead of spilling 'status' to stack, it would re-read it.
Interesting. Do you think/believe or are you sure?
Probably in the realms of 'is allowed to' (under the general 'is if' rule), but in practise won't.
With gcc you can force it to only to one read by adding: asm volatile("":::"memory"); The only portable way is with volatile.
"only portable way" from the C perspective. However, given a specific target environment, we could use its API functions. Either MemoryBarrier(); /* which MSDN documents but Wine does not provide in include/*.h Or InterlockedExchange(&status, wmm->dwStatus);
So if AJ is still not satisfied with try 2, I'll change all reads of wmm->dwStatus within the player into InterlockedExchange. Yet I think that would be a superfluous extra memory barrier within the player.
That use of InterlockedExchange() is OTT. As well as being a slow, locked bus cycle is will force a stack slot for 'status', and the value be read back from there after anything that might modify memory (eg a function call).
I can't remember the minumum requirement to stop the compiler doing a reload. A call to an external function is more than enough.
There are also a lot of different tyoes of 'memory barrier' dunno which sort MSDN's MemoryBarrier() generates. On x86/amd64 you almost never need to request a barrier.
David