Skip to content

Instantly share code, notes, and snippets.

@yohhoy
Last active August 29, 2015 13:56
Show Gist options
  • Save yohhoy/9225261 to your computer and use it in GitHub Desktop.
Save yohhoy/9225261 to your computer and use it in GitHub Desktop.
2 adjacent pointers swap with CMPXCHG8B instruction
#include <atomic>
// pointer pack
typedef struct {
int* p[2];
} pack_t;
void atomic_swap(std::atomic<pack_t>& pack)
{
pack_t actual{{nullptr, nullptr}};
pack_t expect = actual;
while (!pack.compare_exchange_weak(actual, expect)) {
expect.p[0] = actual.p[1];
expect.p[1] = actual.p[0];
}
}
int a, b;
// swap target
std::atomic<pack_t> pack({&a, &b});
atomic_swap(pack);
; $ gcc -std=c++11 -O2 atomicswap.cpp -S
__Z11atomic_swapRSt6atomicI6pack_tE:
pushl %edi
xorl %ecx, %ecx
pushl %esi
xorl %esi, %esi
pushl %ebx
subl $16, %esp
movl 32(%esp), %edi
movl $0, 8(%esp)
movl $0, 12(%esp)
jmp L2
.p2align 4,,7
L3:
movl 12(%esp), %esi
movl 8(%esp), %ecx
L2:
movl 8(%esp), %eax
movl %esi, %ebx
movl 12(%esp), %edx
lock cmpxchg8b (%edi)
movl %eax, 8(%esp)
movl %edx, 12(%esp)
jne L3
addl $16, %esp
popl %ebx
popl %esi
popl %edi
ret
@yohhoy
Copy link
Author

yohhoy commented Feb 26, 2014

CMPXCHG8B--Compare and Exchange 8 Bytes

IF (EDX:EAX == DEST)
ZF = 1
DEST = ECX:EBX
ELSE
ZF = 0
EDX:EAX = DEST

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment