qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH v5 07/18] qemu-thread: add simple test-and-set s


From: Sergey Fedorov
Subject: Re: [Qemu-devel] [PATCH v5 07/18] qemu-thread: add simple test-and-set spinlock
Date: Wed, 18 May 2016 18:05:11 +0300
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.2

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]