xref: /freebsd/tests/sys/sys/bitset_test.c (revision e0c4386e)
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