From: Ivan Maidanski Date: Wed, 2 Jan 2013 18:22:17 +0000 (+0400) Subject: Add generalized atomic and/or/xor operations for char/short/int types X-Git-Tag: libatomic_ops-7_4_0~51 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fa0473729bab33329dbc50ac8f2b26f77030829a;p=libatomic_ops Add generalized atomic and/or/xor operations for char/short/int types * src/atomic_ops/generalize-small.template (AO_XSIZE_and_full, AO_XSIZE_and_release, AO_XSIZE_and_acquire, AO_XSIZE_and_write, AO_XSIZE_and_read, AO_XSIZE_and, AO_XSIZE_and_release_write, AO_XSIZE_and_acquire_read, AO_XSIZE_or_full, AO_XSIZE_or_release, AO_XSIZE_or_acquire, AO_XSIZE_or_write, AO_XSIZE_or_read, AO_XSIZE_or, AO_XSIZE_or_release_write, AO_XSIZE_or_acquire_read, AO_XSIZE_xor_full, AO_XSIZE_xor_release, AO_XSIZE_xor_acquire, AO_XSIZE_xor_write, AO_XSIZE_xor_read, AO_XSIZE_xor, AO_XSIZE_xor_release_write, AO_XSIZE_xor_acquire_read): New template primitive (code copied from generalize.h for AO_t); define the corresponding AO_HAVE_x. * src/atomic_ops/generalize-small.h: Regenerate. * src/atomic_ops/generalize.h (AO_and_full, AO_and_release, AO_and_acquire, AO_and_write, AO_and_read, AO_and, AO_and_release_write, AO_and_acquire_read, AO_or_full, AO_or_release, AO_or_acquire, AO_or_write, AO_or_read, AO_xor, AO_or_release_write, AO_or_acquire_read, AO_xor_full, AO_xor_release, AO_xor_acquire, AO_xor_write, AO_xor_read, AO_xor, AO_xor_release_write, AO_xor_acquire_read): Remove (since present in the autogenerated generalize-small.h) together with the corresponding AO_HAVE_x. * src/atomic_ops/sysdeps/generic_pthread.h (AO_char_and_full, AO_char_or_full, AO_char_xor_full, AO_short_and_full, AO_short_or_full, AO_short_xor_full, AO_int_and_full, AO_int_or_full, AO_int_xor_full): Implement primitive (and define the corresponding AO_HAVE_x). --- diff --git a/src/atomic_ops/generalize-small.h b/src/atomic_ops/generalize-small.h index 06aebf9..0b6d5fb 100644 --- a/src/atomic_ops/generalize-small.h +++ b/src/atomic_ops/generalize-small.h @@ -654,6 +654,253 @@ # define AO_HAVE_char_fetch_and_sub1_dd_acquire_read # endif #endif /* !AO_NO_DD_ORDERING */ + +/* char_and */ +#if defined(AO_HAVE_char_compare_and_swap_full) \ + && !defined(AO_HAVE_char_and_full) + AO_INLINE void + AO_char_and_full(volatile unsigned/**/char *addr, unsigned/**/char value) + { + unsigned/**/char old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_full(addr, old, + old & value))); + } +# define AO_HAVE_char_and_full +#endif + +#if defined(AO_HAVE_char_and_full) +# if !defined(AO_HAVE_char_and_release) +# define AO_char_and_release(addr, val) AO_char_and_full(addr, val) +# define AO_HAVE_char_and_release +# endif +# if !defined(AO_HAVE_char_and_acquire) +# define AO_char_and_acquire(addr, val) AO_char_and_full(addr, val) +# define AO_HAVE_char_and_acquire +# endif +# if !defined(AO_HAVE_char_and_write) +# define AO_char_and_write(addr, val) AO_char_and_full(addr, val) +# define AO_HAVE_char_and_write +# endif +# if !defined(AO_HAVE_char_and_read) +# define AO_char_and_read(addr, val) AO_char_and_full(addr, val) +# define AO_HAVE_char_and_read +# endif +#endif /* AO_HAVE_char_and_full */ + +#if !defined(AO_HAVE_char_and) && defined(AO_HAVE_char_and_release) +# define AO_char_and(addr, val) AO_char_and_release(addr, val) +# define AO_HAVE_char_and +#endif +#if !defined(AO_HAVE_char_and) && defined(AO_HAVE_char_and_acquire) +# define AO_char_and(addr, val) AO_char_and_acquire(addr, val) +# define AO_HAVE_char_and +#endif +#if !defined(AO_HAVE_char_and) && defined(AO_HAVE_char_and_write) +# define AO_char_and(addr, val) AO_char_and_write(addr, val) +# define AO_HAVE_char_and +#endif +#if !defined(AO_HAVE_char_and) && defined(AO_HAVE_char_and_read) +# define AO_char_and(addr, val) AO_char_and_read(addr, val) +# define AO_HAVE_char_and +#endif + +#if defined(AO_HAVE_char_and_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_char_and_full) +# define AO_char_and_full(addr, val) \ + (AO_nop_full(), AO_char_and_acquire(addr, val)) +# define AO_HAVE_char_and_full +#endif + +#if !defined(AO_HAVE_char_and_release_write) \ + && defined(AO_HAVE_char_and_write) +# define AO_char_and_release_write(addr, val) AO_char_and_write(addr, val) +# define AO_HAVE_char_and_release_write +#endif +#if !defined(AO_HAVE_char_and_release_write) \ + && defined(AO_HAVE_char_and_release) +# define AO_char_and_release_write(addr, val) AO_char_and_release(addr, val) +# define AO_HAVE_char_and_release_write +#endif +#if !defined(AO_HAVE_char_and_acquire_read) \ + && defined(AO_HAVE_char_and_read) +# define AO_char_and_acquire_read(addr, val) AO_char_and_read(addr, val) +# define AO_HAVE_char_and_acquire_read +#endif +#if !defined(AO_HAVE_char_and_acquire_read) \ + && defined(AO_HAVE_char_and_acquire) +# define AO_char_and_acquire_read(addr, val) AO_char_and_acquire(addr, val) +# define AO_HAVE_char_and_acquire_read +#endif + +/* char_or */ +#if defined(AO_HAVE_char_compare_and_swap_full) \ + && !defined(AO_HAVE_char_or_full) + AO_INLINE void + AO_char_or_full(volatile unsigned/**/char *addr, unsigned/**/char value) + { + unsigned/**/char old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_full(addr, old, + old | value))); + } +# define AO_HAVE_char_or_full +#endif + +#if defined(AO_HAVE_char_or_full) +# if !defined(AO_HAVE_char_or_release) +# define AO_char_or_release(addr, val) AO_char_or_full(addr, val) +# define AO_HAVE_char_or_release +# endif +# if !defined(AO_HAVE_char_or_acquire) +# define AO_char_or_acquire(addr, val) AO_char_or_full(addr, val) +# define AO_HAVE_char_or_acquire +# endif +# if !defined(AO_HAVE_char_or_write) +# define AO_char_or_write(addr, val) AO_char_or_full(addr, val) +# define AO_HAVE_char_or_write +# endif +# if !defined(AO_HAVE_char_or_read) +# define AO_char_or_read(addr, val) AO_char_or_full(addr, val) +# define AO_HAVE_char_or_read +# endif +#endif /* AO_HAVE_char_or_full */ + +#if !defined(AO_HAVE_char_or) && defined(AO_HAVE_char_or_release) +# define AO_char_or(addr, val) AO_char_or_release(addr, val) +# define AO_HAVE_char_or +#endif +#if !defined(AO_HAVE_char_or) && defined(AO_HAVE_char_or_acquire) +# define AO_char_or(addr, val) AO_char_or_acquire(addr, val) +# define AO_HAVE_char_or +#endif +#if !defined(AO_HAVE_char_or) && defined(AO_HAVE_char_or_write) +# define AO_char_or(addr, val) AO_char_or_write(addr, val) +# define AO_HAVE_char_or +#endif +#if !defined(AO_HAVE_char_or) && defined(AO_HAVE_char_or_read) +# define AO_char_or(addr, val) AO_char_or_read(addr, val) +# define AO_HAVE_char_or +#endif + +#if defined(AO_HAVE_char_or_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_char_or_full) +# define AO_char_or_full(addr, val) \ + (AO_nop_full(), AO_char_or_acquire(addr, val)) +# define AO_HAVE_char_or_full +#endif + +#if !defined(AO_HAVE_char_or_release_write) \ + && defined(AO_HAVE_char_or_write) +# define AO_char_or_release_write(addr, val) AO_char_or_write(addr, val) +# define AO_HAVE_char_or_release_write +#endif +#if !defined(AO_HAVE_char_or_release_write) \ + && defined(AO_HAVE_char_or_release) +# define AO_char_or_release_write(addr, val) AO_char_or_release(addr, val) +# define AO_HAVE_char_or_release_write +#endif +#if !defined(AO_HAVE_char_or_acquire_read) && defined(AO_HAVE_char_or_read) +# define AO_char_or_acquire_read(addr, val) AO_char_or_read(addr, val) +# define AO_HAVE_char_or_acquire_read +#endif +#if !defined(AO_HAVE_char_or_acquire_read) \ + && defined(AO_HAVE_char_or_acquire) +# define AO_char_or_acquire_read(addr, val) AO_char_or_acquire(addr, val) +# define AO_HAVE_char_or_acquire_read +#endif + +/* char_xor */ +#if defined(AO_HAVE_char_compare_and_swap_full) \ + && !defined(AO_HAVE_char_xor_full) + AO_INLINE void + AO_char_xor_full(volatile unsigned/**/char *addr, unsigned/**/char value) + { + unsigned/**/char old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_char_compare_and_swap_full(addr, old, + old ^ value))); + } +# define AO_HAVE_char_xor_full +#endif + +#if defined(AO_HAVE_char_xor_full) +# if !defined(AO_HAVE_char_xor_release) +# define AO_char_xor_release(addr, val) AO_char_xor_full(addr, val) +# define AO_HAVE_char_xor_release +# endif +# if !defined(AO_HAVE_char_xor_acquire) +# define AO_char_xor_acquire(addr, val) AO_char_xor_full(addr, val) +# define AO_HAVE_char_xor_acquire +# endif +# if !defined(AO_HAVE_char_xor_write) +# define AO_char_xor_write(addr, val) AO_char_xor_full(addr, val) +# define AO_HAVE_char_xor_write +# endif +# if !defined(AO_HAVE_char_xor_read) +# define AO_char_xor_read(addr, val) AO_char_xor_full(addr, val) +# define AO_HAVE_char_xor_read +# endif +#endif /* AO_HAVE_char_xor_full */ + +#if !defined(AO_HAVE_char_xor) && defined(AO_HAVE_char_xor_release) +# define AO_char_xor(addr, val) AO_char_xor_release(addr, val) +# define AO_HAVE_char_xor +#endif +#if !defined(AO_HAVE_char_xor) && defined(AO_HAVE_char_xor_acquire) +# define AO_char_xor(addr, val) AO_char_xor_acquire(addr, val) +# define AO_HAVE_char_xor +#endif +#if !defined(AO_HAVE_char_xor) && defined(AO_HAVE_char_xor_write) +# define AO_char_xor(addr, val) AO_char_xor_write(addr, val) +# define AO_HAVE_char_xor +#endif +#if !defined(AO_HAVE_char_xor) && defined(AO_HAVE_char_xor_read) +# define AO_char_xor(addr, val) AO_char_xor_read(addr, val) +# define AO_HAVE_char_xor +#endif + +#if defined(AO_HAVE_char_xor_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_char_xor_full) +# define AO_char_xor_full(addr, val) \ + (AO_nop_full(), AO_char_xor_acquire(addr, val)) +# define AO_HAVE_char_xor_full +#endif + +#if !defined(AO_HAVE_char_xor_release_write) \ + && defined(AO_HAVE_char_xor_write) +# define AO_char_xor_release_write(addr, val) AO_char_xor_write(addr, val) +# define AO_HAVE_char_xor_release_write +#endif +#if !defined(AO_HAVE_char_xor_release_write) \ + && defined(AO_HAVE_char_xor_release) +# define AO_char_xor_release_write(addr, val) AO_char_xor_release(addr, val) +# define AO_HAVE_char_xor_release_write +#endif +#if !defined(AO_HAVE_char_xor_acquire_read) \ + && defined(AO_HAVE_char_xor_read) +# define AO_char_xor_acquire_read(addr, val) AO_char_xor_read(addr, val) +# define AO_HAVE_char_xor_acquire_read +#endif +#if !defined(AO_HAVE_char_xor_acquire_read) \ + && defined(AO_HAVE_char_xor_acquire) +# define AO_char_xor_acquire_read(addr, val) AO_char_xor_acquire(addr, val) +# define AO_HAVE_char_xor_acquire_read +#endif + +/* char_and/or/xor_dd_aquire_read are meaningless. */ /* * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P. * @@ -1310,6 +1557,253 @@ # define AO_HAVE_short_fetch_and_sub1_dd_acquire_read # endif #endif /* !AO_NO_DD_ORDERING */ + +/* short_and */ +#if defined(AO_HAVE_short_compare_and_swap_full) \ + && !defined(AO_HAVE_short_and_full) + AO_INLINE void + AO_short_and_full(volatile unsigned/**/short *addr, unsigned/**/short value) + { + unsigned/**/short old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_full(addr, old, + old & value))); + } +# define AO_HAVE_short_and_full +#endif + +#if defined(AO_HAVE_short_and_full) +# if !defined(AO_HAVE_short_and_release) +# define AO_short_and_release(addr, val) AO_short_and_full(addr, val) +# define AO_HAVE_short_and_release +# endif +# if !defined(AO_HAVE_short_and_acquire) +# define AO_short_and_acquire(addr, val) AO_short_and_full(addr, val) +# define AO_HAVE_short_and_acquire +# endif +# if !defined(AO_HAVE_short_and_write) +# define AO_short_and_write(addr, val) AO_short_and_full(addr, val) +# define AO_HAVE_short_and_write +# endif +# if !defined(AO_HAVE_short_and_read) +# define AO_short_and_read(addr, val) AO_short_and_full(addr, val) +# define AO_HAVE_short_and_read +# endif +#endif /* AO_HAVE_short_and_full */ + +#if !defined(AO_HAVE_short_and) && defined(AO_HAVE_short_and_release) +# define AO_short_and(addr, val) AO_short_and_release(addr, val) +# define AO_HAVE_short_and +#endif +#if !defined(AO_HAVE_short_and) && defined(AO_HAVE_short_and_acquire) +# define AO_short_and(addr, val) AO_short_and_acquire(addr, val) +# define AO_HAVE_short_and +#endif +#if !defined(AO_HAVE_short_and) && defined(AO_HAVE_short_and_write) +# define AO_short_and(addr, val) AO_short_and_write(addr, val) +# define AO_HAVE_short_and +#endif +#if !defined(AO_HAVE_short_and) && defined(AO_HAVE_short_and_read) +# define AO_short_and(addr, val) AO_short_and_read(addr, val) +# define AO_HAVE_short_and +#endif + +#if defined(AO_HAVE_short_and_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_short_and_full) +# define AO_short_and_full(addr, val) \ + (AO_nop_full(), AO_short_and_acquire(addr, val)) +# define AO_HAVE_short_and_full +#endif + +#if !defined(AO_HAVE_short_and_release_write) \ + && defined(AO_HAVE_short_and_write) +# define AO_short_and_release_write(addr, val) AO_short_and_write(addr, val) +# define AO_HAVE_short_and_release_write +#endif +#if !defined(AO_HAVE_short_and_release_write) \ + && defined(AO_HAVE_short_and_release) +# define AO_short_and_release_write(addr, val) AO_short_and_release(addr, val) +# define AO_HAVE_short_and_release_write +#endif +#if !defined(AO_HAVE_short_and_acquire_read) \ + && defined(AO_HAVE_short_and_read) +# define AO_short_and_acquire_read(addr, val) AO_short_and_read(addr, val) +# define AO_HAVE_short_and_acquire_read +#endif +#if !defined(AO_HAVE_short_and_acquire_read) \ + && defined(AO_HAVE_short_and_acquire) +# define AO_short_and_acquire_read(addr, val) AO_short_and_acquire(addr, val) +# define AO_HAVE_short_and_acquire_read +#endif + +/* short_or */ +#if defined(AO_HAVE_short_compare_and_swap_full) \ + && !defined(AO_HAVE_short_or_full) + AO_INLINE void + AO_short_or_full(volatile unsigned/**/short *addr, unsigned/**/short value) + { + unsigned/**/short old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_full(addr, old, + old | value))); + } +# define AO_HAVE_short_or_full +#endif + +#if defined(AO_HAVE_short_or_full) +# if !defined(AO_HAVE_short_or_release) +# define AO_short_or_release(addr, val) AO_short_or_full(addr, val) +# define AO_HAVE_short_or_release +# endif +# if !defined(AO_HAVE_short_or_acquire) +# define AO_short_or_acquire(addr, val) AO_short_or_full(addr, val) +# define AO_HAVE_short_or_acquire +# endif +# if !defined(AO_HAVE_short_or_write) +# define AO_short_or_write(addr, val) AO_short_or_full(addr, val) +# define AO_HAVE_short_or_write +# endif +# if !defined(AO_HAVE_short_or_read) +# define AO_short_or_read(addr, val) AO_short_or_full(addr, val) +# define AO_HAVE_short_or_read +# endif +#endif /* AO_HAVE_short_or_full */ + +#if !defined(AO_HAVE_short_or) && defined(AO_HAVE_short_or_release) +# define AO_short_or(addr, val) AO_short_or_release(addr, val) +# define AO_HAVE_short_or +#endif +#if !defined(AO_HAVE_short_or) && defined(AO_HAVE_short_or_acquire) +# define AO_short_or(addr, val) AO_short_or_acquire(addr, val) +# define AO_HAVE_short_or +#endif +#if !defined(AO_HAVE_short_or) && defined(AO_HAVE_short_or_write) +# define AO_short_or(addr, val) AO_short_or_write(addr, val) +# define AO_HAVE_short_or +#endif +#if !defined(AO_HAVE_short_or) && defined(AO_HAVE_short_or_read) +# define AO_short_or(addr, val) AO_short_or_read(addr, val) +# define AO_HAVE_short_or +#endif + +#if defined(AO_HAVE_short_or_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_short_or_full) +# define AO_short_or_full(addr, val) \ + (AO_nop_full(), AO_short_or_acquire(addr, val)) +# define AO_HAVE_short_or_full +#endif + +#if !defined(AO_HAVE_short_or_release_write) \ + && defined(AO_HAVE_short_or_write) +# define AO_short_or_release_write(addr, val) AO_short_or_write(addr, val) +# define AO_HAVE_short_or_release_write +#endif +#if !defined(AO_HAVE_short_or_release_write) \ + && defined(AO_HAVE_short_or_release) +# define AO_short_or_release_write(addr, val) AO_short_or_release(addr, val) +# define AO_HAVE_short_or_release_write +#endif +#if !defined(AO_HAVE_short_or_acquire_read) && defined(AO_HAVE_short_or_read) +# define AO_short_or_acquire_read(addr, val) AO_short_or_read(addr, val) +# define AO_HAVE_short_or_acquire_read +#endif +#if !defined(AO_HAVE_short_or_acquire_read) \ + && defined(AO_HAVE_short_or_acquire) +# define AO_short_or_acquire_read(addr, val) AO_short_or_acquire(addr, val) +# define AO_HAVE_short_or_acquire_read +#endif + +/* short_xor */ +#if defined(AO_HAVE_short_compare_and_swap_full) \ + && !defined(AO_HAVE_short_xor_full) + AO_INLINE void + AO_short_xor_full(volatile unsigned/**/short *addr, unsigned/**/short value) + { + unsigned/**/short old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_short_compare_and_swap_full(addr, old, + old ^ value))); + } +# define AO_HAVE_short_xor_full +#endif + +#if defined(AO_HAVE_short_xor_full) +# if !defined(AO_HAVE_short_xor_release) +# define AO_short_xor_release(addr, val) AO_short_xor_full(addr, val) +# define AO_HAVE_short_xor_release +# endif +# if !defined(AO_HAVE_short_xor_acquire) +# define AO_short_xor_acquire(addr, val) AO_short_xor_full(addr, val) +# define AO_HAVE_short_xor_acquire +# endif +# if !defined(AO_HAVE_short_xor_write) +# define AO_short_xor_write(addr, val) AO_short_xor_full(addr, val) +# define AO_HAVE_short_xor_write +# endif +# if !defined(AO_HAVE_short_xor_read) +# define AO_short_xor_read(addr, val) AO_short_xor_full(addr, val) +# define AO_HAVE_short_xor_read +# endif +#endif /* AO_HAVE_short_xor_full */ + +#if !defined(AO_HAVE_short_xor) && defined(AO_HAVE_short_xor_release) +# define AO_short_xor(addr, val) AO_short_xor_release(addr, val) +# define AO_HAVE_short_xor +#endif +#if !defined(AO_HAVE_short_xor) && defined(AO_HAVE_short_xor_acquire) +# define AO_short_xor(addr, val) AO_short_xor_acquire(addr, val) +# define AO_HAVE_short_xor +#endif +#if !defined(AO_HAVE_short_xor) && defined(AO_HAVE_short_xor_write) +# define AO_short_xor(addr, val) AO_short_xor_write(addr, val) +# define AO_HAVE_short_xor +#endif +#if !defined(AO_HAVE_short_xor) && defined(AO_HAVE_short_xor_read) +# define AO_short_xor(addr, val) AO_short_xor_read(addr, val) +# define AO_HAVE_short_xor +#endif + +#if defined(AO_HAVE_short_xor_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_short_xor_full) +# define AO_short_xor_full(addr, val) \ + (AO_nop_full(), AO_short_xor_acquire(addr, val)) +# define AO_HAVE_short_xor_full +#endif + +#if !defined(AO_HAVE_short_xor_release_write) \ + && defined(AO_HAVE_short_xor_write) +# define AO_short_xor_release_write(addr, val) AO_short_xor_write(addr, val) +# define AO_HAVE_short_xor_release_write +#endif +#if !defined(AO_HAVE_short_xor_release_write) \ + && defined(AO_HAVE_short_xor_release) +# define AO_short_xor_release_write(addr, val) AO_short_xor_release(addr, val) +# define AO_HAVE_short_xor_release_write +#endif +#if !defined(AO_HAVE_short_xor_acquire_read) \ + && defined(AO_HAVE_short_xor_read) +# define AO_short_xor_acquire_read(addr, val) AO_short_xor_read(addr, val) +# define AO_HAVE_short_xor_acquire_read +#endif +#if !defined(AO_HAVE_short_xor_acquire_read) \ + && defined(AO_HAVE_short_xor_acquire) +# define AO_short_xor_acquire_read(addr, val) AO_short_xor_acquire(addr, val) +# define AO_HAVE_short_xor_acquire_read +#endif + +/* short_and/or/xor_dd_aquire_read are meaningless. */ /* * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P. * @@ -1966,6 +2460,253 @@ # define AO_HAVE_int_fetch_and_sub1_dd_acquire_read # endif #endif /* !AO_NO_DD_ORDERING */ + +/* int_and */ +#if defined(AO_HAVE_int_compare_and_swap_full) \ + && !defined(AO_HAVE_int_and_full) + AO_INLINE void + AO_int_and_full(volatile unsigned *addr, unsigned value) + { + unsigned old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_full(addr, old, + old & value))); + } +# define AO_HAVE_int_and_full +#endif + +#if defined(AO_HAVE_int_and_full) +# if !defined(AO_HAVE_int_and_release) +# define AO_int_and_release(addr, val) AO_int_and_full(addr, val) +# define AO_HAVE_int_and_release +# endif +# if !defined(AO_HAVE_int_and_acquire) +# define AO_int_and_acquire(addr, val) AO_int_and_full(addr, val) +# define AO_HAVE_int_and_acquire +# endif +# if !defined(AO_HAVE_int_and_write) +# define AO_int_and_write(addr, val) AO_int_and_full(addr, val) +# define AO_HAVE_int_and_write +# endif +# if !defined(AO_HAVE_int_and_read) +# define AO_int_and_read(addr, val) AO_int_and_full(addr, val) +# define AO_HAVE_int_and_read +# endif +#endif /* AO_HAVE_int_and_full */ + +#if !defined(AO_HAVE_int_and) && defined(AO_HAVE_int_and_release) +# define AO_int_and(addr, val) AO_int_and_release(addr, val) +# define AO_HAVE_int_and +#endif +#if !defined(AO_HAVE_int_and) && defined(AO_HAVE_int_and_acquire) +# define AO_int_and(addr, val) AO_int_and_acquire(addr, val) +# define AO_HAVE_int_and +#endif +#if !defined(AO_HAVE_int_and) && defined(AO_HAVE_int_and_write) +# define AO_int_and(addr, val) AO_int_and_write(addr, val) +# define AO_HAVE_int_and +#endif +#if !defined(AO_HAVE_int_and) && defined(AO_HAVE_int_and_read) +# define AO_int_and(addr, val) AO_int_and_read(addr, val) +# define AO_HAVE_int_and +#endif + +#if defined(AO_HAVE_int_and_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_int_and_full) +# define AO_int_and_full(addr, val) \ + (AO_nop_full(), AO_int_and_acquire(addr, val)) +# define AO_HAVE_int_and_full +#endif + +#if !defined(AO_HAVE_int_and_release_write) \ + && defined(AO_HAVE_int_and_write) +# define AO_int_and_release_write(addr, val) AO_int_and_write(addr, val) +# define AO_HAVE_int_and_release_write +#endif +#if !defined(AO_HAVE_int_and_release_write) \ + && defined(AO_HAVE_int_and_release) +# define AO_int_and_release_write(addr, val) AO_int_and_release(addr, val) +# define AO_HAVE_int_and_release_write +#endif +#if !defined(AO_HAVE_int_and_acquire_read) \ + && defined(AO_HAVE_int_and_read) +# define AO_int_and_acquire_read(addr, val) AO_int_and_read(addr, val) +# define AO_HAVE_int_and_acquire_read +#endif +#if !defined(AO_HAVE_int_and_acquire_read) \ + && defined(AO_HAVE_int_and_acquire) +# define AO_int_and_acquire_read(addr, val) AO_int_and_acquire(addr, val) +# define AO_HAVE_int_and_acquire_read +#endif + +/* int_or */ +#if defined(AO_HAVE_int_compare_and_swap_full) \ + && !defined(AO_HAVE_int_or_full) + AO_INLINE void + AO_int_or_full(volatile unsigned *addr, unsigned value) + { + unsigned old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_full(addr, old, + old | value))); + } +# define AO_HAVE_int_or_full +#endif + +#if defined(AO_HAVE_int_or_full) +# if !defined(AO_HAVE_int_or_release) +# define AO_int_or_release(addr, val) AO_int_or_full(addr, val) +# define AO_HAVE_int_or_release +# endif +# if !defined(AO_HAVE_int_or_acquire) +# define AO_int_or_acquire(addr, val) AO_int_or_full(addr, val) +# define AO_HAVE_int_or_acquire +# endif +# if !defined(AO_HAVE_int_or_write) +# define AO_int_or_write(addr, val) AO_int_or_full(addr, val) +# define AO_HAVE_int_or_write +# endif +# if !defined(AO_HAVE_int_or_read) +# define AO_int_or_read(addr, val) AO_int_or_full(addr, val) +# define AO_HAVE_int_or_read +# endif +#endif /* AO_HAVE_int_or_full */ + +#if !defined(AO_HAVE_int_or) && defined(AO_HAVE_int_or_release) +# define AO_int_or(addr, val) AO_int_or_release(addr, val) +# define AO_HAVE_int_or +#endif +#if !defined(AO_HAVE_int_or) && defined(AO_HAVE_int_or_acquire) +# define AO_int_or(addr, val) AO_int_or_acquire(addr, val) +# define AO_HAVE_int_or +#endif +#if !defined(AO_HAVE_int_or) && defined(AO_HAVE_int_or_write) +# define AO_int_or(addr, val) AO_int_or_write(addr, val) +# define AO_HAVE_int_or +#endif +#if !defined(AO_HAVE_int_or) && defined(AO_HAVE_int_or_read) +# define AO_int_or(addr, val) AO_int_or_read(addr, val) +# define AO_HAVE_int_or +#endif + +#if defined(AO_HAVE_int_or_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_int_or_full) +# define AO_int_or_full(addr, val) \ + (AO_nop_full(), AO_int_or_acquire(addr, val)) +# define AO_HAVE_int_or_full +#endif + +#if !defined(AO_HAVE_int_or_release_write) \ + && defined(AO_HAVE_int_or_write) +# define AO_int_or_release_write(addr, val) AO_int_or_write(addr, val) +# define AO_HAVE_int_or_release_write +#endif +#if !defined(AO_HAVE_int_or_release_write) \ + && defined(AO_HAVE_int_or_release) +# define AO_int_or_release_write(addr, val) AO_int_or_release(addr, val) +# define AO_HAVE_int_or_release_write +#endif +#if !defined(AO_HAVE_int_or_acquire_read) && defined(AO_HAVE_int_or_read) +# define AO_int_or_acquire_read(addr, val) AO_int_or_read(addr, val) +# define AO_HAVE_int_or_acquire_read +#endif +#if !defined(AO_HAVE_int_or_acquire_read) \ + && defined(AO_HAVE_int_or_acquire) +# define AO_int_or_acquire_read(addr, val) AO_int_or_acquire(addr, val) +# define AO_HAVE_int_or_acquire_read +#endif + +/* int_xor */ +#if defined(AO_HAVE_int_compare_and_swap_full) \ + && !defined(AO_HAVE_int_xor_full) + AO_INLINE void + AO_int_xor_full(volatile unsigned *addr, unsigned value) + { + unsigned old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_int_compare_and_swap_full(addr, old, + old ^ value))); + } +# define AO_HAVE_int_xor_full +#endif + +#if defined(AO_HAVE_int_xor_full) +# if !defined(AO_HAVE_int_xor_release) +# define AO_int_xor_release(addr, val) AO_int_xor_full(addr, val) +# define AO_HAVE_int_xor_release +# endif +# if !defined(AO_HAVE_int_xor_acquire) +# define AO_int_xor_acquire(addr, val) AO_int_xor_full(addr, val) +# define AO_HAVE_int_xor_acquire +# endif +# if !defined(AO_HAVE_int_xor_write) +# define AO_int_xor_write(addr, val) AO_int_xor_full(addr, val) +# define AO_HAVE_int_xor_write +# endif +# if !defined(AO_HAVE_int_xor_read) +# define AO_int_xor_read(addr, val) AO_int_xor_full(addr, val) +# define AO_HAVE_int_xor_read +# endif +#endif /* AO_HAVE_int_xor_full */ + +#if !defined(AO_HAVE_int_xor) && defined(AO_HAVE_int_xor_release) +# define AO_int_xor(addr, val) AO_int_xor_release(addr, val) +# define AO_HAVE_int_xor +#endif +#if !defined(AO_HAVE_int_xor) && defined(AO_HAVE_int_xor_acquire) +# define AO_int_xor(addr, val) AO_int_xor_acquire(addr, val) +# define AO_HAVE_int_xor +#endif +#if !defined(AO_HAVE_int_xor) && defined(AO_HAVE_int_xor_write) +# define AO_int_xor(addr, val) AO_int_xor_write(addr, val) +# define AO_HAVE_int_xor +#endif +#if !defined(AO_HAVE_int_xor) && defined(AO_HAVE_int_xor_read) +# define AO_int_xor(addr, val) AO_int_xor_read(addr, val) +# define AO_HAVE_int_xor +#endif + +#if defined(AO_HAVE_int_xor_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_int_xor_full) +# define AO_int_xor_full(addr, val) \ + (AO_nop_full(), AO_int_xor_acquire(addr, val)) +# define AO_HAVE_int_xor_full +#endif + +#if !defined(AO_HAVE_int_xor_release_write) \ + && defined(AO_HAVE_int_xor_write) +# define AO_int_xor_release_write(addr, val) AO_int_xor_write(addr, val) +# define AO_HAVE_int_xor_release_write +#endif +#if !defined(AO_HAVE_int_xor_release_write) \ + && defined(AO_HAVE_int_xor_release) +# define AO_int_xor_release_write(addr, val) AO_int_xor_release(addr, val) +# define AO_HAVE_int_xor_release_write +#endif +#if !defined(AO_HAVE_int_xor_acquire_read) \ + && defined(AO_HAVE_int_xor_read) +# define AO_int_xor_acquire_read(addr, val) AO_int_xor_read(addr, val) +# define AO_HAVE_int_xor_acquire_read +#endif +#if !defined(AO_HAVE_int_xor_acquire_read) \ + && defined(AO_HAVE_int_xor_acquire) +# define AO_int_xor_acquire_read(addr, val) AO_int_xor_acquire(addr, val) +# define AO_HAVE_int_xor_acquire_read +#endif + +/* int_and/or/xor_dd_aquire_read are meaningless. */ /* * Copyright (c) 2003-2011 Hewlett-Packard Development Company, L.P. * @@ -2622,3 +3363,250 @@ # define AO_HAVE_fetch_and_sub1_dd_acquire_read # endif #endif /* !AO_NO_DD_ORDERING */ + +/* and */ +#if defined(AO_HAVE_compare_and_swap_full) \ + && !defined(AO_HAVE_and_full) + AO_INLINE void + AO_and_full(volatile AO_t *addr, AO_t value) + { + AO_t old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, + old & value))); + } +# define AO_HAVE_and_full +#endif + +#if defined(AO_HAVE_and_full) +# if !defined(AO_HAVE_and_release) +# define AO_and_release(addr, val) AO_and_full(addr, val) +# define AO_HAVE_and_release +# endif +# if !defined(AO_HAVE_and_acquire) +# define AO_and_acquire(addr, val) AO_and_full(addr, val) +# define AO_HAVE_and_acquire +# endif +# if !defined(AO_HAVE_and_write) +# define AO_and_write(addr, val) AO_and_full(addr, val) +# define AO_HAVE_and_write +# endif +# if !defined(AO_HAVE_and_read) +# define AO_and_read(addr, val) AO_and_full(addr, val) +# define AO_HAVE_and_read +# endif +#endif /* AO_HAVE_and_full */ + +#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_release) +# define AO_and(addr, val) AO_and_release(addr, val) +# define AO_HAVE_and +#endif +#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_acquire) +# define AO_and(addr, val) AO_and_acquire(addr, val) +# define AO_HAVE_and +#endif +#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_write) +# define AO_and(addr, val) AO_and_write(addr, val) +# define AO_HAVE_and +#endif +#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_read) +# define AO_and(addr, val) AO_and_read(addr, val) +# define AO_HAVE_and +#endif + +#if defined(AO_HAVE_and_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_and_full) +# define AO_and_full(addr, val) \ + (AO_nop_full(), AO_and_acquire(addr, val)) +# define AO_HAVE_and_full +#endif + +#if !defined(AO_HAVE_and_release_write) \ + && defined(AO_HAVE_and_write) +# define AO_and_release_write(addr, val) AO_and_write(addr, val) +# define AO_HAVE_and_release_write +#endif +#if !defined(AO_HAVE_and_release_write) \ + && defined(AO_HAVE_and_release) +# define AO_and_release_write(addr, val) AO_and_release(addr, val) +# define AO_HAVE_and_release_write +#endif +#if !defined(AO_HAVE_and_acquire_read) \ + && defined(AO_HAVE_and_read) +# define AO_and_acquire_read(addr, val) AO_and_read(addr, val) +# define AO_HAVE_and_acquire_read +#endif +#if !defined(AO_HAVE_and_acquire_read) \ + && defined(AO_HAVE_and_acquire) +# define AO_and_acquire_read(addr, val) AO_and_acquire(addr, val) +# define AO_HAVE_and_acquire_read +#endif + +/* or */ +#if defined(AO_HAVE_compare_and_swap_full) \ + && !defined(AO_HAVE_or_full) + AO_INLINE void + AO_or_full(volatile AO_t *addr, AO_t value) + { + AO_t old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, + old | value))); + } +# define AO_HAVE_or_full +#endif + +#if defined(AO_HAVE_or_full) +# if !defined(AO_HAVE_or_release) +# define AO_or_release(addr, val) AO_or_full(addr, val) +# define AO_HAVE_or_release +# endif +# if !defined(AO_HAVE_or_acquire) +# define AO_or_acquire(addr, val) AO_or_full(addr, val) +# define AO_HAVE_or_acquire +# endif +# if !defined(AO_HAVE_or_write) +# define AO_or_write(addr, val) AO_or_full(addr, val) +# define AO_HAVE_or_write +# endif +# if !defined(AO_HAVE_or_read) +# define AO_or_read(addr, val) AO_or_full(addr, val) +# define AO_HAVE_or_read +# endif +#endif /* AO_HAVE_or_full */ + +#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_release) +# define AO_or(addr, val) AO_or_release(addr, val) +# define AO_HAVE_or +#endif +#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_acquire) +# define AO_or(addr, val) AO_or_acquire(addr, val) +# define AO_HAVE_or +#endif +#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_write) +# define AO_or(addr, val) AO_or_write(addr, val) +# define AO_HAVE_or +#endif +#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_read) +# define AO_or(addr, val) AO_or_read(addr, val) +# define AO_HAVE_or +#endif + +#if defined(AO_HAVE_or_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_or_full) +# define AO_or_full(addr, val) \ + (AO_nop_full(), AO_or_acquire(addr, val)) +# define AO_HAVE_or_full +#endif + +#if !defined(AO_HAVE_or_release_write) \ + && defined(AO_HAVE_or_write) +# define AO_or_release_write(addr, val) AO_or_write(addr, val) +# define AO_HAVE_or_release_write +#endif +#if !defined(AO_HAVE_or_release_write) \ + && defined(AO_HAVE_or_release) +# define AO_or_release_write(addr, val) AO_or_release(addr, val) +# define AO_HAVE_or_release_write +#endif +#if !defined(AO_HAVE_or_acquire_read) && defined(AO_HAVE_or_read) +# define AO_or_acquire_read(addr, val) AO_or_read(addr, val) +# define AO_HAVE_or_acquire_read +#endif +#if !defined(AO_HAVE_or_acquire_read) \ + && defined(AO_HAVE_or_acquire) +# define AO_or_acquire_read(addr, val) AO_or_acquire(addr, val) +# define AO_HAVE_or_acquire_read +#endif + +/* xor */ +#if defined(AO_HAVE_compare_and_swap_full) \ + && !defined(AO_HAVE_xor_full) + AO_INLINE void + AO_xor_full(volatile AO_t *addr, AO_t value) + { + AO_t old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, + old ^ value))); + } +# define AO_HAVE_xor_full +#endif + +#if defined(AO_HAVE_xor_full) +# if !defined(AO_HAVE_xor_release) +# define AO_xor_release(addr, val) AO_xor_full(addr, val) +# define AO_HAVE_xor_release +# endif +# if !defined(AO_HAVE_xor_acquire) +# define AO_xor_acquire(addr, val) AO_xor_full(addr, val) +# define AO_HAVE_xor_acquire +# endif +# if !defined(AO_HAVE_xor_write) +# define AO_xor_write(addr, val) AO_xor_full(addr, val) +# define AO_HAVE_xor_write +# endif +# if !defined(AO_HAVE_xor_read) +# define AO_xor_read(addr, val) AO_xor_full(addr, val) +# define AO_HAVE_xor_read +# endif +#endif /* AO_HAVE_xor_full */ + +#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_release) +# define AO_xor(addr, val) AO_xor_release(addr, val) +# define AO_HAVE_xor +#endif +#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_acquire) +# define AO_xor(addr, val) AO_xor_acquire(addr, val) +# define AO_HAVE_xor +#endif +#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_write) +# define AO_xor(addr, val) AO_xor_write(addr, val) +# define AO_HAVE_xor +#endif +#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_read) +# define AO_xor(addr, val) AO_xor_read(addr, val) +# define AO_HAVE_xor +#endif + +#if defined(AO_HAVE_xor_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_xor_full) +# define AO_xor_full(addr, val) \ + (AO_nop_full(), AO_xor_acquire(addr, val)) +# define AO_HAVE_xor_full +#endif + +#if !defined(AO_HAVE_xor_release_write) \ + && defined(AO_HAVE_xor_write) +# define AO_xor_release_write(addr, val) AO_xor_write(addr, val) +# define AO_HAVE_xor_release_write +#endif +#if !defined(AO_HAVE_xor_release_write) \ + && defined(AO_HAVE_xor_release) +# define AO_xor_release_write(addr, val) AO_xor_release(addr, val) +# define AO_HAVE_xor_release_write +#endif +#if !defined(AO_HAVE_xor_acquire_read) \ + && defined(AO_HAVE_xor_read) +# define AO_xor_acquire_read(addr, val) AO_xor_read(addr, val) +# define AO_HAVE_xor_acquire_read +#endif +#if !defined(AO_HAVE_xor_acquire_read) \ + && defined(AO_HAVE_xor_acquire) +# define AO_xor_acquire_read(addr, val) AO_xor_acquire(addr, val) +# define AO_HAVE_xor_acquire_read +#endif + +/* and/or/xor_dd_aquire_read are meaningless. */ diff --git a/src/atomic_ops/generalize-small.template b/src/atomic_ops/generalize-small.template index b56430e..ba824b5 100644 --- a/src/atomic_ops/generalize-small.template +++ b/src/atomic_ops/generalize-small.template @@ -654,3 +654,250 @@ # define AO_HAVE_XSIZE_fetch_and_sub1_dd_acquire_read # endif #endif /* !AO_NO_DD_ORDERING */ + +/* XSIZE_and */ +#if defined(AO_HAVE_XSIZE_compare_and_swap_full) \ + && !defined(AO_HAVE_XSIZE_and_full) + AO_INLINE void + AO_XSIZE_and_full(volatile XCTYPE *addr, XCTYPE value) + { + XCTYPE old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_full(addr, old, + old & value))); + } +# define AO_HAVE_XSIZE_and_full +#endif + +#if defined(AO_HAVE_XSIZE_and_full) +# if !defined(AO_HAVE_XSIZE_and_release) +# define AO_XSIZE_and_release(addr, val) AO_XSIZE_and_full(addr, val) +# define AO_HAVE_XSIZE_and_release +# endif +# if !defined(AO_HAVE_XSIZE_and_acquire) +# define AO_XSIZE_and_acquire(addr, val) AO_XSIZE_and_full(addr, val) +# define AO_HAVE_XSIZE_and_acquire +# endif +# if !defined(AO_HAVE_XSIZE_and_write) +# define AO_XSIZE_and_write(addr, val) AO_XSIZE_and_full(addr, val) +# define AO_HAVE_XSIZE_and_write +# endif +# if !defined(AO_HAVE_XSIZE_and_read) +# define AO_XSIZE_and_read(addr, val) AO_XSIZE_and_full(addr, val) +# define AO_HAVE_XSIZE_and_read +# endif +#endif /* AO_HAVE_XSIZE_and_full */ + +#if !defined(AO_HAVE_XSIZE_and) && defined(AO_HAVE_XSIZE_and_release) +# define AO_XSIZE_and(addr, val) AO_XSIZE_and_release(addr, val) +# define AO_HAVE_XSIZE_and +#endif +#if !defined(AO_HAVE_XSIZE_and) && defined(AO_HAVE_XSIZE_and_acquire) +# define AO_XSIZE_and(addr, val) AO_XSIZE_and_acquire(addr, val) +# define AO_HAVE_XSIZE_and +#endif +#if !defined(AO_HAVE_XSIZE_and) && defined(AO_HAVE_XSIZE_and_write) +# define AO_XSIZE_and(addr, val) AO_XSIZE_and_write(addr, val) +# define AO_HAVE_XSIZE_and +#endif +#if !defined(AO_HAVE_XSIZE_and) && defined(AO_HAVE_XSIZE_and_read) +# define AO_XSIZE_and(addr, val) AO_XSIZE_and_read(addr, val) +# define AO_HAVE_XSIZE_and +#endif + +#if defined(AO_HAVE_XSIZE_and_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_XSIZE_and_full) +# define AO_XSIZE_and_full(addr, val) \ + (AO_nop_full(), AO_XSIZE_and_acquire(addr, val)) +# define AO_HAVE_XSIZE_and_full +#endif + +#if !defined(AO_HAVE_XSIZE_and_release_write) \ + && defined(AO_HAVE_XSIZE_and_write) +# define AO_XSIZE_and_release_write(addr, val) AO_XSIZE_and_write(addr, val) +# define AO_HAVE_XSIZE_and_release_write +#endif +#if !defined(AO_HAVE_XSIZE_and_release_write) \ + && defined(AO_HAVE_XSIZE_and_release) +# define AO_XSIZE_and_release_write(addr, val) AO_XSIZE_and_release(addr, val) +# define AO_HAVE_XSIZE_and_release_write +#endif +#if !defined(AO_HAVE_XSIZE_and_acquire_read) \ + && defined(AO_HAVE_XSIZE_and_read) +# define AO_XSIZE_and_acquire_read(addr, val) AO_XSIZE_and_read(addr, val) +# define AO_HAVE_XSIZE_and_acquire_read +#endif +#if !defined(AO_HAVE_XSIZE_and_acquire_read) \ + && defined(AO_HAVE_XSIZE_and_acquire) +# define AO_XSIZE_and_acquire_read(addr, val) AO_XSIZE_and_acquire(addr, val) +# define AO_HAVE_XSIZE_and_acquire_read +#endif + +/* XSIZE_or */ +#if defined(AO_HAVE_XSIZE_compare_and_swap_full) \ + && !defined(AO_HAVE_XSIZE_or_full) + AO_INLINE void + AO_XSIZE_or_full(volatile XCTYPE *addr, XCTYPE value) + { + XCTYPE old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_full(addr, old, + old | value))); + } +# define AO_HAVE_XSIZE_or_full +#endif + +#if defined(AO_HAVE_XSIZE_or_full) +# if !defined(AO_HAVE_XSIZE_or_release) +# define AO_XSIZE_or_release(addr, val) AO_XSIZE_or_full(addr, val) +# define AO_HAVE_XSIZE_or_release +# endif +# if !defined(AO_HAVE_XSIZE_or_acquire) +# define AO_XSIZE_or_acquire(addr, val) AO_XSIZE_or_full(addr, val) +# define AO_HAVE_XSIZE_or_acquire +# endif +# if !defined(AO_HAVE_XSIZE_or_write) +# define AO_XSIZE_or_write(addr, val) AO_XSIZE_or_full(addr, val) +# define AO_HAVE_XSIZE_or_write +# endif +# if !defined(AO_HAVE_XSIZE_or_read) +# define AO_XSIZE_or_read(addr, val) AO_XSIZE_or_full(addr, val) +# define AO_HAVE_XSIZE_or_read +# endif +#endif /* AO_HAVE_XSIZE_or_full */ + +#if !defined(AO_HAVE_XSIZE_or) && defined(AO_HAVE_XSIZE_or_release) +# define AO_XSIZE_or(addr, val) AO_XSIZE_or_release(addr, val) +# define AO_HAVE_XSIZE_or +#endif +#if !defined(AO_HAVE_XSIZE_or) && defined(AO_HAVE_XSIZE_or_acquire) +# define AO_XSIZE_or(addr, val) AO_XSIZE_or_acquire(addr, val) +# define AO_HAVE_XSIZE_or +#endif +#if !defined(AO_HAVE_XSIZE_or) && defined(AO_HAVE_XSIZE_or_write) +# define AO_XSIZE_or(addr, val) AO_XSIZE_or_write(addr, val) +# define AO_HAVE_XSIZE_or +#endif +#if !defined(AO_HAVE_XSIZE_or) && defined(AO_HAVE_XSIZE_or_read) +# define AO_XSIZE_or(addr, val) AO_XSIZE_or_read(addr, val) +# define AO_HAVE_XSIZE_or +#endif + +#if defined(AO_HAVE_XSIZE_or_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_XSIZE_or_full) +# define AO_XSIZE_or_full(addr, val) \ + (AO_nop_full(), AO_XSIZE_or_acquire(addr, val)) +# define AO_HAVE_XSIZE_or_full +#endif + +#if !defined(AO_HAVE_XSIZE_or_release_write) \ + && defined(AO_HAVE_XSIZE_or_write) +# define AO_XSIZE_or_release_write(addr, val) AO_XSIZE_or_write(addr, val) +# define AO_HAVE_XSIZE_or_release_write +#endif +#if !defined(AO_HAVE_XSIZE_or_release_write) \ + && defined(AO_HAVE_XSIZE_or_release) +# define AO_XSIZE_or_release_write(addr, val) AO_XSIZE_or_release(addr, val) +# define AO_HAVE_XSIZE_or_release_write +#endif +#if !defined(AO_HAVE_XSIZE_or_acquire_read) && defined(AO_HAVE_XSIZE_or_read) +# define AO_XSIZE_or_acquire_read(addr, val) AO_XSIZE_or_read(addr, val) +# define AO_HAVE_XSIZE_or_acquire_read +#endif +#if !defined(AO_HAVE_XSIZE_or_acquire_read) \ + && defined(AO_HAVE_XSIZE_or_acquire) +# define AO_XSIZE_or_acquire_read(addr, val) AO_XSIZE_or_acquire(addr, val) +# define AO_HAVE_XSIZE_or_acquire_read +#endif + +/* XSIZE_xor */ +#if defined(AO_HAVE_XSIZE_compare_and_swap_full) \ + && !defined(AO_HAVE_XSIZE_xor_full) + AO_INLINE void + AO_XSIZE_xor_full(volatile XCTYPE *addr, XCTYPE value) + { + XCTYPE old; + + do + { + old = *addr; + } + while (AO_EXPECT_FALSE(!AO_XSIZE_compare_and_swap_full(addr, old, + old ^ value))); + } +# define AO_HAVE_XSIZE_xor_full +#endif + +#if defined(AO_HAVE_XSIZE_xor_full) +# if !defined(AO_HAVE_XSIZE_xor_release) +# define AO_XSIZE_xor_release(addr, val) AO_XSIZE_xor_full(addr, val) +# define AO_HAVE_XSIZE_xor_release +# endif +# if !defined(AO_HAVE_XSIZE_xor_acquire) +# define AO_XSIZE_xor_acquire(addr, val) AO_XSIZE_xor_full(addr, val) +# define AO_HAVE_XSIZE_xor_acquire +# endif +# if !defined(AO_HAVE_XSIZE_xor_write) +# define AO_XSIZE_xor_write(addr, val) AO_XSIZE_xor_full(addr, val) +# define AO_HAVE_XSIZE_xor_write +# endif +# if !defined(AO_HAVE_XSIZE_xor_read) +# define AO_XSIZE_xor_read(addr, val) AO_XSIZE_xor_full(addr, val) +# define AO_HAVE_XSIZE_xor_read +# endif +#endif /* AO_HAVE_XSIZE_xor_full */ + +#if !defined(AO_HAVE_XSIZE_xor) && defined(AO_HAVE_XSIZE_xor_release) +# define AO_XSIZE_xor(addr, val) AO_XSIZE_xor_release(addr, val) +# define AO_HAVE_XSIZE_xor +#endif +#if !defined(AO_HAVE_XSIZE_xor) && defined(AO_HAVE_XSIZE_xor_acquire) +# define AO_XSIZE_xor(addr, val) AO_XSIZE_xor_acquire(addr, val) +# define AO_HAVE_XSIZE_xor +#endif +#if !defined(AO_HAVE_XSIZE_xor) && defined(AO_HAVE_XSIZE_xor_write) +# define AO_XSIZE_xor(addr, val) AO_XSIZE_xor_write(addr, val) +# define AO_HAVE_XSIZE_xor +#endif +#if !defined(AO_HAVE_XSIZE_xor) && defined(AO_HAVE_XSIZE_xor_read) +# define AO_XSIZE_xor(addr, val) AO_XSIZE_xor_read(addr, val) +# define AO_HAVE_XSIZE_xor +#endif + +#if defined(AO_HAVE_XSIZE_xor_acquire) && defined(AO_HAVE_nop_full) \ + && !defined(AO_HAVE_XSIZE_xor_full) +# define AO_XSIZE_xor_full(addr, val) \ + (AO_nop_full(), AO_XSIZE_xor_acquire(addr, val)) +# define AO_HAVE_XSIZE_xor_full +#endif + +#if !defined(AO_HAVE_XSIZE_xor_release_write) \ + && defined(AO_HAVE_XSIZE_xor_write) +# define AO_XSIZE_xor_release_write(addr, val) AO_XSIZE_xor_write(addr, val) +# define AO_HAVE_XSIZE_xor_release_write +#endif +#if !defined(AO_HAVE_XSIZE_xor_release_write) \ + && defined(AO_HAVE_XSIZE_xor_release) +# define AO_XSIZE_xor_release_write(addr, val) AO_XSIZE_xor_release(addr, val) +# define AO_HAVE_XSIZE_xor_release_write +#endif +#if !defined(AO_HAVE_XSIZE_xor_acquire_read) \ + && defined(AO_HAVE_XSIZE_xor_read) +# define AO_XSIZE_xor_acquire_read(addr, val) AO_XSIZE_xor_read(addr, val) +# define AO_HAVE_XSIZE_xor_acquire_read +#endif +#if !defined(AO_HAVE_XSIZE_xor_acquire_read) \ + && defined(AO_HAVE_XSIZE_xor_acquire) +# define AO_XSIZE_xor_acquire_read(addr, val) AO_XSIZE_xor_acquire(addr, val) +# define AO_HAVE_XSIZE_xor_acquire_read +#endif + +/* XSIZE_and/or/xor_dd_aquire_read are meaningless. */ diff --git a/src/atomic_ops/generalize.h b/src/atomic_ops/generalize.h index dd6b1b8..2318289 100644 --- a/src/atomic_ops/generalize.h +++ b/src/atomic_ops/generalize.h @@ -231,230 +231,6 @@ # define AO_HAVE_test_and_set_acquire #endif -/* Atomic "and" */ -#if defined(AO_HAVE_compare_and_swap_full) && !defined(AO_HAVE_and_full) - AO_INLINE void - AO_and_full(volatile AO_t *addr, AO_t value) - { - AO_t old; - do - { - old = *addr; - } - while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old & value))); - } -# define AO_HAVE_and_full -#endif - -#if defined(AO_HAVE_and_full) -# if !defined(AO_HAVE_and_release) -# define AO_and_release(addr,val) AO_and_full(addr,val) -# define AO_HAVE_and_release -# endif -# if !defined(AO_HAVE_and_acquire) -# define AO_and_acquire(addr,val) AO_and_full(addr,val) -# define AO_HAVE_and_acquire -# endif -# if !defined(AO_HAVE_and_write) -# define AO_and_write(addr,val) AO_and_full(addr,val) -# define AO_HAVE_and_write -# endif -# if !defined(AO_HAVE_and_read) -# define AO_and_read(addr,val) AO_and_full(addr,val) -# define AO_HAVE_and_read -# endif -#endif /* AO_HAVE_and_full */ - -#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_release) -# define AO_and(addr,val) AO_and_release(addr,val) -# define AO_HAVE_and -#endif -#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_acquire) -# define AO_and(addr,val) AO_and_acquire(addr,val) -# define AO_HAVE_and -#endif -#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_write) -# define AO_and(addr,val) AO_and_write(addr,val) -# define AO_HAVE_and -#endif -#if !defined(AO_HAVE_and) && defined(AO_HAVE_and_read) -# define AO_and(addr,val) AO_and_read(addr,val) -# define AO_HAVE_and -#endif - -#if defined(AO_HAVE_and_acquire) && defined(AO_HAVE_nop_full) \ - && !defined(AO_HAVE_and_full) -# define AO_and_full(addr,val) (AO_nop_full(), AO_and_acquire(addr,val)) -# define AO_HAVE_and_full -#endif - -#if !defined(AO_HAVE_and_release_write) && defined(AO_HAVE_and_write) -# define AO_and_release_write(addr,val) AO_and_write(addr,val) -# define AO_HAVE_and_release_write -#endif -#if !defined(AO_HAVE_and_release_write) && defined(AO_HAVE_and_release) -# define AO_and_release_write(addr,val) AO_and_release(addr,val) -# define AO_HAVE_and_release_write -#endif -#if !defined(AO_HAVE_and_acquire_read) && defined(AO_HAVE_and_read) -# define AO_and_acquire_read(addr,val) AO_and_read(addr,val) -# define AO_HAVE_and_acquire_read -#endif -#if !defined(AO_HAVE_and_acquire_read) && defined(AO_HAVE_and_acquire) -# define AO_and_acquire_read(addr,val) AO_and_acquire(addr,val) -# define AO_HAVE_and_acquire_read -#endif - -/* Atomic "or" */ -#if defined(AO_HAVE_compare_and_swap_full) && !defined(AO_HAVE_or_full) - AO_INLINE void - AO_or_full(volatile AO_t *addr, AO_t value) - { - AO_t old; - do - { - old = *addr; - } - while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old | value))); - } -# define AO_HAVE_or_full -#endif - -#if defined(AO_HAVE_or_full) -# if !defined(AO_HAVE_or_release) -# define AO_or_release(addr,val) AO_or_full(addr,val) -# define AO_HAVE_or_release -# endif -# if !defined(AO_HAVE_or_acquire) -# define AO_or_acquire(addr,val) AO_or_full(addr,val) -# define AO_HAVE_or_acquire -# endif -# if !defined(AO_HAVE_or_write) -# define AO_or_write(addr,val) AO_or_full(addr,val) -# define AO_HAVE_or_write -# endif -# if !defined(AO_HAVE_or_read) -# define AO_or_read(addr,val) AO_or_full(addr,val) -# define AO_HAVE_or_read -# endif -#endif /* AO_HAVE_or_full */ - -#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_release) -# define AO_or(addr,val) AO_or_release(addr,val) -# define AO_HAVE_or -#endif -#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_acquire) -# define AO_or(addr,val) AO_or_acquire(addr,val) -# define AO_HAVE_or -#endif -#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_write) -# define AO_or(addr,val) AO_or_write(addr,val) -# define AO_HAVE_or -#endif -#if !defined(AO_HAVE_or) && defined(AO_HAVE_or_read) -# define AO_or(addr,val) AO_or_read(addr,val) -# define AO_HAVE_or -#endif - -#if defined(AO_HAVE_or_acquire) && defined(AO_HAVE_nop_full) \ - && !defined(AO_HAVE_or_full) -# define AO_or_full(addr,val) (AO_nop_full(), AO_or_acquire(addr,val)) -# define AO_HAVE_or_full -#endif - -#if !defined(AO_HAVE_or_release_write) && defined(AO_HAVE_or_write) -# define AO_or_release_write(addr,val) AO_or_write(addr,val) -# define AO_HAVE_or_release_write -#endif -#if !defined(AO_HAVE_or_release_write) && defined(AO_HAVE_or_release) -# define AO_or_release_write(addr,val) AO_or_release(addr,val) -# define AO_HAVE_or_release_write -#endif -#if !defined(AO_HAVE_or_acquire_read) && defined(AO_HAVE_or_read) -# define AO_or_acquire_read(addr,val) AO_or_read(addr,val) -# define AO_HAVE_or_acquire_read -#endif -#if !defined(AO_HAVE_or_acquire_read) && defined(AO_HAVE_or_acquire) -# define AO_or_acquire_read(addr,val) AO_or_acquire(addr,val) -# define AO_HAVE_or_acquire_read -#endif - -/* Atomic "xor" */ -#if defined(AO_HAVE_compare_and_swap_full) && !defined(AO_HAVE_xor_full) - AO_INLINE void - AO_xor_full(volatile AO_t *addr, AO_t value) - { - AO_t old; - do - { - old = *addr; - } - while (AO_EXPECT_FALSE(!AO_compare_and_swap_full(addr, old, old ^ value))); - } -# define AO_HAVE_xor_full -#endif - -#if defined(AO_HAVE_xor_full) -# if !defined(AO_HAVE_xor_release) -# define AO_xor_release(addr,val) AO_xor_full(addr,val) -# define AO_HAVE_xor_release -# endif -# if !defined(AO_HAVE_xor_acquire) -# define AO_xor_acquire(addr,val) AO_xor_full(addr,val) -# define AO_HAVE_xor_acquire -# endif -# if !defined(AO_HAVE_xor_write) -# define AO_xor_write(addr,val) AO_xor_full(addr,val) -# define AO_HAVE_xor_write -# endif -# if !defined(AO_HAVE_xor_read) -# define AO_xor_read(addr,val) AO_xor_full(addr,val) -# define AO_HAVE_xor_read -# endif -#endif /* AO_HAVE_xor_full */ - -#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_release) -# define AO_xor(addr,val) AO_xor_release(addr,val) -# define AO_HAVE_xor -#endif -#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_acquire) -# define AO_xor(addr,val) AO_xor_acquire(addr,val) -# define AO_HAVE_xor -#endif -#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_write) -# define AO_xor(addr,val) AO_xor_write(addr,val) -# define AO_HAVE_xor -#endif -#if !defined(AO_HAVE_xor) && defined(AO_HAVE_xor_read) -# define AO_xor(addr,val) AO_xor_read(addr,val) -# define AO_HAVE_xor -#endif - -#if defined(AO_HAVE_xor_acquire) && defined(AO_HAVE_nop_full) \ - && !defined(AO_HAVE_xor_full) -# define AO_xor_full(addr,val) (AO_nop_full(), AO_xor_acquire(addr,val)) -# define AO_HAVE_xor_full -#endif - -#if !defined(AO_HAVE_xor_release_write) && defined(AO_HAVE_xor_write) -# define AO_xor_release_write(addr,val) AO_xor_write(addr,val) -# define AO_HAVE_xor_release_write -#endif -#if !defined(AO_HAVE_xor_release_write) && defined(AO_HAVE_xor_release) -# define AO_xor_release_write(addr,val) AO_xor_release(addr,val) -# define AO_HAVE_xor_release_write -#endif -#if !defined(AO_HAVE_xor_acquire_read) && defined(AO_HAVE_xor_read) -# define AO_xor_acquire_read(addr,val) AO_xor_read(addr,val) -# define AO_HAVE_xor_acquire_read -#endif -#if !defined(AO_HAVE_xor_acquire_read) && defined(AO_HAVE_xor_acquire) -# define AO_xor_acquire_read(addr,val) AO_xor_acquire(addr,val) -# define AO_HAVE_xor_acquire_read -#endif - -/* dd_aquire_read is meaningless. */ - /* Test_and_set */ #if defined(AO_HAVE_test_and_set_full) # if !defined(AO_HAVE_test_and_set_release) diff --git a/src/atomic_ops/sysdeps/generic_pthread.h b/src/atomic_ops/sysdeps/generic_pthread.h index 2adaf54..aaf8ca1 100644 --- a/src/atomic_ops/sysdeps/generic_pthread.h +++ b/src/atomic_ops/sysdeps/generic_pthread.h @@ -217,6 +217,87 @@ AO_xor_full(volatile AO_t *p, AO_t value) } #define AO_HAVE_xor_full +AO_INLINE void +AO_char_and_full(volatile unsigned char *p, unsigned char value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p &= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_char_and_full + +AO_INLINE void +AO_char_or_full(volatile unsigned char *p, unsigned char value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p |= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_char_or_full + +AO_INLINE void +AO_char_xor_full(volatile unsigned char *p, unsigned char value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p ^= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_char_xor_full + +AO_INLINE void +AO_short_and_full(volatile unsigned short *p, unsigned short value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p &= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_short_and_full + +AO_INLINE void +AO_short_or_full(volatile unsigned short *p, unsigned short value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p |= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_short_or_full + +AO_INLINE void +AO_short_xor_full(volatile unsigned short *p, unsigned short value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p ^= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_short_xor_full + +AO_INLINE void +AO_int_and_full(volatile unsigned *p, unsigned value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p &= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_int_and_full + +AO_INLINE void +AO_int_or_full(volatile unsigned *p, unsigned value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p |= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_int_or_full + +AO_INLINE void +AO_int_xor_full(volatile unsigned *p, unsigned value) +{ + pthread_mutex_lock(&AO_pt_lock); + *p ^= value; + pthread_mutex_unlock(&AO_pt_lock); +} +#define AO_HAVE_int_xor_full + AO_INLINE AO_t AO_fetch_compare_and_swap_full(volatile AO_t *addr, AO_t old_val, AO_t new_val)