Hi, On Mon, Oct 10, 2016 at 9:59 AM, Paolo Bonzini <pbonz...@redhat.com> wrote: > This introduces load-acquire and store-release operations in QEMU. > For now, just use them as an implementation detail of atomic_mb_read > and atomic_mb_set. > > Since docs/atomics.txt documents that atomic_mb_read only synchronizes > with an atomic_mb_set of the same variable, we can use the new implementation > everywhere instead of seq-cst loads and stores. > > Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> > --- > docs/atomics.txt | 5 +-- > include/qemu/atomic.h | 93 > +++++++++++++++++---------------------------------- > 2 files changed, 34 insertions(+), 64 deletions(-) > > diff --git a/docs/atomics.txt b/docs/atomics.txt > index 5cd8e32..9a1f8aa 100644 > --- a/docs/atomics.txt > +++ b/docs/atomics.txt > @@ -374,8 +374,9 @@ and memory barriers, and the equivalents in QEMU: > note that smp_store_mb() is a little weaker than atomic_mb_set(). > atomic_mb_read() compiles to the same instructions as Linux's > smp_load_acquire(), but this should be treated as an implementation > - detail. If required, QEMU might later add atomic_load_acquire() and > - atomic_store_release() macros. > + detail. QEMU does have atomic_load_acquire() and atomic_store_release() > + macros, but for now they are only used within atomic.h. This may > + change in the future. > > > SOURCES > diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h > index b108df0..d940e98 100644 > --- a/include/qemu/atomic.h > +++ b/include/qemu/atomic.h > @@ -135,44 +135,18 @@ > __atomic_store_n(ptr, i, __ATOMIC_RELEASE); \ > } while(0) > > -/* atomic_mb_read/set semantics map Java volatile variables. They are > - * less expensive on some platforms (notably POWER & ARMv7) than fully > - * sequentially consistent operations. > - * > - * As long as they are used as paired operations they are safe to > - * use. See docs/atomic.txt for more discussion. > - */ > - > -#if defined(_ARCH_PPC) > -#define atomic_mb_read(ptr) \ > - ({ \ > - QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ > - typeof_strip_qual(*ptr) _val; \ > - __atomic_load(ptr, &_val, __ATOMIC_RELAXED); \ > - smp_mb_acquire(); \ > - _val; \ > - }) > - > -#define atomic_mb_set(ptr, i) do { \ > - QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ > - smp_mb_release(); \ > - __atomic_store_n(ptr, i, __ATOMIC_RELAXED); \ > - smp_mb(); \ > -} while(0) > -#else > -#define atomic_mb_read(ptr) \ > +#define atomic_load_acquire(ptr) \ > ({ \ > QEMU_BUILD_BUG_ON(sizeof(*ptr) > sizeof(void *)); \ > typeof_strip_qual(*ptr) _val; \ > - __atomic_load(ptr, &_val, __ATOMIC_SEQ_CST); \ > + __atomic_load(ptr, &_val, __ATOMIC_ACQUIRE); \ > _val; \ > }) >
Is there any reason we are not using __atomic_load_n() here? -- Pranith