[newlib 13/22] bitset: Reimplement BIT_FOREACH_IS(SET|CLR)
Sebastian Huber
sebastian.huber at embedded-brains.de
Wed Jun 22 08:24:36 UTC 2022
From: Mark Johnston <markj at FreeBSD.org>
Eliminate the nested loops and re-implement following a suggestion from
rlibby.
Add some simple regression tests.
Reviewed by: rlibby, kib
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D32472
---
newlib/libc/sys/rtems/include/sys/bitset.h | 31 +++++++++++++++++-----
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/newlib/libc/sys/rtems/include/sys/bitset.h b/newlib/libc/sys/rtems/include/sys/bitset.h
index 35c21f6ae..88cda9dd9 100644
--- a/newlib/libc/sys/rtems/include/sys/bitset.h
+++ b/newlib/libc/sys/rtems/include/sys/bitset.h
@@ -274,12 +274,31 @@
__count; \
})
-/* Non-destructively loop over all set or clear bits in the set. */
-#define _BIT_FOREACH(_s, i, p, op) \
- for (__size_t __i = 0; __i < __bitset_words(_s); __i++) \
- for (long __j = op((p)->__bits[__i]), __b = ffsl(__j); \
- (i = (__b - 1) + __i * _BITSET_BITS), __j != 0; \
- __j &= ~(1l << i), __b = ffsl(__j))
+#define _BIT_FOREACH_ADVANCE(_s, i, p, op) __extension__ ({ \
+ int __found; \
+ for (;;) { \
+ if (__bits != 0) { \
+ int __bit = ffsl(__bits) - 1; \
+ __bits &= ~(1ul << __bit); \
+ (i) = __i * _BITSET_BITS + __bit; \
+ __found = 1; \
+ break; \
+ } \
+ if (++__i == __bitset_words(_s)) { \
+ __found = 0; \
+ break; \
+ } \
+ __bits = op((p)->__bits[__i]); \
+ } \
+ __found != 0; \
+})
+
+/*
+ * Non-destructively loop over all set or clear bits in the set.
+ */
+#define _BIT_FOREACH(_s, i, p, op) \
+ for (long __i = -1, __bits = 0; \
+ _BIT_FOREACH_ADVANCE(_s, i, p, op); )
#define BIT_FOREACH_ISSET(_s, i, p) _BIT_FOREACH(_s, i, p, )
#define BIT_FOREACH_ISCLR(_s, i, p) _BIT_FOREACH(_s, i, p, ~)
--
2.35.3
More information about the devel
mailing list