1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2021 The FreeBSD Foundation 5 * 6 * This software was developed by Mark Johnston under sponsorship from 7 * the FreeBSD Foundation. 8 */ 9 10 #define _WANT_FREEBSD_BITSET 11 12 #include <sys/types.h> 13 #include <sys/_bitset.h> 14 #include <sys/bitset.h> 15 #include <stdio.h> 16 #include <stdlib.h> 17 18 #include <atf-c.h> 19 20 BITSET_DEFINE(bs256, 256); 21 22 ATF_TC_WITHOUT_HEAD(bit_foreach); 23 ATF_TC_BODY(bit_foreach, tc) 24 { 25 struct bs256 bs0, bs1, bsrand; 26 int setc, clrc, i; 27 28 #define _BIT_FOREACH_COUNT(s, bs) do { \ 29 int prev = -1; \ 30 setc = clrc = 0; \ 31 BIT_FOREACH_ISSET((s), i, (bs)) { \ 32 ATF_REQUIRE_MSG(prev < i, "incorrect bit ordering"); \ 33 ATF_REQUIRE_MSG(BIT_ISSET((s), i, (bs)), \ 34 "bit %d is not set", i); \ 35 setc++; \ 36 prev = i; \ 37 } \ 38 prev = -1; \ 39 BIT_FOREACH_ISCLR((s), i, (bs)) { \ 40 ATF_REQUIRE_MSG(prev < i, "incorrect bit ordering"); \ 41 ATF_REQUIRE_MSG(!BIT_ISSET((s), i, (bs)), \ 42 "bit %d is set", i); \ 43 clrc++; \ 44 prev = i; \ 45 } \ 46 } while (0) 47 48 /* 49 * Create several bitsets, and for each one count the number 50 * of set and clear bits and make sure they match what we expect. 51 */ 52 53 BIT_FILL(256, &bs1); 54 _BIT_FOREACH_COUNT(256, &bs1); 55 ATF_REQUIRE_MSG(setc == 256, "incorrect set count %d", setc); 56 ATF_REQUIRE_MSG(clrc == 0, "incorrect clear count %d", clrc); 57 58 BIT_ZERO(256, &bs0); 59 _BIT_FOREACH_COUNT(256, &bs0); 60 ATF_REQUIRE_MSG(setc == 0, "incorrect set count %d", setc); 61 ATF_REQUIRE_MSG(clrc == 256, "incorrect clear count %d", clrc); 62 63 BIT_ZERO(256, &bsrand); 64 for (i = 0; i < 256; i++) 65 if (random() % 2 != 0) 66 BIT_SET(256, i, &bsrand); 67 _BIT_FOREACH_COUNT(256, &bsrand); 68 ATF_REQUIRE_MSG(setc + clrc == 256, "incorrect counts %d, %d", 69 setc, clrc); 70 71 /* 72 * Try to verify that we can safely clear bits in the set while 73 * iterating. 74 */ 75 BIT_FOREACH_ISSET(256, i, &bsrand) { 76 ATF_REQUIRE(setc-- > 0); 77 BIT_CLR(256, i, &bsrand); 78 } 79 _BIT_FOREACH_COUNT(256, &bsrand); 80 ATF_REQUIRE_MSG(setc == 0, "incorrect set count %d", setc); 81 ATF_REQUIRE_MSG(clrc == 256, "incorrect clear count %d", clrc); 82 83 #undef _BIT_FOREACH_COUNT 84 } 85 86 ATF_TP_ADD_TCS(tp) 87 { 88 ATF_TP_ADD_TC(tp, bit_foreach); 89 return (atf_no_error()); 90 } 91