On 18/05/16 17:59, Paolo Bonzini wrote: > > On 18/05/2016 16:47, Sergey Fedorov wrote: >>>>>> Why not? AFAIK the reason to avoid __sync primitives is that in most >>>>>> cases >>>>>> they include barriers that callers might not necessarily need; __atomic's >>>>>> allow for finer tuning, which is in general a good thing. However, >>>>>> __sync_test_and_set has the exact semantics we need, without the >>>>>> limitations >>>>>> documented for __atomic_test_and_set; so why not use it? >>>> So it should be okay as long as the legacy build-ins are supported. >> However, there's also __atomic_compare_exchange_n(). Could it be the choice? > cmpxchg is not TAS. I don't see any reason not to use > __sync_test_and_set, the only sensible alternative is to ignore the > standard and use __atomic_test_and_set on int.
Please look at this: $ cat >a.c <<EOF int atomic_exchange(int *x, int v) { return __atomic_exchange_n(x, v, __ATOMIC_ACQUIRE); } _Bool atomic_compare_exchange(int *x, int o, int n) { return __atomic_compare_exchange_n(x, &o, n, 1, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); } _Bool sync_val_compare_and_swap(int *x, int o, int n) { return __sync_val_compare_and_swap(x, 0, n); } int sync_lock_test_and_set(int *x, int v) { __sync_lock_test_and_set(x, v); } EOF $ arm-linux-gnueabi-gcc -march=armv6 -O2 -c a.c $ arm-linux-gnueabi-objdump -d a.o a.o: file format elf32-littlearm Disassembly of section .text: 00000000 <atomic_exchange>: 0: e1902f9f ldrex r2, [r0] 4: e1803f91 strex r3, r1, [r0] 8: e3530000 cmp r3, #0 c: 1afffffb bne 0 <atomic_exchange> 10: ee070fba mcr 15, 0, r0, cr7, cr10, {5} 14: e1a00002 mov r0, r2 18: e12fff1e bx lr 0000001c <atomic_compare_exchange>: 1c: e24dd008 sub sp, sp, #8 20: e58d1004 str r1, [sp, #4] 24: e1903f9f ldrex r3, [r0] 28: e1530001 cmp r3, r1 2c: 1a000002 bne 3c <atomic_compare_exchange+0x20> 30: e180cf92 strex ip, r2, [r0] 34: e35c0000 cmp ip, #0 38: ee070fba mcr 15, 0, r0, cr7, cr10, {5} 3c: 13a00000 movne r0, #0 40: 03a00001 moveq r0, #1 44: e28dd008 add sp, sp, #8 48: e12fff1e bx lr 0000004c <sync_val_compare_and_swap>: 4c: ee070fba mcr 15, 0, r0, cr7, cr10, {5} 50: e1901f9f ldrex r1, [r0] 54: e3510000 cmp r1, #0 58: 1a000002 bne 68 <sync_val_compare_and_swap+0x1c> 5c: e1803f92 strex r3, r2, [r0] 60: e3530000 cmp r3, #0 64: 1afffff9 bne 50 <sync_val_compare_and_swap+0x4> 68: e2910000 adds r0, r1, #0 6c: ee070fba mcr 15, 0, r0, cr7, cr10, {5} 70: 13a00001 movne r0, #1 74: e12fff1e bx lr 00000078 <sync_lock_test_and_set>: 78: e1902f9f ldrex r2, [r0] 7c: e1803f91 strex r3, r1, [r0] 80: e3530000 cmp r3, #0 84: 1afffffb bne 78 <sync_lock_test_and_set> 88: ee070fba mcr 15, 0, r0, cr7, cr10, {5} 8c: e12fff1e bx lr atomic_compare_exchange() looks pretty good, doesn't it? Could we use it to implement qemu_spin_lock()? Kind regards, Sergey