Last active
August 29, 2015 13:56
-
-
Save yohhoy/9225261 to your computer and use it in GitHub Desktop.
2 adjacent pointers swap with CMPXCHG8B instruction
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; $ 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
CMPXCHG8B--Compare and Exchange 8 Bytes
IF (EDX:EAX == DEST)
ZF = 1
DEST = ECX:EBX
ELSE
ZF = 0
EDX:EAX = DEST