From: Mark Johnston <ma...@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

_______________________________________________
devel mailing list
devel@rtems.org
http://lists.rtems.org/mailman/listinfo/devel

Reply via email to