Reputation: 51
The function as it looks to me is working fine. I am trying to implement a counter for a multi threaded application. As the counter value can be beyond the integer range, I using 64 bit for it. I am not very sure about the thread safety as, here we are dealing with 64 bit numbers.
UINT64 get_and_increment(volatile UINT64* dest) {
UINT64 old_value, new_value;
bool result = false;
while(!result) {
old_value = *dest;
new_value = old_value + 1;
__asm__ volatile (
"lock cmpxchg %3, %1 \n setzb %0"
: "=m"(result), "+m" (*dest)
: "a" (old_value), "r"(new_value)
);
}
return old_value;
}
Thanks
Sudhanshu Shukla
Upvotes: 0
Views: 311
Reputation: 204718
Why not use GCC's built-in atomic intrinsics?
UINT64 get_and_increment(volatile UINT64* dest) {
UINT64 old_value, new_value;
do {
old_value = *dest;
new_value = old_value + 1;
} while (!__sync_bool_compare_and_swap(dest, old_value, new_value));
return old_value;
}
Or even
UINT64 get_and_increment(volatile UINT64* dest) {
return __sync_fetch_and_add(dest, 1);
}
That being said, your assembly won't work on 32-bit platforms (lack of a 64-bit lock cmpxchg
), and would be simpler written as lock xadd
without a loop, but otherwise looks like it would work on 64-bit.
Upvotes: 2