I have a C++ project, run rightly compiled by gcc-4.1.2-46 and gcc-4.4.5-6
But it has an abnormal dead loop while compiled by gcc-4.4.6-3 using -O2.
I use gdb to
I suspect the problem is in your loop in BitLock::lock
:
while (true)
{
uint8_t ov = bits_[byte_index];
if (ov & BIT_MASKS[bit_index])
{
continue;
}
if (ov == ATOMIC_CAS(&(bits_[byte_index]), ov, ov | BIT_MASKS[bit_index]))
{
break;
}
}
The __sync_val_compare_and_swap
in your ATOMIC_CAS
macro will act as memory barrier, preventing the compiler/processor from speculating loads across it, but it won't do anything about loads before it, so the condition ov & BIT_MASKS[bit_index]
could be optimized based on the value of bits_[byte_index]
before the __sync_val_compare_and_swap
call and thus resulting in an infinite loop.
Try the following, instead:
while (true)
{
uint8_t ov = bits_[byte_index];
if (ov & BIT_MASKS[bit_index])
{
__sync_synchronize(); // or define ATOMIC_SYNC if you prefer
continue;
}
if (ov == ATOMIC_CAS(&(bits_[byte_index]), ov, ov | BIT_MASKS[bit_index]))
{
break;
}
}
The __sync_synchronize
memory barrier will prevent the loop from degenerating into a trivial one.
Update:
The _Unwind_Resume
function will
Resume the unwind process, called at the end of cleanup code that didn't return to the normal thread of execution (ie, not a catch).
See The Secret Life of C++: Day 3: Exceptions
which according to this
It's needed for pthread_cancel. It resumes unwinding after a cleanup.
So it seems there is an exception in a thread for which there is no catch
... given that the behavior is different with different versions of gcc and different optimization levels I would venture that you are using threads and have a race condition.