how to do an atomic copy of 128-bit number in gcc inline x86_64 asm?
I haven't done assembly since school (eons ago) and have never done any x86, but I have found a pesky bug in old existing code where somebody isn't doing an atomic op where they should be. The person who wrote 开发者_开发知识库the code is long gone and nobody around here knows the answer to my question. What I need to do is create an atomic copy for 128-bit values. The code I currently have is as follows:
void atomic_copy128(volatile void* dest,volatile const void* source) {
#if PLATFORM_BITS == 64
#ifdef __INTEL_COMPILER
//For IA64 platform using intel compiler
*((__int64*)source)=__load128((__int64*)dest,((__int64*)source)+1);
#else
//For x86_64 compiled with gcc
__asm__ __volatile__("lock ; movq %0,%1"
: "=r"(*((volatile long *)(source)))
: "r"(*((volatile long *)(dest)))
: "memory");
#endif
#else
#error "128 bit operations not supported on this platform."
#endif
}
This isn't the code that I originally tried, since I've messed with it quite a bit while trying get it to compile and run. When I make it a totally invalid instruction, it does not compile. When I run this, it executes until it hits this line and then generates a "Illegal instruction" error message. I'd appreciate any help.
As far as I know, "movq" supports at most one memory operand, and its arguments are of 64-bit size anyway, so even if two memory operands were supported, it still wouldn't give you that atomic 128-bit copy you're looking for.
For windows:
::memset( dst, -1, 16 );
_InterlockedCompareExchange128(source, -1, -1, dst );
(but const
must be deleted)
For other use cmpxchg16b
instruction
精彩评论