Pastebin:Atomic
The question is, are atomic_1 and atomic_2 equivalent? Are they atomic? Are they thread-safe? (Continuing a discussion from #rosettacode)
Feel free to edit this to heck and back; If it needs to be linked to, link to a specific revision.
volatile LONG var;
class statmux
{
public:
HANDLE hMux;
statmux()
{
// Initialize the mutex
hMux = CreateMutex(NULL, FALSE, NULL);
}
~statmux()
{
// Free the mutex
CloseHandle(hMux);
}
} s;
void atomic_1(LONG newval)
{
// Lock the mutex
DWORD res = WaitForSingleObject(s.hMux, INFINITE);
// WAIT_OBJECT_0 indicates that we hold the mutex. For these purposes, we don't care about any other scenario.
if(WAIT_OBJECT_0 != res)
return;
// Replace the file-static variable value with the value we were passed.
var = newval;
// Release the mutex
ReleaseMutex(s.hMux);
}
void atomic_2(LONG newval)
{
// InterlockedExchange sets up memory fences on either side of the load/store
// Theoretically, no other thread will see a mixture of the old and new value (i.e. tearing)
// Additionally, no other CPU will subsequently hold cached version of the old value.
InterlockedExchange(&var, newval);
}