1*1208bc7eSAndroid Build Coastguard Worker #include "test/jemalloc_test.h"
2*1208bc7eSAndroid Build Coastguard Worker
3*1208bc7eSAndroid Build Coastguard Worker #define NBITS_TAB \
4*1208bc7eSAndroid Build Coastguard Worker NB( 1) \
5*1208bc7eSAndroid Build Coastguard Worker NB( 2) \
6*1208bc7eSAndroid Build Coastguard Worker NB( 3) \
7*1208bc7eSAndroid Build Coastguard Worker NB( 4) \
8*1208bc7eSAndroid Build Coastguard Worker NB( 5) \
9*1208bc7eSAndroid Build Coastguard Worker NB( 6) \
10*1208bc7eSAndroid Build Coastguard Worker NB( 7) \
11*1208bc7eSAndroid Build Coastguard Worker NB( 8) \
12*1208bc7eSAndroid Build Coastguard Worker NB( 9) \
13*1208bc7eSAndroid Build Coastguard Worker NB(10) \
14*1208bc7eSAndroid Build Coastguard Worker NB(11) \
15*1208bc7eSAndroid Build Coastguard Worker NB(12) \
16*1208bc7eSAndroid Build Coastguard Worker NB(13) \
17*1208bc7eSAndroid Build Coastguard Worker NB(14) \
18*1208bc7eSAndroid Build Coastguard Worker NB(15) \
19*1208bc7eSAndroid Build Coastguard Worker NB(16) \
20*1208bc7eSAndroid Build Coastguard Worker NB(17) \
21*1208bc7eSAndroid Build Coastguard Worker NB(18) \
22*1208bc7eSAndroid Build Coastguard Worker NB(19) \
23*1208bc7eSAndroid Build Coastguard Worker NB(20) \
24*1208bc7eSAndroid Build Coastguard Worker NB(21) \
25*1208bc7eSAndroid Build Coastguard Worker NB(22) \
26*1208bc7eSAndroid Build Coastguard Worker NB(23) \
27*1208bc7eSAndroid Build Coastguard Worker NB(24) \
28*1208bc7eSAndroid Build Coastguard Worker NB(25) \
29*1208bc7eSAndroid Build Coastguard Worker NB(26) \
30*1208bc7eSAndroid Build Coastguard Worker NB(27) \
31*1208bc7eSAndroid Build Coastguard Worker NB(28) \
32*1208bc7eSAndroid Build Coastguard Worker NB(29) \
33*1208bc7eSAndroid Build Coastguard Worker NB(30) \
34*1208bc7eSAndroid Build Coastguard Worker NB(31) \
35*1208bc7eSAndroid Build Coastguard Worker NB(32) \
36*1208bc7eSAndroid Build Coastguard Worker \
37*1208bc7eSAndroid Build Coastguard Worker NB(33) \
38*1208bc7eSAndroid Build Coastguard Worker NB(34) \
39*1208bc7eSAndroid Build Coastguard Worker NB(35) \
40*1208bc7eSAndroid Build Coastguard Worker NB(36) \
41*1208bc7eSAndroid Build Coastguard Worker NB(37) \
42*1208bc7eSAndroid Build Coastguard Worker NB(38) \
43*1208bc7eSAndroid Build Coastguard Worker NB(39) \
44*1208bc7eSAndroid Build Coastguard Worker NB(40) \
45*1208bc7eSAndroid Build Coastguard Worker NB(41) \
46*1208bc7eSAndroid Build Coastguard Worker NB(42) \
47*1208bc7eSAndroid Build Coastguard Worker NB(43) \
48*1208bc7eSAndroid Build Coastguard Worker NB(44) \
49*1208bc7eSAndroid Build Coastguard Worker NB(45) \
50*1208bc7eSAndroid Build Coastguard Worker NB(46) \
51*1208bc7eSAndroid Build Coastguard Worker NB(47) \
52*1208bc7eSAndroid Build Coastguard Worker NB(48) \
53*1208bc7eSAndroid Build Coastguard Worker NB(49) \
54*1208bc7eSAndroid Build Coastguard Worker NB(50) \
55*1208bc7eSAndroid Build Coastguard Worker NB(51) \
56*1208bc7eSAndroid Build Coastguard Worker NB(52) \
57*1208bc7eSAndroid Build Coastguard Worker NB(53) \
58*1208bc7eSAndroid Build Coastguard Worker NB(54) \
59*1208bc7eSAndroid Build Coastguard Worker NB(55) \
60*1208bc7eSAndroid Build Coastguard Worker NB(56) \
61*1208bc7eSAndroid Build Coastguard Worker NB(57) \
62*1208bc7eSAndroid Build Coastguard Worker NB(58) \
63*1208bc7eSAndroid Build Coastguard Worker NB(59) \
64*1208bc7eSAndroid Build Coastguard Worker NB(60) \
65*1208bc7eSAndroid Build Coastguard Worker NB(61) \
66*1208bc7eSAndroid Build Coastguard Worker NB(62) \
67*1208bc7eSAndroid Build Coastguard Worker NB(63) \
68*1208bc7eSAndroid Build Coastguard Worker NB(64) \
69*1208bc7eSAndroid Build Coastguard Worker NB(65) \
70*1208bc7eSAndroid Build Coastguard Worker \
71*1208bc7eSAndroid Build Coastguard Worker NB(126) \
72*1208bc7eSAndroid Build Coastguard Worker NB(127) \
73*1208bc7eSAndroid Build Coastguard Worker NB(128) \
74*1208bc7eSAndroid Build Coastguard Worker NB(129) \
75*1208bc7eSAndroid Build Coastguard Worker NB(130) \
76*1208bc7eSAndroid Build Coastguard Worker \
77*1208bc7eSAndroid Build Coastguard Worker NB(254) \
78*1208bc7eSAndroid Build Coastguard Worker NB(255) \
79*1208bc7eSAndroid Build Coastguard Worker NB(256) \
80*1208bc7eSAndroid Build Coastguard Worker NB(257) \
81*1208bc7eSAndroid Build Coastguard Worker NB(258) \
82*1208bc7eSAndroid Build Coastguard Worker \
83*1208bc7eSAndroid Build Coastguard Worker NB(510) \
84*1208bc7eSAndroid Build Coastguard Worker NB(511) \
85*1208bc7eSAndroid Build Coastguard Worker NB(512) \
86*1208bc7eSAndroid Build Coastguard Worker NB(513) \
87*1208bc7eSAndroid Build Coastguard Worker NB(514) \
88*1208bc7eSAndroid Build Coastguard Worker \
89*1208bc7eSAndroid Build Coastguard Worker NB(1024) \
90*1208bc7eSAndroid Build Coastguard Worker NB(2048) \
91*1208bc7eSAndroid Build Coastguard Worker NB(4096) \
92*1208bc7eSAndroid Build Coastguard Worker NB(8192) \
93*1208bc7eSAndroid Build Coastguard Worker NB(16384) \
94*1208bc7eSAndroid Build Coastguard Worker
95*1208bc7eSAndroid Build Coastguard Worker static void
test_bitmap_initializer_body(const bitmap_info_t * binfo,size_t nbits)96*1208bc7eSAndroid Build Coastguard Worker test_bitmap_initializer_body(const bitmap_info_t *binfo, size_t nbits) {
97*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo_dyn;
98*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo_dyn, nbits);
99*1208bc7eSAndroid Build Coastguard Worker
100*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_size(binfo), bitmap_size(&binfo_dyn),
101*1208bc7eSAndroid Build Coastguard Worker "Unexpected difference between static and dynamic initialization, "
102*1208bc7eSAndroid Build Coastguard Worker "nbits=%zu", nbits);
103*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(binfo->nbits, binfo_dyn.nbits,
104*1208bc7eSAndroid Build Coastguard Worker "Unexpected difference between static and dynamic initialization, "
105*1208bc7eSAndroid Build Coastguard Worker "nbits=%zu", nbits);
106*1208bc7eSAndroid Build Coastguard Worker #ifdef BITMAP_USE_TREE
107*1208bc7eSAndroid Build Coastguard Worker assert_u_eq(binfo->nlevels, binfo_dyn.nlevels,
108*1208bc7eSAndroid Build Coastguard Worker "Unexpected difference between static and dynamic initialization, "
109*1208bc7eSAndroid Build Coastguard Worker "nbits=%zu", nbits);
110*1208bc7eSAndroid Build Coastguard Worker {
111*1208bc7eSAndroid Build Coastguard Worker unsigned i;
112*1208bc7eSAndroid Build Coastguard Worker
113*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < binfo->nlevels; i++) {
114*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(binfo->levels[i].group_offset,
115*1208bc7eSAndroid Build Coastguard Worker binfo_dyn.levels[i].group_offset,
116*1208bc7eSAndroid Build Coastguard Worker "Unexpected difference between static and dynamic "
117*1208bc7eSAndroid Build Coastguard Worker "initialization, nbits=%zu, level=%u", nbits, i);
118*1208bc7eSAndroid Build Coastguard Worker }
119*1208bc7eSAndroid Build Coastguard Worker }
120*1208bc7eSAndroid Build Coastguard Worker #else
121*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(binfo->ngroups, binfo_dyn.ngroups,
122*1208bc7eSAndroid Build Coastguard Worker "Unexpected difference between static and dynamic initialization");
123*1208bc7eSAndroid Build Coastguard Worker #endif
124*1208bc7eSAndroid Build Coastguard Worker }
125*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_initializer)126*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_initializer) {
127*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
128*1208bc7eSAndroid Build Coastguard Worker if (nbits <= BITMAP_MAXBITS) { \
129*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = \
130*1208bc7eSAndroid Build Coastguard Worker BITMAP_INFO_INITIALIZER(nbits); \
131*1208bc7eSAndroid Build Coastguard Worker test_bitmap_initializer_body(&binfo, nbits); \
132*1208bc7eSAndroid Build Coastguard Worker } \
133*1208bc7eSAndroid Build Coastguard Worker }
134*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
135*1208bc7eSAndroid Build Coastguard Worker #undef NB
136*1208bc7eSAndroid Build Coastguard Worker }
137*1208bc7eSAndroid Build Coastguard Worker TEST_END
138*1208bc7eSAndroid Build Coastguard Worker
139*1208bc7eSAndroid Build Coastguard Worker static size_t
test_bitmap_size_body(const bitmap_info_t * binfo,size_t nbits,size_t prev_size)140*1208bc7eSAndroid Build Coastguard Worker test_bitmap_size_body(const bitmap_info_t *binfo, size_t nbits,
141*1208bc7eSAndroid Build Coastguard Worker size_t prev_size) {
142*1208bc7eSAndroid Build Coastguard Worker size_t size = bitmap_size(binfo);
143*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(size, (nbits >> 3),
144*1208bc7eSAndroid Build Coastguard Worker "Bitmap size is smaller than expected");
145*1208bc7eSAndroid Build Coastguard Worker assert_zu_ge(size, prev_size, "Bitmap size is smaller than expected");
146*1208bc7eSAndroid Build Coastguard Worker return size;
147*1208bc7eSAndroid Build Coastguard Worker }
148*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_size)149*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_size) {
150*1208bc7eSAndroid Build Coastguard Worker size_t nbits, prev_size;
151*1208bc7eSAndroid Build Coastguard Worker
152*1208bc7eSAndroid Build Coastguard Worker prev_size = 0;
153*1208bc7eSAndroid Build Coastguard Worker for (nbits = 1; nbits <= BITMAP_MAXBITS; nbits++) {
154*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo;
155*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo, nbits);
156*1208bc7eSAndroid Build Coastguard Worker prev_size = test_bitmap_size_body(&binfo, nbits, prev_size);
157*1208bc7eSAndroid Build Coastguard Worker }
158*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
159*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
160*1208bc7eSAndroid Build Coastguard Worker prev_size = test_bitmap_size_body(&binfo, nbits, \
161*1208bc7eSAndroid Build Coastguard Worker prev_size); \
162*1208bc7eSAndroid Build Coastguard Worker }
163*1208bc7eSAndroid Build Coastguard Worker prev_size = 0;
164*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
165*1208bc7eSAndroid Build Coastguard Worker #undef NB
166*1208bc7eSAndroid Build Coastguard Worker }
167*1208bc7eSAndroid Build Coastguard Worker TEST_END
168*1208bc7eSAndroid Build Coastguard Worker
169*1208bc7eSAndroid Build Coastguard Worker static void
test_bitmap_init_body(const bitmap_info_t * binfo,size_t nbits)170*1208bc7eSAndroid Build Coastguard Worker test_bitmap_init_body(const bitmap_info_t *binfo, size_t nbits) {
171*1208bc7eSAndroid Build Coastguard Worker size_t i;
172*1208bc7eSAndroid Build Coastguard Worker bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
173*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(bitmap, "Unexpected malloc() failure");
174*1208bc7eSAndroid Build Coastguard Worker
175*1208bc7eSAndroid Build Coastguard Worker bitmap_init(bitmap, binfo, false);
176*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
177*1208bc7eSAndroid Build Coastguard Worker assert_false(bitmap_get(bitmap, binfo, i),
178*1208bc7eSAndroid Build Coastguard Worker "Bit should be unset");
179*1208bc7eSAndroid Build Coastguard Worker }
180*1208bc7eSAndroid Build Coastguard Worker
181*1208bc7eSAndroid Build Coastguard Worker bitmap_init(bitmap, binfo, true);
182*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
183*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_get(bitmap, binfo, i), "Bit should be set");
184*1208bc7eSAndroid Build Coastguard Worker }
185*1208bc7eSAndroid Build Coastguard Worker
186*1208bc7eSAndroid Build Coastguard Worker free(bitmap);
187*1208bc7eSAndroid Build Coastguard Worker }
188*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_init)189*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_init) {
190*1208bc7eSAndroid Build Coastguard Worker size_t nbits;
191*1208bc7eSAndroid Build Coastguard Worker
192*1208bc7eSAndroid Build Coastguard Worker for (nbits = 1; nbits <= BITMAP_MAXBITS; nbits++) {
193*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo;
194*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo, nbits);
195*1208bc7eSAndroid Build Coastguard Worker test_bitmap_init_body(&binfo, nbits);
196*1208bc7eSAndroid Build Coastguard Worker }
197*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
198*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
199*1208bc7eSAndroid Build Coastguard Worker test_bitmap_init_body(&binfo, nbits); \
200*1208bc7eSAndroid Build Coastguard Worker }
201*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
202*1208bc7eSAndroid Build Coastguard Worker #undef NB
203*1208bc7eSAndroid Build Coastguard Worker }
204*1208bc7eSAndroid Build Coastguard Worker TEST_END
205*1208bc7eSAndroid Build Coastguard Worker
206*1208bc7eSAndroid Build Coastguard Worker static void
test_bitmap_set_body(const bitmap_info_t * binfo,size_t nbits)207*1208bc7eSAndroid Build Coastguard Worker test_bitmap_set_body(const bitmap_info_t *binfo, size_t nbits) {
208*1208bc7eSAndroid Build Coastguard Worker size_t i;
209*1208bc7eSAndroid Build Coastguard Worker bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
210*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(bitmap, "Unexpected malloc() failure");
211*1208bc7eSAndroid Build Coastguard Worker bitmap_init(bitmap, binfo, false);
212*1208bc7eSAndroid Build Coastguard Worker
213*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
214*1208bc7eSAndroid Build Coastguard Worker bitmap_set(bitmap, binfo, i);
215*1208bc7eSAndroid Build Coastguard Worker }
216*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_full(bitmap, binfo), "All bits should be set");
217*1208bc7eSAndroid Build Coastguard Worker free(bitmap);
218*1208bc7eSAndroid Build Coastguard Worker }
219*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_set)220*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_set) {
221*1208bc7eSAndroid Build Coastguard Worker size_t nbits;
222*1208bc7eSAndroid Build Coastguard Worker
223*1208bc7eSAndroid Build Coastguard Worker for (nbits = 1; nbits <= BITMAP_MAXBITS; nbits++) {
224*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo;
225*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo, nbits);
226*1208bc7eSAndroid Build Coastguard Worker test_bitmap_set_body(&binfo, nbits);
227*1208bc7eSAndroid Build Coastguard Worker }
228*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
229*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
230*1208bc7eSAndroid Build Coastguard Worker test_bitmap_set_body(&binfo, nbits); \
231*1208bc7eSAndroid Build Coastguard Worker }
232*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
233*1208bc7eSAndroid Build Coastguard Worker #undef NB
234*1208bc7eSAndroid Build Coastguard Worker }
235*1208bc7eSAndroid Build Coastguard Worker TEST_END
236*1208bc7eSAndroid Build Coastguard Worker
237*1208bc7eSAndroid Build Coastguard Worker static void
test_bitmap_unset_body(const bitmap_info_t * binfo,size_t nbits)238*1208bc7eSAndroid Build Coastguard Worker test_bitmap_unset_body(const bitmap_info_t *binfo, size_t nbits) {
239*1208bc7eSAndroid Build Coastguard Worker size_t i;
240*1208bc7eSAndroid Build Coastguard Worker bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
241*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(bitmap, "Unexpected malloc() failure");
242*1208bc7eSAndroid Build Coastguard Worker bitmap_init(bitmap, binfo, false);
243*1208bc7eSAndroid Build Coastguard Worker
244*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
245*1208bc7eSAndroid Build Coastguard Worker bitmap_set(bitmap, binfo, i);
246*1208bc7eSAndroid Build Coastguard Worker }
247*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_full(bitmap, binfo), "All bits should be set");
248*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
249*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
250*1208bc7eSAndroid Build Coastguard Worker }
251*1208bc7eSAndroid Build Coastguard Worker for (i = 0; i < nbits; i++) {
252*1208bc7eSAndroid Build Coastguard Worker bitmap_set(bitmap, binfo, i);
253*1208bc7eSAndroid Build Coastguard Worker }
254*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_full(bitmap, binfo), "All bits should be set");
255*1208bc7eSAndroid Build Coastguard Worker free(bitmap);
256*1208bc7eSAndroid Build Coastguard Worker }
257*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_unset)258*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_unset) {
259*1208bc7eSAndroid Build Coastguard Worker size_t nbits;
260*1208bc7eSAndroid Build Coastguard Worker
261*1208bc7eSAndroid Build Coastguard Worker for (nbits = 1; nbits <= BITMAP_MAXBITS; nbits++) {
262*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo;
263*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo, nbits);
264*1208bc7eSAndroid Build Coastguard Worker test_bitmap_unset_body(&binfo, nbits);
265*1208bc7eSAndroid Build Coastguard Worker }
266*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
267*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
268*1208bc7eSAndroid Build Coastguard Worker test_bitmap_unset_body(&binfo, nbits); \
269*1208bc7eSAndroid Build Coastguard Worker }
270*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
271*1208bc7eSAndroid Build Coastguard Worker #undef NB
272*1208bc7eSAndroid Build Coastguard Worker }
273*1208bc7eSAndroid Build Coastguard Worker TEST_END
274*1208bc7eSAndroid Build Coastguard Worker
275*1208bc7eSAndroid Build Coastguard Worker static void
test_bitmap_xfu_body(const bitmap_info_t * binfo,size_t nbits)276*1208bc7eSAndroid Build Coastguard Worker test_bitmap_xfu_body(const bitmap_info_t *binfo, size_t nbits) {
277*1208bc7eSAndroid Build Coastguard Worker bitmap_t *bitmap = (bitmap_t *)malloc(bitmap_size(binfo));
278*1208bc7eSAndroid Build Coastguard Worker assert_ptr_not_null(bitmap, "Unexpected malloc() failure");
279*1208bc7eSAndroid Build Coastguard Worker bitmap_init(bitmap, binfo, false);
280*1208bc7eSAndroid Build Coastguard Worker
281*1208bc7eSAndroid Build Coastguard Worker /* Iteratively set bits starting at the beginning. */
282*1208bc7eSAndroid Build Coastguard Worker for (size_t i = 0; i < nbits; i++) {
283*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
284*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after previous first unset "
285*1208bc7eSAndroid Build Coastguard Worker "bit");
286*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
287*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after previous first unset "
288*1208bc7eSAndroid Build Coastguard Worker "bit");
289*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
290*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after previous first unset "
291*1208bc7eSAndroid Build Coastguard Worker "bit");
292*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i,
293*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after previous first unset "
294*1208bc7eSAndroid Build Coastguard Worker "bit");
295*1208bc7eSAndroid Build Coastguard Worker }
296*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_full(bitmap, binfo), "All bits should be set");
297*1208bc7eSAndroid Build Coastguard Worker
298*1208bc7eSAndroid Build Coastguard Worker /*
299*1208bc7eSAndroid Build Coastguard Worker * Iteratively unset bits starting at the end, and verify that
300*1208bc7eSAndroid Build Coastguard Worker * bitmap_sfu() reaches the unset bits.
301*1208bc7eSAndroid Build Coastguard Worker */
302*1208bc7eSAndroid Build Coastguard Worker for (size_t i = nbits - 1; i < nbits; i--) { /* (nbits..0] */
303*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
304*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
305*1208bc7eSAndroid Build Coastguard Worker "First unset bit should the bit previously unset");
306*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
307*1208bc7eSAndroid Build Coastguard Worker "First unset bit should the bit previously unset");
308*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
309*1208bc7eSAndroid Build Coastguard Worker "First unset bit should the bit previously unset");
310*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i,
311*1208bc7eSAndroid Build Coastguard Worker "First unset bit should the bit previously unset");
312*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
313*1208bc7eSAndroid Build Coastguard Worker }
314*1208bc7eSAndroid Build Coastguard Worker assert_false(bitmap_get(bitmap, binfo, 0), "Bit should be unset");
315*1208bc7eSAndroid Build Coastguard Worker
316*1208bc7eSAndroid Build Coastguard Worker /*
317*1208bc7eSAndroid Build Coastguard Worker * Iteratively set bits starting at the beginning, and verify that
318*1208bc7eSAndroid Build Coastguard Worker * bitmap_sfu() looks past them.
319*1208bc7eSAndroid Build Coastguard Worker */
320*1208bc7eSAndroid Build Coastguard Worker for (size_t i = 1; i < nbits; i++) {
321*1208bc7eSAndroid Build Coastguard Worker bitmap_set(bitmap, binfo, i - 1);
322*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, 0), i,
323*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after the bit previously "
324*1208bc7eSAndroid Build Coastguard Worker "set");
325*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, (i > 0) ? i-1 : i), i,
326*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after the bit previously "
327*1208bc7eSAndroid Build Coastguard Worker "set");
328*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
329*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after the bit previously "
330*1208bc7eSAndroid Build Coastguard Worker "set");
331*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i,
332*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be just after the bit previously "
333*1208bc7eSAndroid Build Coastguard Worker "set");
334*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
335*1208bc7eSAndroid Build Coastguard Worker }
336*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, 0), nbits - 1,
337*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be the last bit");
338*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, (nbits > 1) ? nbits-2 : nbits-1),
339*1208bc7eSAndroid Build Coastguard Worker nbits - 1, "First unset bit should be the last bit");
340*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, nbits - 1), nbits - 1,
341*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be the last bit");
342*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), nbits - 1,
343*1208bc7eSAndroid Build Coastguard Worker "First unset bit should be the last bit");
344*1208bc7eSAndroid Build Coastguard Worker assert_true(bitmap_full(bitmap, binfo), "All bits should be set");
345*1208bc7eSAndroid Build Coastguard Worker
346*1208bc7eSAndroid Build Coastguard Worker /*
347*1208bc7eSAndroid Build Coastguard Worker * Bubble a "usu" pattern through the bitmap and verify that
348*1208bc7eSAndroid Build Coastguard Worker * bitmap_ffu() finds the correct bit for all five min_bit cases.
349*1208bc7eSAndroid Build Coastguard Worker */
350*1208bc7eSAndroid Build Coastguard Worker if (nbits >= 3) {
351*1208bc7eSAndroid Build Coastguard Worker for (size_t i = 0; i < nbits-2; i++) {
352*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
353*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i+2);
354*1208bc7eSAndroid Build Coastguard Worker if (i > 0) {
355*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i-1), i,
356*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
357*1208bc7eSAndroid Build Coastguard Worker }
358*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
359*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
360*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i+1), i+2,
361*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
362*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i+2), i+2,
363*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
364*1208bc7eSAndroid Build Coastguard Worker if (i + 3 < nbits) {
365*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i+3),
366*1208bc7eSAndroid Build Coastguard Worker nbits, "Unexpected first unset bit");
367*1208bc7eSAndroid Build Coastguard Worker }
368*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i,
369*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
370*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i+2,
371*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
372*1208bc7eSAndroid Build Coastguard Worker }
373*1208bc7eSAndroid Build Coastguard Worker }
374*1208bc7eSAndroid Build Coastguard Worker
375*1208bc7eSAndroid Build Coastguard Worker /*
376*1208bc7eSAndroid Build Coastguard Worker * Unset the last bit, bubble another unset bit through the bitmap, and
377*1208bc7eSAndroid Build Coastguard Worker * verify that bitmap_ffu() finds the correct bit for all four min_bit
378*1208bc7eSAndroid Build Coastguard Worker * cases.
379*1208bc7eSAndroid Build Coastguard Worker */
380*1208bc7eSAndroid Build Coastguard Worker if (nbits >= 3) {
381*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, nbits-1);
382*1208bc7eSAndroid Build Coastguard Worker for (size_t i = 0; i < nbits-1; i++) {
383*1208bc7eSAndroid Build Coastguard Worker bitmap_unset(bitmap, binfo, i);
384*1208bc7eSAndroid Build Coastguard Worker if (i > 0) {
385*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i-1), i,
386*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
387*1208bc7eSAndroid Build Coastguard Worker }
388*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i), i,
389*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
390*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, i+1), nbits-1,
391*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
392*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_ffu(bitmap, binfo, nbits-1),
393*1208bc7eSAndroid Build Coastguard Worker nbits-1, "Unexpected first unset bit");
394*1208bc7eSAndroid Build Coastguard Worker
395*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), i,
396*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
397*1208bc7eSAndroid Build Coastguard Worker }
398*1208bc7eSAndroid Build Coastguard Worker assert_zu_eq(bitmap_sfu(bitmap, binfo), nbits-1,
399*1208bc7eSAndroid Build Coastguard Worker "Unexpected first unset bit");
400*1208bc7eSAndroid Build Coastguard Worker }
401*1208bc7eSAndroid Build Coastguard Worker
402*1208bc7eSAndroid Build Coastguard Worker free(bitmap);
403*1208bc7eSAndroid Build Coastguard Worker }
404*1208bc7eSAndroid Build Coastguard Worker
TEST_BEGIN(test_bitmap_xfu)405*1208bc7eSAndroid Build Coastguard Worker TEST_BEGIN(test_bitmap_xfu) {
406*1208bc7eSAndroid Build Coastguard Worker size_t nbits;
407*1208bc7eSAndroid Build Coastguard Worker
408*1208bc7eSAndroid Build Coastguard Worker for (nbits = 1; nbits <= BITMAP_MAXBITS; nbits++) {
409*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo;
410*1208bc7eSAndroid Build Coastguard Worker bitmap_info_init(&binfo, nbits);
411*1208bc7eSAndroid Build Coastguard Worker test_bitmap_xfu_body(&binfo, nbits);
412*1208bc7eSAndroid Build Coastguard Worker }
413*1208bc7eSAndroid Build Coastguard Worker #define NB(nbits) { \
414*1208bc7eSAndroid Build Coastguard Worker bitmap_info_t binfo = BITMAP_INFO_INITIALIZER(nbits); \
415*1208bc7eSAndroid Build Coastguard Worker test_bitmap_xfu_body(&binfo, nbits); \
416*1208bc7eSAndroid Build Coastguard Worker }
417*1208bc7eSAndroid Build Coastguard Worker NBITS_TAB
418*1208bc7eSAndroid Build Coastguard Worker #undef NB
419*1208bc7eSAndroid Build Coastguard Worker }
420*1208bc7eSAndroid Build Coastguard Worker TEST_END
421*1208bc7eSAndroid Build Coastguard Worker
422*1208bc7eSAndroid Build Coastguard Worker int
main(void)423*1208bc7eSAndroid Build Coastguard Worker main(void) {
424*1208bc7eSAndroid Build Coastguard Worker return test(
425*1208bc7eSAndroid Build Coastguard Worker test_bitmap_initializer,
426*1208bc7eSAndroid Build Coastguard Worker test_bitmap_size,
427*1208bc7eSAndroid Build Coastguard Worker test_bitmap_init,
428*1208bc7eSAndroid Build Coastguard Worker test_bitmap_set,
429*1208bc7eSAndroid Build Coastguard Worker test_bitmap_unset,
430*1208bc7eSAndroid Build Coastguard Worker test_bitmap_xfu);
431*1208bc7eSAndroid Build Coastguard Worker }
432