Module: sip-router
Branch: master
Commit: 628e975416ba291f7158520e5cc92d0b0cb6826e
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=628e975…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)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 */