[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