VirtualBox

source: vbox/trunk/src/VBox/Runtime/testcase/tstHandleTable.cpp@ 86715

Last change on this file since 86715 was 82968, checked in by vboxsync, 5 years ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 19.9 KB
Line 
1/* $Id: tstHandleTable.cpp 82968 2020-02-04 10:35:17Z vboxsync $ */
2/** @file
3 * IPRT Testcase - Handle Tables.
4 */
5
6/*
7 * Copyright (C) 2008-2020 Oracle Corporation
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
27
28/*********************************************************************************************************************************
29* Header Files *
30*********************************************************************************************************************************/
31#include <iprt/handletable.h>
32#include <iprt/stream.h>
33#include <iprt/initterm.h>
34#include <iprt/err.h>
35#include <iprt/getopt.h>
36#include <iprt/mem.h>
37#include <iprt/alloca.h>
38#include <iprt/thread.h>
39#include <iprt/string.h>
40
41
42/*********************************************************************************************************************************
43* Global Variables *
44*********************************************************************************************************************************/
45static unsigned g_cErrors;
46
47static DECLCALLBACK(void) tstHandleTableTest1Delete(RTHANDLETABLE hHandleTable, uint32_t h, void *pvObj, void *pvCtx, void *pvUser)
48{
49 uint32_t *pcCalls = (uint32_t *)pvUser;
50 (*pcCalls)++;
51 RT_NOREF_PV(hHandleTable); RT_NOREF_PV(h); RT_NOREF_PV(pvCtx); RT_NOREF_PV(pvObj);
52}
53
54static DECLCALLBACK(int) tstHandleTableTest1Retain(RTHANDLETABLE hHandleTable, void *pvObj, void *pvCtx, void *pvUser)
55{
56 uint32_t *pcCalls = (uint32_t *)pvUser;
57 (*pcCalls)++;
58 RT_NOREF_PV(hHandleTable); RT_NOREF_PV(pvCtx); RT_NOREF_PV(pvObj);
59 return VINF_SUCCESS;
60}
61
62static int tstHandleTableTest1(uint32_t uBase, uint32_t cMax, uint32_t cDelta, uint32_t cUnitsPerDot, bool fCallbacks, uint32_t fFlags)
63{
64 const char *pszWithCtx = fFlags & RTHANDLETABLE_FLAGS_CONTEXT ? "WithCtx" : "";
65 uint32_t cRetainerCalls = 0;
66 int rc;
67
68 RTPrintf("tstHandleTable: TESTING RTHandleTableCreateEx(, 0");
69 if (fFlags & RTHANDLETABLE_FLAGS_LOCKED) RTPrintf(" | LOCKED");
70 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT) RTPrintf(" | CONTEXT");
71 RTPrintf(", %#x, %#x,,)...\n", uBase, cMax);
72
73 RTHANDLETABLE hHT;
74 rc = RTHandleTableCreateEx(&hHT, fFlags, uBase, cMax,
75 fCallbacks ? tstHandleTableTest1Retain : NULL,
76 fCallbacks ? &cRetainerCalls : NULL);
77 if (RT_FAILURE(rc))
78 {
79 RTPrintf("\ntstHandleTable: FAILURE - RTHandleTableCreateEx failed, %Rrc!\n", rc);
80 return 1;
81 }
82
83 /* fill it */
84 RTPrintf("tstHandleTable: TESTING RTHandleTableAlloc%s..", pszWithCtx); RTStrmFlush(g_pStdOut);
85 uint32_t i = uBase;
86 for (;; i++)
87 {
88 uint32_t h;
89 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
90 rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)i * 4), NULL, &h);
91 else
92 rc = RTHandleTableAlloc(hHT, (void *)((uintptr_t)&i + (uintptr_t)i * 4), &h);
93 if (RT_SUCCESS(rc))
94 {
95 if (h != i)
96 {
97 RTPrintf("\ntstHandleTable: FAILURE (%d) - h=%d, expected %d!\n", __LINE__, h, i);
98 g_cErrors++;
99 }
100 }
101 else if (rc == VERR_NO_MORE_HANDLES)
102 {
103 if (i < cMax)
104 {
105 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, expected > 65534!\n", __LINE__, i);
106 g_cErrors++;
107 }
108 break;
109 }
110 else
111 {
112 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, rc=%Rrc!\n", __LINE__, i, rc);
113 g_cErrors++;
114 }
115 if (!(i % cUnitsPerDot))
116 {
117 RTPrintf(".");
118 RTStrmFlush(g_pStdOut);
119 }
120 }
121 uint32_t const c = i;
122 RTPrintf(" c=%#x\n", c);
123 if (fCallbacks && cRetainerCalls != 0)
124 {
125 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected 0!\n", __LINE__, cRetainerCalls);
126 g_cErrors++;
127 }
128
129 /* look up all the entries */
130 RTPrintf("tstHandleTable: TESTING RTHandleTableLookup%s..", pszWithCtx); RTStrmFlush(g_pStdOut);
131 cRetainerCalls = 0;
132 for (i = uBase; i < c; i++)
133 {
134 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4);
135 void *pvObj;
136 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
137 pvObj = RTHandleTableLookupWithCtx(hHT, i, NULL);
138 else
139 pvObj = RTHandleTableLookup(hHT, i);
140 if (!pvObj)
141 {
142 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s failed!\n", __LINE__, i, pszWithCtx);
143 g_cErrors++;
144 }
145 else if (pvObj != pvExpect)
146 {
147 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect);
148 g_cErrors++;
149 }
150 if (!(i % cUnitsPerDot))
151 {
152 RTPrintf(".");
153 RTStrmFlush(g_pStdOut);
154 }
155 }
156 RTPrintf("\n");
157 if (fCallbacks && cRetainerCalls != c - uBase)
158 {
159 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase);
160 g_cErrors++;
161 }
162
163 /* remove all the entries (in order) */
164 RTPrintf("tstHandleTable: TESTING RTHandleTableFree%s..", pszWithCtx); RTStrmFlush(g_pStdOut);
165 cRetainerCalls = 0;
166 for (i = uBase; i < c; i++)
167 {
168 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)i * 4);
169 void *pvObj;
170 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
171 pvObj = RTHandleTableFreeWithCtx(hHT, i, NULL);
172 else
173 pvObj = RTHandleTableFree(hHT, i);
174 if (!pvObj)
175 {
176 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s failed!\n", __LINE__, i, pszWithCtx);
177 g_cErrors++;
178 }
179 else if (pvObj != pvExpect)
180 {
181 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, pvObj=%p expected %p\n", __LINE__, i, pvObj, pvExpect);
182 g_cErrors++;
183 }
184 else if ( fFlags & RTHANDLETABLE_FLAGS_CONTEXT
185 ? RTHandleTableLookupWithCtx(hHT, i, NULL)
186 : RTHandleTableLookup(hHT, i))
187 {
188 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup%s succeeded after free!\n", __LINE__, i, pszWithCtx);
189 g_cErrors++;
190 }
191 if (!(i % cUnitsPerDot))
192 {
193 RTPrintf(".");
194 RTStrmFlush(g_pStdOut);
195 }
196 }
197 RTPrintf("\n");
198 if (fCallbacks && cRetainerCalls != c - uBase)
199 {
200 RTPrintf("tstHandleTable: FAILURE (%d) - cRetainerCalls=%#x expected %#x!\n", __LINE__, cRetainerCalls, c - uBase);
201 g_cErrors++;
202 }
203
204 /* do a mix of alloc, lookup and free where there is a constant of cDelta handles in the table. */
205 RTPrintf("tstHandleTable: TESTING Alloc,Lookup,Free mix [cDelta=%#x]..", cDelta); RTStrmFlush(g_pStdOut);
206 for (i = uBase; i < c * 2; i++)
207 {
208 /* alloc */
209 uint32_t hExpect = ((i - uBase) % (c - uBase)) + uBase;
210 uint32_t h;
211 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
212 rc = RTHandleTableAllocWithCtx(hHT, (void *)((uintptr_t)&i + (uintptr_t)hExpect * 4), NULL, &h);
213 else
214 rc = RTHandleTableAlloc(hHT, (void *)((uintptr_t)&i + (uintptr_t)hExpect * 4), &h);
215 if (RT_FAILURE(rc))
216 {
217 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAlloc%s: rc=%Rrc!\n", __LINE__, i, pszWithCtx, rc);
218 g_cErrors++;
219 }
220 else if (h != hExpect)
221 {
222 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableAlloc%s: h=%u hExpect=%u! - abort sub-test\n", __LINE__, i, pszWithCtx, h, hExpect);
223 g_cErrors++;
224 break;
225 }
226
227 if (i >= cDelta + uBase)
228 {
229 /* lookup */
230 for (uint32_t j = i - cDelta; j <= i; j++)
231 {
232 uint32_t hLookup = ((j - uBase) % (c - uBase)) + uBase;
233 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hLookup * 4);
234 void *pvObj;
235 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
236 pvObj = RTHandleTableLookupWithCtx(hHT, hLookup, NULL);
237 else
238 pvObj = RTHandleTableLookup(hHT, hLookup);
239 if (pvObj != pvExpect)
240 {
241 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookup%s(,%u,): pvObj=%p expected %p!\n",
242 __LINE__, i, j, pszWithCtx, hLookup, pvObj, pvExpect);
243 g_cErrors++;
244 }
245 else if ( (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
246 && RTHandleTableLookupWithCtx(hHT, hLookup, &i))
247 {
248 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, j=%d, RTHandleTableLookupWithCtx: succeeded with bad context\n",
249 __LINE__, i, j);
250 g_cErrors++;
251 }
252 }
253
254 /* free */
255 uint32_t hFree = ((i - uBase - cDelta) % (c - uBase)) + uBase;
256 void *pvExpect = (void *)((uintptr_t)&i + (uintptr_t)hFree * 4);
257 void *pvObj;
258 if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT)
259 pvObj = RTHandleTableFreeWithCtx(hHT, hFree, NULL);
260 else
261 pvObj = RTHandleTableFree(hHT, hFree);
262 if (pvObj != pvExpect)
263 {
264 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableFree%s: pvObj=%p expected %p!\n",
265 __LINE__, i, pszWithCtx, pvObj, pvExpect);
266 g_cErrors++;
267 }
268 else if (fFlags & RTHANDLETABLE_FLAGS_CONTEXT
269 ? RTHandleTableLookupWithCtx(hHT, hFree, NULL)
270 || RTHandleTableFreeWithCtx(hHT, hFree, NULL)
271 : RTHandleTableLookup(hHT, hFree)
272 || RTHandleTableFree(hHT, hFree))
273 {
274 RTPrintf("\ntstHandleTable: FAILURE (%d) - i=%d, RTHandleTableLookup/Free%s: succeeded after free\n",
275 __LINE__, i, pszWithCtx);
276 g_cErrors++;
277 }
278 }
279 if (!(i % (cUnitsPerDot * 2)))
280 {
281 RTPrintf(".");
282 RTStrmFlush(g_pStdOut);
283 }
284 }
285 RTPrintf("\n");
286
287 /* finally, destroy the table (note that there are 128 entries in it). */
288 cRetainerCalls = 0;
289 uint32_t cDeleteCalls = 0;
290 rc = RTHandleTableDestroy(hHT,
291 fCallbacks ? tstHandleTableTest1Delete : NULL,
292 fCallbacks ? &cDeleteCalls : NULL);
293 if (RT_FAILURE(rc))
294 {
295 RTPrintf("tstHandleTable: FAILURE (%d) - RTHandleTableDestroy failed, %Rrc!\n", __LINE__, rc);
296 g_cErrors++;
297 }
298
299 return 0;
300}
301
302
303typedef struct TSTHTTEST2ARGS
304{
305 /** The handle table. */
306 RTHANDLETABLE hHT;
307 /** The thread handle. */
308 RTTHREAD hThread;
309 /** Thread index. */
310 uint32_t iThread;
311 /** the max number of handles the thread should allocate. */
312 uint32_t cMax;
313} TSTHTTEST2ARGS, *PTSTHTTEST2ARGS;
314
315
316static DECLCALLBACK(int) tstHandleTableTest2Thread(RTTHREAD hThread, void *pvUser)
317{
318 RTHANDLETABLE const hHT = ((PTSTHTTEST2ARGS)pvUser)->hHT;
319 uint32_t const iThread = ((PTSTHTTEST2ARGS)pvUser)->iThread;
320 uint32_t const cMax = ((PTSTHTTEST2ARGS)pvUser)->cMax;
321 uint32_t *pah = (uint32_t *)RTMemAllocZ(sizeof(uint32_t) * cMax);
322 if (!pah)
323 {
324 RTPrintf("tstHandleTable: FAILURE (%d) - failed to allocate %zu bytes\n", __LINE__, sizeof(uint32_t) * cMax);
325 return VERR_NO_MEMORY;
326 }
327
328 /*
329 * Allocate our quota.
330 */
331 for (uint32_t i = 0; i < cMax; i++)
332 {
333 int rc = RTHandleTableAllocWithCtx(hHT, pvUser, hThread, &pah[i]);
334 if (RT_FAILURE(rc))
335 {
336 RTPrintf("tstHandleTable: FAILURE (%d) - t=%d i=%d: RTHandleTableAllocWithCtx failed, rc=%Rrc\n",
337 __LINE__, iThread, i, rc);
338 return rc;
339 }
340 }
341
342 /*
343 * Look them up.
344 */
345 for (uint32_t i = 0; i < cMax; i++)
346 {
347 void *pvObj = RTHandleTableLookupWithCtx(hHT, pah[i], hThread);
348 if (pvObj != pvUser)
349 {
350 RTPrintf("tstHandleTable: FAILURE (%d) - t=%d i=%d: RTHandleTableLookupWithCtx failed, pvObj=%p\n",
351 __LINE__, iThread, i, pvObj);
352 return VERR_INTERNAL_ERROR;
353 }
354 }
355
356 /*
357 * Free them all.
358 */
359 for (uint32_t i = 0; i < cMax; i++)
360 {
361 void *pvObj = RTHandleTableFreeWithCtx(hHT, pah[i], hThread);
362 if (pvObj != pvUser)
363 {
364 RTPrintf("tstHandleTable: FAILURE (%d) - t=%d i=%d: RTHandleTableFreeWithCtx failed, pvObj=%p\n",
365 __LINE__, iThread, i, pvObj);
366 return VERR_INTERNAL_ERROR;
367 }
368 }
369
370 RTMemFree(pah);
371 return VINF_SUCCESS;
372}
373
374static int tstHandleTableTest2(uint32_t uBase, uint32_t cMax, uint32_t cThreads)
375{
376 /*
377 * Create the table.
378 */
379 RTPrintf("tstHandleTable: TESTING %u threads: uBase=%u, cMax=%u\n", cThreads, uBase, cMax);
380 RTHANDLETABLE hHT;
381 int rc = RTHandleTableCreateEx(&hHT, RTHANDLETABLE_FLAGS_LOCKED | RTHANDLETABLE_FLAGS_CONTEXT, uBase, cMax, NULL, NULL);
382 if (RT_FAILURE(rc))
383 {
384 RTPrintf("tstHandleTable: FAILURE - RTHandleTableCreateEx failed, %Rrc!\n", rc);
385 return 1;
386 }
387 /// @todo there must be a race somewhere in the thread code, I keep hitting a duplicate insert id here...
388 // Or perhaps it just barcelona B2 bugs?
389 RTThreadSleep(50);
390
391 /*
392 * Spawn the threads.
393 */
394 PTSTHTTEST2ARGS paThread = (PTSTHTTEST2ARGS)alloca(sizeof(*paThread) * cThreads);
395 for (uint32_t i = 0; i < cThreads; i++)
396 {
397 paThread[i].hHT = hHT;
398 paThread[i].hThread = NIL_RTTHREAD;
399 paThread[i].iThread = i;
400 paThread[i].cMax = cMax / cThreads;
401 }
402 for (uint32_t i = 0; i < cThreads; i++)
403 {
404 char szName[32];
405 RTStrPrintf(szName, sizeof(szName), "TEST2-%x/%x", i, cMax);
406 rc = RTThreadCreate(&paThread[i].hThread, tstHandleTableTest2Thread, &paThread[i], 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, szName);
407 if (RT_FAILURE(rc))
408 {
409 RTPrintf("tstHandleTable: FAILURE - RTThreadCreate failed, %Rrc!\n", rc);
410 g_cErrors++;
411 break;
412 }
413 }
414
415 /*
416 * Wait for them to complete.
417 */
418 uint32_t cRunning = cThreads;
419 do /** @todo Remove when RTSemEventWait (linux) has been fixed. */
420 {
421 if (cRunning != cThreads)
422 RTThreadSleep(10);
423 cRunning = 0;
424 for (uint32_t i = 0; i < cThreads; i++)
425 if (paThread[i].hThread != NIL_RTTHREAD)
426 {
427 rc = RTThreadWait(paThread[i].hThread, RT_INDEFINITE_WAIT, NULL);
428 if (RT_SUCCESS(rc))
429 paThread[i].hThread = NIL_RTTHREAD;
430 else
431 cRunning++;
432 }
433 } while (cRunning);
434
435 /*
436 * Destroy the handle table.
437 */
438 rc = RTHandleTableDestroy(hHT, NULL, NULL);
439 if (RT_FAILURE(rc))
440 {
441 RTPrintf("tstHandleTable: FAILURE (%d) - RTHandleTableDestroy failed, %Rrc!\n", __LINE__, rc);
442 g_cErrors++;
443 }
444
445 return 0;
446}
447
448
449int main(int argc, char **argv)
450{
451 /*
452 * Init the runtime and parse the arguments.
453 */
454 RTR3InitExe(argc, &argv, 0);
455
456 static RTGETOPTDEF const s_aOptions[] =
457 {
458 { "--base", 'b', RTGETOPT_REQ_UINT32 },
459 { "--max", 'm', RTGETOPT_REQ_UINT32 },
460 { "--threads", 't', RTGETOPT_REQ_UINT32 },
461 };
462
463 uint32_t uBase = 0;
464 uint32_t cMax = 0;
465 uint32_t cThreads = 0;
466
467 int ch;
468 RTGETOPTUNION Value;
469 RTGETOPTSTATE GetState;
470 RTGetOptInit(&GetState, argc, argv, &s_aOptions[0], RT_ELEMENTS(s_aOptions), 1, 0 /* fFlags */);
471 while ((ch = RTGetOpt(&GetState, &Value)))
472 switch (ch)
473 {
474 case 'b':
475 uBase = Value.u32;
476 break;
477
478 case 'm':
479 cMax = Value.u32;
480 break;
481
482 case 't':
483 cThreads = Value.u32;
484 if (!cThreads)
485 cThreads = 1;
486 break;
487
488 case 'h':
489 RTPrintf("syntax: tstHandleTable [-b <base>] [-m <max>] [-t <threads>]\n");
490 return 1;
491
492 case 'V':
493 RTPrintf("$Revision: 82968 $\n");
494 return 0;
495
496 default:
497 return RTGetOptPrintError(ch, &Value);
498 }
499
500 /*
501 * If any argument was specified, run the requested test setup.
502 * Otherwise run a bunch of default tests.
503 */
504 if (cThreads || cMax || uBase)
505 {
506 if (!cMax)
507 cMax = 65535;
508 if (!cThreads)
509 tstHandleTableTest1(uBase, cMax, 128, cMax / 32, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
510 else
511 tstHandleTableTest2(uBase, cMax, 128);
512 }
513 else
514 {
515 /*
516 * Do a simple warmup / smoke test first.
517 */
518 tstHandleTableTest1(1, 65534, 128, 2048, false, 0);
519 tstHandleTableTest1(1, 65534, 128, 2048, false, RTHANDLETABLE_FLAGS_CONTEXT);
520 tstHandleTableTest1(1, 65534, 63, 2048, false, RTHANDLETABLE_FLAGS_LOCKED);
521 tstHandleTableTest1(1, 65534, 63, 2048, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
522 /* Test that the retain and delete functions work. */
523 tstHandleTableTest1(1, 1024, 256, 256, true, RTHANDLETABLE_FLAGS_LOCKED);
524 tstHandleTableTest1(1, 1024, 256, 256, true, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
525 /* check that the base works. */
526 tstHandleTableTest1(0x7ffff000, 65534, 4, 2048, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
527 tstHandleTableTest1(0xeffff000, 65534, 4, 2048, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
528 tstHandleTableTest1(0, 4097, 4, 256, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
529 tstHandleTableTest1(0, 1024, 4, 128, false, RTHANDLETABLE_FLAGS_CONTEXT | RTHANDLETABLE_FLAGS_LOCKED);
530 /* For testing 1st level expansion / reallocation. */
531 tstHandleTableTest1(1, 1024*1024*8, 3, 150000, false, 0);
532 tstHandleTableTest1(1, 1024*1024*8, 3, 150000, false, RTHANDLETABLE_FLAGS_CONTEXT);
533
534 /*
535 * Threaded tests.
536 */
537 tstHandleTableTest2(0x80000000, 32768, 2);
538 tstHandleTableTest2(0x00010000, 2048, 4);
539 tstHandleTableTest2(0x00010000, 3072, 8);
540 tstHandleTableTest2(0x00000000, 1024*1024*8, 3);
541 }
542
543 /*
544 * Summary.
545 */
546 if (!g_cErrors)
547 RTPrintf("tstHandleTable: SUCCESS\n");
548 else
549 RTPrintf("tstHandleTable: FAILURE - %d errors\n", g_cErrors);
550
551 return !!g_cErrors;
552}
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