
Michael van der Westhuizen wrote:
Ok, it looks like I spoke too soon. I was getting core dumps on weak_ptr_mt_test until I changed compare_and_swap to this:
inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) { __asm__ __volatile__( "cas [%2], %3, %0" : "=&r"(compare_), "=m"(*dest_) : "r"(dest_), "r"(compare_), "0"(swap_), "m"(*dest_) : "memory" ); return compare_; }
It's better if we can get an +m(*p)/=m(*p) formulation to work, instead of passing p in a register with r(p). It makes a difference in efficiency on platforms that can address an expression in addition to a single register, and on some architectures/modes when a C++ pointer is 32 bit but the hardware address is 64 bit, using r(p) truncates p to 32 bits and crashes. :-) Actually, the bug in the original seems to be that CAS returns the old value in swap_ and not compare_, so how about: inline int32_t compare_and_swap( int32_t * dest_, int32_t compare_, int32_t swap_ ) { __asm__ __volatile__( "cas %0, %2, %1" : "+m" (*dest_), "+r" (swap_) : "r" (compare_) : "memory" ); return swap_; }