Using xadd for different integer widths
I'm currently porting atomic.hpp out of boost for a project and would like to generalize the atomic add function whereby it's templated on the type to add:
template <typename T, typename V>
inline T add(volatile T* mem, V val)
{
T r;
asm volatile
(
"lock\n\t"
"xadd %1, %0":
"+m"( *mem ), "=r"( r 开发者_JS百科):
"1"( val ):
"memory", "cc"
);
return r;
}
I can't find a clear documentation as to wither it's safe to use signed and unsigned 8, 16, 32 and 64 bit numbers with this. Anyone know?
Yes, you can use lock xadd
under IA32 or IA64 with all types of numbers 8, 16, 32 and 64 bit signed or unsigned.
The memory alignment isn't needed but if it is, then the memory access is faster.
From Intel Manual:
The integrity of the LOCK prefix is not affected by the alignment of the memory field. Memory locking is observed for arbitrarily misaligned fields. This instruction’s operation is the same in non-64-bit modes and 64-bit mode.
Warning!:
If the LOCK prefix is used with XADD instruction and the source operand is a memory operand, an undefined opcode exception (#UD) may be generated.
So the source operand must be register and the destination operand is memory address!
精彩评论