VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstRTBitOperations.cpp@ 24639

Last change on this file since 24639 was 20606, checked in by vboxsync, 15 years ago

IPRT/testcase: Use RTTestInitAndCreate.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 15.2 KB
Line 
1/* $Id: tstRTBitOperations.cpp 20606 2009-06-15 23:49:07Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Inlined Bit Operations.
4 */
5
6/*
7 * Copyright (C) 2006-2009 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * The contents of this file may alternatively be used under the terms
18 * of the Common Development and Distribution License Version 1.0
19 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
20 * VirtualBox OSE distribution, in which case the provisions of the
21 * CDDL are applicable instead of those of the GPL.
22 *
23 * You may elect to license modified versions of this file under the
24 * terms and conditions of either the GPL or the CDDL or both.
25 *
26 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
27 * Clara, CA 95054 USA or visit http://www.sun.com if you need
28 * additional information or have any questions.
29 */
30
31/*******************************************************************************
32* Header Files *
33*******************************************************************************/
34#include <iprt/asm.h>
35
36#include <iprt/initterm.h>
37#include <iprt/stream.h>
38#include <iprt/string.h>
39#include <iprt/test.h>
40
41
42/*
43 * Test 2 - ID allocation using a bitmap.
44 */
45
46#define NIL_TEST2_ID 0
47#define TEST2_ID_LAST ((RT_BIT_32(28) - 1) >> 8)
48
49struct TestMap2
50{
51 uint32_t idNil;
52 uint32_t idLast;
53 uint32_t idChunkPrev;
54 uint32_t bmChunkId[(TEST2_ID_LAST + 1 + 31) / 32];
55};
56
57static uint32_t test2AllocId(struct TestMap2 *p2)
58{
59 /*
60 * Scan sequentially from the last one + 1.
61 */
62 int32_t idChunk = ++p2->idChunkPrev;
63 if ( (uint32_t)idChunk < TEST2_ID_LAST
64 && idChunk > NIL_TEST2_ID)
65 {
66 idChunk = ASMBitNextClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1, idChunk);
67 if (idChunk > NIL_TEST2_ID)
68 {
69 if (ASMAtomicBitTestAndSet(&p2->bmChunkId[0], idChunk))
70 {
71 RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
72 return NIL_TEST2_ID;
73 }
74 return p2->idChunkPrev = idChunk;
75 }
76 }
77
78 /*
79 * Ok, scan from the start.
80 */
81 idChunk = ASMBitFirstClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1);
82 if (idChunk <= NIL_TEST2_ID)
83 {
84 RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
85 return NIL_TEST2_ID;
86 }
87 if (ASMAtomicBitTestAndSet(&p2->bmChunkId[0], idChunk))
88 {
89 RTTestFailed(NIL_RTTEST, "line %d: idChunk=%#x", __LINE__, idChunk);
90 return NIL_TEST2_ID;
91 }
92
93 return p2->idChunkPrev = idChunk;
94}
95
96
97static void test2(RTTEST hTest)
98{
99 struct TestMap2 *p2 = (struct TestMap2 *)RTTestGuardedAllocTail(hTest, sizeof(TestMap2));
100 p2->idNil = NIL_TEST2_ID;
101 p2->idLast = TEST2_ID_LAST;
102
103 /* Some simple tests first. */
104 RT_ZERO(p2->bmChunkId);
105 RTTEST_CHECK(hTest, ASMBitFirstSet(&p2->bmChunkId[0], TEST2_ID_LAST + 1) == -1);
106 for (uint32_t iBit = 0; iBit <= TEST2_ID_LAST; iBit++)
107 RTTEST_CHECK(hTest, !ASMBitTest(&p2->bmChunkId[0], iBit));
108
109 memset(&p2->bmChunkId[0], 0xff, sizeof(p2->bmChunkId));
110 RTTEST_CHECK(hTest, ASMBitFirstClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1) == -1);
111 for (uint32_t iBit = 0; iBit <= TEST2_ID_LAST; iBit++)
112 RTTEST_CHECK(hTest, ASMBitTest(&p2->bmChunkId[0], iBit));
113
114 /* The real test. */
115 p2->idChunkPrev = 0;
116 RT_ZERO(p2->bmChunkId);
117 ASMBitSet(p2->bmChunkId, NIL_TEST2_ID);
118 uint32_t cLeft = TEST2_ID_LAST;
119 while (cLeft-- > 0)
120 test2AllocId(p2);
121
122 RTTEST_CHECK(hTest, ASMBitFirstClear(&p2->bmChunkId[0], TEST2_ID_LAST + 1) == -1);
123}
124
125
126int main()
127{
128 /*
129 * Init the runtime and stuff.
130 */
131 RTTEST hTest;
132 int rc = RTTestInitAndCreate("tstRTBitOperations", &hTest);
133 if (rc)
134 return rc;
135 RTTestBanner(hTest);
136
137 int rcRet = 0;
138 int i;
139 int j;
140 int k;
141
142 /*
143 * Tests
144 */
145 struct TestMap
146 {
147 uint32_t au32[4];
148 };
149#if 0
150 struct TestMap sTest;
151 struct TestMap *p = &sTest;
152#else
153 struct TestMap *p = (struct TestMap *)RTTestGuardedAllocTail(hTest, sizeof(*p));
154#endif
155#define DUMP() RTTestPrintf(hTest, RTTESTLVL_INFO, "au32={%08x,%08x,%08x,%08x}", p->au32[0], p->au32[1], p->au32[2], p->au32[3])
156#define CHECK(expr) do { if (!(expr)) { RTTestFailed(hTest, "line %d: %s", __LINE__, #expr); DUMP(); } CHECK_GUARD(s); } while (0)
157#define CHECK_BIT(expr, b1) do { if (!(expr)) { RTTestFailed(hTest, "line %d, b1=%d: %s", __LINE__, b1, #expr); } CHECK_GUARD(s); } while (0)
158#define CHECK_BIT2(expr, b1, b2) do { if (!(expr)) { RTTestFailed(hTest, "line %d, b1=%d b2=%d: %s", __LINE__, b1, b2, #expr); } CHECK_GUARD(s); } while (0)
159#define CHECK_BIT3(expr, b1, b2, b3) do { if (!(expr)) { RTTestFailed(hTest, "line %d, b1=%d b2=%d b3=%d: %s", __LINE__, b1, b2, b3, #expr); } CHECK_GUARD(s); } while (0)
160
161#define GUARD_MAP(p) do { } while (0)
162#define CHECK_GUARD(p) do { } while (0)
163#define MAP_CLEAR(p) do { RT_ZERO(*(p)); GUARD_MAP(p); } while (0)
164#define MAP_SET(p) do { memset(p, 0xff, sizeof(*(p))); GUARD_MAP(p); } while (0)
165
166 /* self check. */
167 MAP_CLEAR(p);
168 CHECK_GUARD(p);
169
170 /* set */
171 MAP_CLEAR(p);
172 ASMBitSet(&p->au32[0], 0);
173 ASMBitSet(&p->au32[0], 31);
174 ASMBitSet(&p->au32[0], 65);
175 CHECK(p->au32[0] == 0x80000001U);
176 CHECK(p->au32[2] == 0x00000002U);
177 CHECK(ASMBitTestAndSet(&p->au32[0], 0) && p->au32[0] == 0x80000001U);
178 CHECK(!ASMBitTestAndSet(&p->au32[0], 16) && p->au32[0] == 0x80010001U);
179 CHECK(ASMBitTestAndSet(&p->au32[0], 16) && p->au32[0] == 0x80010001U);
180 CHECK(!ASMBitTestAndSet(&p->au32[0], 80) && p->au32[2] == 0x00010002U);
181
182 MAP_CLEAR(p);
183 ASMAtomicBitSet(&p->au32[0], 0);
184 ASMAtomicBitSet(&p->au32[0], 30);
185 ASMAtomicBitSet(&p->au32[0], 64);
186 CHECK(p->au32[0] == 0x40000001U);
187 CHECK(p->au32[2] == 0x00000001U);
188 CHECK(ASMAtomicBitTestAndSet(&p->au32[0], 0) && p->au32[0] == 0x40000001U);
189 CHECK(!ASMAtomicBitTestAndSet(&p->au32[0], 16) && p->au32[0] == 0x40010001U);
190 CHECK(ASMAtomicBitTestAndSet(&p->au32[0], 16) && p->au32[0] == 0x40010001U);
191 CHECK(!ASMAtomicBitTestAndSet(&p->au32[0], 80) && p->au32[2] == 0x00010001U);
192
193 /* clear */
194 MAP_SET(p);
195 ASMBitClear(&p->au32[0], 0);
196 ASMBitClear(&p->au32[0], 31);
197 ASMBitClear(&p->au32[0], 65);
198 CHECK(p->au32[0] == ~0x80000001U);
199 CHECK(p->au32[2] == ~0x00000002U);
200 CHECK(!ASMBitTestAndClear(&p->au32[0], 0) && p->au32[0] == ~0x80000001U);
201 CHECK(ASMBitTestAndClear(&p->au32[0], 16) && p->au32[0] == ~0x80010001U);
202 CHECK(!ASMBitTestAndClear(&p->au32[0], 16) && p->au32[0] == ~0x80010001U);
203 CHECK(ASMBitTestAndClear(&p->au32[0], 80) && p->au32[2] == ~0x00010002U);
204
205 MAP_SET(p);
206 ASMAtomicBitClear(&p->au32[0], 0);
207 ASMAtomicBitClear(&p->au32[0], 30);
208 ASMAtomicBitClear(&p->au32[0], 64);
209 CHECK(p->au32[0] == ~0x40000001U);
210 CHECK(p->au32[2] == ~0x00000001U);
211 CHECK(!ASMAtomicBitTestAndClear(&p->au32[0], 0) && p->au32[0] == ~0x40000001U);
212 CHECK(ASMAtomicBitTestAndClear(&p->au32[0], 16) && p->au32[0] == ~0x40010001U);
213 CHECK(!ASMAtomicBitTestAndClear(&p->au32[0], 16) && p->au32[0] == ~0x40010001U);
214 CHECK(ASMAtomicBitTestAndClear(&p->au32[0], 80) && p->au32[2] == ~0x00010001U);
215
216 /* toggle */
217 MAP_SET(p);
218 ASMBitToggle(&p->au32[0], 0);
219 ASMBitToggle(&p->au32[0], 31);
220 ASMBitToggle(&p->au32[0], 65);
221 ASMBitToggle(&p->au32[0], 47);
222 ASMBitToggle(&p->au32[0], 47);
223 CHECK(p->au32[0] == ~0x80000001U);
224 CHECK(p->au32[2] == ~0x00000002U);
225 CHECK(!ASMBitTestAndToggle(&p->au32[0], 0) && p->au32[0] == ~0x80000000U);
226 CHECK(ASMBitTestAndToggle(&p->au32[0], 0) && p->au32[0] == ~0x80000001U);
227 CHECK(ASMBitTestAndToggle(&p->au32[0], 16) && p->au32[0] == ~0x80010001U);
228 CHECK(!ASMBitTestAndToggle(&p->au32[0], 16) && p->au32[0] == ~0x80000001U);
229 CHECK(ASMBitTestAndToggle(&p->au32[0], 80) && p->au32[2] == ~0x00010002U);
230
231 MAP_SET(p);
232 ASMAtomicBitToggle(&p->au32[0], 0);
233 ASMAtomicBitToggle(&p->au32[0], 30);
234 ASMAtomicBitToggle(&p->au32[0], 64);
235 ASMAtomicBitToggle(&p->au32[0], 47);
236 ASMAtomicBitToggle(&p->au32[0], 47);
237 CHECK(p->au32[0] == ~0x40000001U);
238 CHECK(p->au32[2] == ~0x00000001U);
239 CHECK(!ASMAtomicBitTestAndToggle(&p->au32[0], 0) && p->au32[0] == ~0x40000000U);
240 CHECK(ASMAtomicBitTestAndToggle(&p->au32[0], 0) && p->au32[0] == ~0x40000001U);
241 CHECK(ASMAtomicBitTestAndToggle(&p->au32[0], 16) && p->au32[0] == ~0x40010001U);
242 CHECK(!ASMAtomicBitTestAndToggle(&p->au32[0], 16) && p->au32[0] == ~0x40000001U);
243 CHECK(ASMAtomicBitTestAndToggle(&p->au32[0], 80) && p->au32[2] == ~0x00010001U);
244
245 /* test bit. */
246 for (i = 0; i < 128; i++)
247 {
248 MAP_SET(p);
249 CHECK_BIT(ASMBitTest(&p->au32[0], i), i);
250 ASMBitToggle(&p->au32[0], i);
251 CHECK_BIT(!ASMBitTest(&p->au32[0], i), i);
252 CHECK_BIT(!ASMBitTestAndToggle(&p->au32[0], i), i);
253 CHECK_BIT(ASMBitTest(&p->au32[0], i), i);
254 CHECK_BIT(ASMBitTestAndToggle(&p->au32[0], i), i);
255 CHECK_BIT(!ASMBitTest(&p->au32[0], i), i);
256
257 MAP_SET(p);
258 CHECK_BIT(ASMBitTest(&p->au32[0], i), i);
259 ASMAtomicBitToggle(&p->au32[0], i);
260 CHECK_BIT(!ASMBitTest(&p->au32[0], i), i);
261 CHECK_BIT(!ASMAtomicBitTestAndToggle(&p->au32[0], i), i);
262 CHECK_BIT(ASMBitTest(&p->au32[0], i), i);
263 CHECK_BIT(ASMAtomicBitTestAndToggle(&p->au32[0], i), i);
264 CHECK_BIT(!ASMBitTest(&p->au32[0], i), i);
265 }
266
267 /* bit searching */
268 MAP_SET(p);
269 CHECK(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == -1);
270 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 0);
271
272 ASMBitClear(&p->au32[0], 1);
273 CHECK(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == 1);
274 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 0);
275
276 MAP_SET(p);
277 ASMBitClear(&p->au32[0], 95);
278 CHECK(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == 95);
279 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 0);
280
281 MAP_SET(p);
282 ASMBitClear(&p->au32[0], 127);
283 CHECK(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == 127);
284 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 0);
285 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 0) == 1);
286 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 1) == 2);
287 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 2) == 3);
288
289
290 MAP_SET(p);
291 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 0) == -1);
292 ASMBitClear(&p->au32[0], 32);
293 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 32) == -1);
294 ASMBitClear(&p->au32[0], 88);
295 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 57) == 88);
296
297 MAP_SET(p);
298 ASMBitClear(&p->au32[0], 31);
299 ASMBitClear(&p->au32[0], 57);
300 ASMBitClear(&p->au32[0], 88);
301 ASMBitClear(&p->au32[0], 101);
302 ASMBitClear(&p->au32[0], 126);
303 ASMBitClear(&p->au32[0], 127);
304 CHECK(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == 31);
305 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 31) == 57);
306 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 57) == 88);
307 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 88) == 101);
308 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 101) == 126);
309 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 126) == 127);
310 CHECK(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, 127) == -1);
311
312 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 29) == 30);
313 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 30) == 32);
314
315 MAP_CLEAR(p);
316 for (i = 1; i < 128; i++)
317 CHECK_BIT(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, i - 1) == i, i);
318 for (i = 0; i < 128; i++)
319 {
320 MAP_SET(p);
321 ASMBitClear(&p->au32[0], i);
322 CHECK_BIT(ASMBitFirstClear(&p->au32[0], sizeof(p->au32) * 8) == i, i);
323 for (j = 0; j < i; j++)
324 CHECK_BIT(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, j) == i, i);
325 for (j = i; j < 128; j++)
326 CHECK_BIT(ASMBitNextClear(&p->au32[0], sizeof(p->au32) * 8, j) == -1, i);
327 }
328
329 /* clear range. */
330 MAP_SET(p);
331 ASMBitClearRange(&p->au32, 0, 128);
332 CHECK(!p->au32[0] && !p->au32[1] && !p->au32[2] && !p->au32[3]);
333 for (i = 0; i < 128; i++)
334 {
335 for (j = i + 1; j <= 128; j++)
336 {
337 MAP_SET(p);
338 ASMBitClearRange(&p->au32, i, j);
339 for (k = 0; k < i; k++)
340 CHECK_BIT3(ASMBitTest(&p->au32[0], k), i, j, k);
341 for (k = i; k < j; k++)
342 CHECK_BIT3(!ASMBitTest(&p->au32[0], k), i, j, k);
343 for (k = j; k < 128; k++)
344 CHECK_BIT3(ASMBitTest(&p->au32[0], k), i, j, k);
345 }
346 }
347
348 /* searching for set bits. */
349 MAP_CLEAR(p);
350 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == -1);
351
352 ASMBitSet(&p->au32[0], 65);
353 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 65);
354 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 65) == -1);
355 for (i = 0; i < 65; i++)
356 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, i) == 65);
357 for (i = 65; i < 128; i++)
358 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, i) == -1);
359
360 ASMBitSet(&p->au32[0], 17);
361 CHECK(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == 17);
362 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, 17) == 65);
363 for (i = 0; i < 16; i++)
364 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, i) == 17);
365 for (i = 17; i < 65; i++)
366 CHECK(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, i) == 65);
367
368 MAP_SET(p);
369 for (i = 1; i < 128; i++)
370 CHECK_BIT(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, i - 1) == i, i);
371 for (i = 0; i < 128; i++)
372 {
373 MAP_CLEAR(p);
374 ASMBitSet(&p->au32[0], i);
375 CHECK_BIT(ASMBitFirstSet(&p->au32[0], sizeof(p->au32) * 8) == i, i);
376 for (j = 0; j < i; j++)
377 CHECK_BIT(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, j) == i, i);
378 for (j = i; j < 128; j++)
379 CHECK_BIT(ASMBitNextSet(&p->au32[0], sizeof(p->au32) * 8, j) == -1, i);
380 }
381
382
383 CHECK(ASMBitLastSetU32(0) == 0);
384 CHECK(ASMBitLastSetU32(1) == 1);
385 CHECK(ASMBitLastSetU32(0x80000000) == 32);
386 CHECK(ASMBitLastSetU32(0xffffffff) == 32);
387 CHECK(ASMBitLastSetU32(RT_BIT(23) | RT_BIT(11)) == 24);
388 for (i = 0; i < 32; i++)
389 CHECK(ASMBitLastSetU32(1 << i) == (unsigned)i + 1);
390
391 CHECK(ASMBitFirstSetU32(0) == 0);
392 CHECK(ASMBitFirstSetU32(1) == 1);
393 CHECK(ASMBitFirstSetU32(0x80000000) == 32);
394 CHECK(ASMBitFirstSetU32(0xffffffff) == 1);
395 CHECK(ASMBitFirstSetU32(RT_BIT(23) | RT_BIT(11)) == 12);
396 for (i = 0; i < 32; i++)
397 CHECK(ASMBitFirstSetU32(1 << i) == (unsigned)i + 1);
398
399 /*
400 * Special tests.
401 */
402 test2(hTest);
403
404 /*
405 * Summary
406 */
407 return RTTestSummaryAndDestroy(hTest);
408}
409
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette