In my attempt to develope a thread-safe C++ weak pointer template class, I need to check a flag that indicating the object is still alive, if yes then increment the object's reference count and I need to do the both steps atomically.
I know the existance of intrinsics functions provided by the compiler, for instance _InterlockedCompareExchange() and _InterlockedIncrement(). But what I want is an interlockedCompareIncrement() function, is there an efficient way to simulate this intrinsic using other primitives, at least on the Windows x86 platform?
In computer science, the fetch-and-add CPU instruction (FAA) atomically increments the contents of a memory location by a specified value. That is, fetch-and-add performs the operation increment the value at address x by a, where x is a memory location and a is some value, and return the original value at x.
Although globalVariable++ was executed 1000 times, the final value of globalVariable was 797. It proves that the + + increment operator in Java is not atomic.
During an atomic operation, a processor can read and write a location during the same data transmission. In this way, another input/output mechanism or processor cannot perform memory reading or writing tasks until the atomic operation has finished.
Suppose that value
is your flag variable. It should be declared volatile
.
long curvalue;
long newvalue;
do
{
curvalue = value;
newvalue = curvalue + 1;
}
while( _InterlockedCompareExchange( &value, newvalue, curvalue ) != curvalue );
As you see you can generalize this to whatever kind of arithmetic you need by changing the operations that are applied to calculate newvalue
.
If you want to compare two values at the same time, your best bet is to pack both values into a single variable, and then operate on that single variable. Since you're using a flag combined with a reference count, I'd recommend using the lowest bit of value
as the 'alive' flag, and then increment/decrement by 2 at a time. This allows you to encode both the flag and the reference count into a single 32-bit variable.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With