Module: sip-router Branch: master Commit: 628e975416ba291f7158520e5cc92d0b0cb6826e URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=628e9754...
Author: Miklos Tirpak miklos@iptel.org Committer: Miklos Tirpak miklos@iptel.org Date: Wed Jan 5 11:40:20 2011 +0100
bit test: bit_test_and_reset() added
The function returns the bit found at offset position in a bitstring and resets the bit to 0.
---
bit_test.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 42 insertions(+), 0 deletions(-)
diff --git a/bit_test.h b/bit_test.h index 534e502..9f83215 100644 --- a/bit_test.h +++ b/bit_test.h @@ -18,6 +18,7 @@ * History * ------- * 2010-04-26 Initial version (Miklos) + * 2011-01-05 bit_test_and_reset added (Miklos) */
/* Bit test functions: @@ -30,6 +31,11 @@ * in a bitstring pointed by addr, and sets * the bit at the given offset. * + * - int bit_test_and_reset(int offset, unsigned int *addr) + * Returns the bit found at offset position + * in a bitstring pointed by addr, and resets + * the bit at the given offset. + * * Note that 0 <= offset <= 128, Make sure that addr points to * a large enough memory area. */ @@ -86,6 +92,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr) return (int)v; }
+/* Returns the bit found at offset position in the bitstring + * pointed by addr and resets it to 0. + * Note that the CPU can access 4 bytes starting from addr, + * hence 0 <= offset < 128 holds. Make sure that addr points + * to a memory area that is large enough. + */ +static inline int bit_test_and_reset(int offset, unsigned int *addr) +{ + unsigned char v; + + asm volatile( + " btr %2, %1 \n\t" + " setc %0 \n\t" + : "=qm" (v) : "m" (*addr), "r" (offset) + ); + return (int)v; +} + #else /* BIT_TEST_ASM */
/* Returns the bit found at offset position in the bitstring @@ -116,6 +140,24 @@ static inline int bit_test_and_set(int offset, unsigned int *addr) return res; }
+/* Returns the bit found at offset position in the bitstring + * pointed by addr and resets it to 0. + * Note that offset can be grater than 32, make sure that addr points + * to a memory area that is large enough. + */ +static inline int bit_test_and_reset(int offset, unsigned int *addr) +{ + unsigned int *i; + int mask, res; + + i = addr + offset/32; + mask = 1U << (offset % 32); + res = ((*i) & mask) ? 1 : 0; + (*i) &= ~mask; + + return res; +} + #endif /* BIT_TEST_ASM */
#endif /* #ifndef _BIT_TEST_H */