* Paolo Bonzini ([email protected]) wrote: > These are useful to flip single bits.
I'm trying to figure out the semantic of these operations. are they uatomic_add / uatomic_or or uatomic_add_return / uatomic_or_return ? Thanks, Mathieu > > Signed-off-by: Paolo Bonzini <[email protected]> > --- > tests/test_uatomic.c | 6 ++ > urcu/uatomic_generic.h | 220 > ++++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 226 insertions(+), 0 deletions(-) > > diff --git a/tests/test_uatomic.c b/tests/test_uatomic.c > index 5682655..f14ed56 100644 > --- a/tests/test_uatomic.c > +++ b/tests/test_uatomic.c > @@ -39,6 +39,12 @@ do { \ > v = uatomic_sub_return(ptr, 1); \ > assert(v == 121); \ > assert(uatomic_read(ptr) == 121); \ > + v = uatomic_and(ptr, 0x47); \ > + assert(v == 121); \ > + assert(uatomic_read(ptr) == 0x41); \ > + v = uatomic_or(ptr, 120); \ > + assert(v == 0x41); \ > + assert(uatomic_read(ptr) == 121); \ > } while (0) > > int main(int argc, char **argv) > diff --git a/urcu/uatomic_generic.h b/urcu/uatomic_generic.h > index 383ddfa..7f3bc00 100644 > --- a/urcu/uatomic_generic.h > +++ b/urcu/uatomic_generic.h > @@ -87,6 +87,74 @@ unsigned long _uatomic_cmpxchg(void *addr, unsigned long > old, > sizeof(*(addr)))) > > > +/* uatomic_and */ > + > +#ifndef uatomic_and > +static inline __attribute__((always_inline)) > +unsigned long _uatomic_and(void *addr, unsigned long val, > + int len) > +{ > + switch (len) { > +#ifdef UATOMIC_HAS_ATOMIC_BYTE > + case 1: > + return __sync_fetch_and_and_1(addr, val); > +#endif > +#ifdef UATOMIC_HAS_ATOMIC_SHORT > + case 2: > + return __sync_fetch_and_and_2(addr, val); > +#endif > + case 4: > + return __sync_fetch_and_and_4(addr, val); > +#if (BITS_PER_LONG == 64) > + case 8: > + return __sync_fetch_and_and_8(addr, val); > +#endif > + } > + _uatomic_link_error(); > + return 0; > +} > + > + > +#define uatomic_and(addr, v) \ > + ((__typeof__(*(addr))) _uatomic_and((addr), \ > + (unsigned long)(v), \ > + sizeof(*(addr)))) > +#endif /* #ifndef uatomic_and */ > + > +/* uatomic_or */ > + > +#ifndef uatomic_or > +static inline __attribute__((always_inline)) > +unsigned long _uatomic_or(void *addr, unsigned long val, > + int len) > +{ > + switch (len) { > +#ifdef UATOMIC_HAS_ATOMIC_BYTE > + case 1: > + return __sync_fetch_and_or_1(addr, val); > +#endif > +#ifdef UATOMIC_HAS_ATOMIC_SHORT > + case 2: > + return __sync_fetch_and_or_2(addr, val); > +#endif > + case 4: > + return __sync_fetch_and_or_4(addr, val); > +#if (BITS_PER_LONG == 64) > + case 8: > + return __sync_fetch_and_or_8(addr, val); > +#endif > + } > + _uatomic_link_error(); > + return 0; > +} > + > + > +#define uatomic_or(addr, v) \ > + ((__typeof__(*(addr))) _uatomic_or((addr), \ > + (unsigned long)(v), \ > + sizeof(*(addr)))) > +#endif /* #ifndef uatomic_or */ > + > /* uatomic_add_return */ > > #ifndef uatomic_add_return > @@ -186,6 +254,158 @@ unsigned long _uatomic_exchange(void *addr, unsigned > long val, int len) > > #else /* #ifndef uatomic_cmpxchg */ > > +#ifndef uatomic_and > +/* uatomic_and */ > + > +static inline __attribute__((always_inline)) > +unsigned long _uatomic_and(void *addr, unsigned long val, int len) > +{ > + switch (len) { > +#ifdef UATOMIC_HAS_ATOMIC_BYTE > + case 1: > + { > + unsigned char old, oldt; > + > + oldt = uatomic_read((unsigned char *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned char *)addr, > + old, old & val); > + } while (oldt != old); > + > + return old; > + } > +#endif > +#ifdef UATOMIC_HAS_ATOMIC_SHORT > + case 2: > + { > + unsigned short old, oldt; > + > + oldt = uatomic_read((unsigned short *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned short *)addr, > + old, old & val); > + } while (oldt != old); > + > + return old; > + } > +#endif > + case 4: > + { > + unsigned int old, oldt; > + > + oldt = uatomic_read((unsigned int *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned int *)addr, > + old, old & val); > + } while (oldt != old); > + > + return old; > + } > +#if (BITS_PER_LONG == 64) > + case 8: > + { > + unsigned long old, oldt; > + > + oldt = uatomic_read((unsigned long *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned long *)addr, > + old, old & val); > + } while (oldt != old); > + > + return old; > + } > +#endif > + } > + _uatomic_link_error(); > + return 0; > +} > + > +#define uatomic_and(addr, v) \ > + ((__typeof__(*(addr))) _uatomic_and((addr), \ > + (unsigned long)(v), \ > + sizeof(*(addr)))) > +#endif /* #ifndef uatomic_and */ > + > +#ifndef uatomic_or > +/* uatomic_or */ > + > +static inline __attribute__((always_inline)) > +unsigned long _uatomic_or(void *addr, unsigned long val, int len) > +{ > + switch (len) { > +#ifdef UATOMIC_HAS_ATOMIC_BYTE > + case 1: > + { > + unsigned char old, oldt; > + > + oldt = uatomic_read((unsigned char *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned char *)addr, > + old, old | val); > + } while (oldt != old); > + > + return old; > + } > +#endif > +#ifdef UATOMIC_HAS_ATOMIC_SHORT > + case 2: > + { > + unsigned short old, oldt; > + > + oldt = uatomic_read((unsigned short *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned short *)addr, > + old, old | val); > + } while (oldt != old); > + > + return old; > + } > +#endif > + case 4: > + { > + unsigned int old, oldt; > + > + oldt = uatomic_read((unsigned int *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned int *)addr, > + old, old | val); > + } while (oldt != old); > + > + return old; > + } > +#if (BITS_PER_LONG == 64) > + case 8: > + { > + unsigned long old, oldt; > + > + oldt = uatomic_read((unsigned long *)addr); > + do { > + old = oldt; > + oldt = uatomic_cmpxchg((unsigned long *)addr, > + old, old | val); > + } while (oldt != old); > + > + return old; > + } > +#endif > + } > + _uatomic_link_error(); > + return 0; > +} > + > +#define uatomic_or(addr, v) \ > + ((__typeof__(*(addr))) _uatomic_or((addr), \ > + (unsigned long)(v), \ > + sizeof(*(addr)))) > +#endif /* #ifndef uatomic_or */ > + > #ifndef uatomic_add_return > /* uatomic_add_return */ > > -- > 1.7.3.2 > > > _______________________________________________ > ltt-dev mailing list > [email protected] > http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev > -- Mathieu Desnoyers Operating System Efficiency R&D Consultant EfficiOS Inc. http://www.efficios.com _______________________________________________ ltt-dev mailing list [email protected] http://lists.casi.polymtl.ca/cgi-bin/mailman/listinfo/ltt-dev
