VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstPDMAsyncCompletionStress.cpp@ 26223

Last change on this file since 26223 was 23973, checked in by vboxsync, 15 years ago

*,RTFileOpen: Fixing RTFileOpen flag misdesign: The deny, access and action flags are mandatory now.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.0 KB
Line 
1/* $Id: tstPDMAsyncCompletionStress.cpp 23973 2009-10-22 12:34:22Z vboxsync $ */
2/** @file
3 * PDM Asynchronous Completion Stresstest.
4 *
5 * This testcase is for stress testing the async completion interface.
6 */
7
8/*
9 * Copyright (C) 2008-2009 Sun Microsystems, Inc.
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
20 * Clara, CA 95054 USA or visit http://www.sun.com if you need
21 * additional information or have any questions.
22 */
23
24/*******************************************************************************
25* Header Files *
26*******************************************************************************/
27#define LOG_GROUP LOG_GROUP_PDM_ASYNC_COMPLETION
28
29#include "../VMInternal.h" /* UVM */
30#include <VBox/vm.h>
31#include <VBox/uvm.h>
32#include <VBox/pdmasynccompletion.h>
33#include <VBox/vmm.h>
34#include <VBox/cpum.h>
35#include <VBox/err.h>
36#include <VBox/log.h>
37#include <VBox/pdmapi.h>
38#include <VBox/pdmthread.h>
39#include <iprt/alloc.h>
40#include <iprt/asm.h>
41#include <iprt/assert.h>
42#include <iprt/file.h>
43#include <iprt/initterm.h>
44#include <iprt/semaphore.h>
45#include <iprt/rand.h>
46#include <iprt/string.h>
47#include <iprt/path.h>
48#include <iprt/stream.h>
49#include <iprt/thread.h>
50#include <iprt/param.h>
51
52#define TESTCASE "tstPDMAsyncCompletionStress"
53
54#if 0
55/** Number of simultaneous open endpoints for reading and writing. */
56#define NR_OPEN_ENDPOINTS 10
57/** Test pattern size. */
58#define TEST_PATTERN_SIZE (100*_1M)
59/** Minimum file size. */
60#define FILE_SIZE_MIN (100 * _1M)
61/** Maximum file size. */
62#define FILE_SIZE_MAX (10000UL * _1M)
63/** Minimum segment size. */
64#define SEGMENT_SIZE_MIN (512)
65/** Maximum segment size. */
66#define SEGMENT_SIZE_MAX (TEST_PATTERN_SIZE)
67/** Maximum number of active tasks. */
68#define TASK_ACTIVE_MAX (1024)
69/** Maximum size of a transfer. */
70#define TASK_TRANSFER_SIZE_MAX (10*_1M)
71#else
72/** Number of simultaneous open endpoints for reading and writing. */
73#define NR_OPEN_ENDPOINTS 5
74/** Test pattern size. */
75#define TEST_PATTERN_SIZE (10*_1M)
76/** Minimum file size. */
77#define FILE_SIZE_MIN (100 * _1M)
78/** Maximum file size. */
79#define FILE_SIZE_MAX (1000UL * _1M)
80/** Minimum segment size. */
81#define SEGMENT_SIZE_MIN (512)
82/** Maximum segment size. */
83#define SEGMENT_SIZE_MAX (TEST_PATTERN_SIZE)
84/** Maximum number of active tasks. */
85#define TASK_ACTIVE_MAX (1)
86/** Maximum size of a transfer. */
87#define TASK_TRANSFER_SIZE_MAX (_1M)
88#endif
89
90/**
91 * Structure defining a file segment.
92 */
93typedef struct PDMACTESTFILESEG
94{
95 /** Start offset in the file. */
96 RTFOFF off;
97 /** Size of the segment. */
98 size_t cbSegment;
99 /** Pointer to the start of the data in the test pattern used for the segment. */
100 uint8_t *pbData;
101} PDMACTESTFILESEG, *PPDMACTESTFILESEG;
102
103/**
104 * Structure defining a I/O task.
105 */
106typedef struct PDMACTESTFILETASK
107{
108 /** Flag whether the task is currently active. */
109 bool fActive;
110 /** Flag whether this is a write. */
111 bool fWrite;
112 /** Start offset. */
113 RTFOFF off;
114 /** Data segment */
115 PDMDATASEG DataSeg;
116 /** Task handle. */
117 PPDMASYNCCOMPLETIONTASK hTask;
118} PDMACTESTFILETASK, *PPDMACTESTFILETASK;
119
120/**
121 * Structure defining a test file.
122 */
123typedef struct PDMACTESTFILE
124{
125 /** The PDM async completion endpoint handle. */
126 PPDMASYNCCOMPLETIONENDPOINT hEndpoint;
127 /** Template used for this file. */
128 PPDMASYNCCOMPLETIONTEMPLATE pTemplate;
129 /** Maximum size of the file. */
130 uint64_t cbFileMax;
131 /** Current size of the file. */
132 uint64_t cbFileCurr;
133 /** Size of a file segment. */
134 size_t cbFileSegment;
135 /** Maximum number of segments. */
136 unsigned cSegments;
137 /** Pointer to the array describing how the file is assembled
138 * of the test pattern. Used for comparing read data to ensure
139 * that no corruption occured.
140 */
141 PPDMACTESTFILESEG paSegs;
142 /** Maximum number of active tasks for this endpoint. */
143 uint32_t cTasksActiveMax;
144 /** Number of current active tasks. */
145 volatile uint32_t cTasksActiveCurr;
146 /** Pointer to the array of task. */
147 PPDMACTESTFILETASK paTasks;
148 /** I/O thread handle. */
149 PPDMTHREAD hThread;
150 /** Flag whether the thread should terminate. */
151 bool fRunning;
152} PDMACTESTFILE, *PPDMACTESTFILE;
153
154/** Buffer storing the random test pattern. */
155uint8_t *g_pbTestPattern = NULL;
156/** Size of the test pattern. */
157size_t g_cbTestPattern;
158/** Array holding test files. */
159PDMACTESTFILE g_aTestFiles[NR_OPEN_ENDPOINTS];
160
161static void tstPDMACStressTestFileVerify(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
162{
163 size_t cbLeft = pTestTask->DataSeg.cbSeg;
164 RTFOFF off = pTestTask->off;
165 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
166
167 while (cbLeft)
168 {
169 size_t cbCompare;
170 unsigned iSeg = off / pTestFile->cbFileSegment;
171 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
172 uint8_t *pbTestPattern;
173 unsigned offSeg = off - pSeg->off;
174
175 cbCompare = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
176 pbTestPattern = pSeg->pbData + offSeg;
177
178 if (memcmp(pbBuf, pbTestPattern, cbCompare))
179 AssertMsgFailed(("Unexpected data for off=%RTfoff size=%u\n", pTestTask->off, pTestTask->DataSeg.cbSeg));
180
181 pbBuf += cbCompare;
182 off += cbCompare;
183 cbLeft -= cbCompare;
184 }
185}
186
187static void tstPDMACStressTestFileFillBuffer(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
188{
189 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
190 size_t cbLeft = pTestTask->DataSeg.cbSeg;
191 RTFOFF off = pTestTask->off;
192
193 Assert(pTestTask->fWrite && pTestTask->fActive);
194
195 while (cbLeft)
196 {
197 size_t cbFill;
198 unsigned iSeg = off / pTestFile->cbFileSegment;
199 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
200 uint8_t *pbTestPattern;
201 unsigned offSeg = off - pSeg->off;
202
203 cbFill = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
204 pbTestPattern = pSeg->pbData + offSeg;
205
206 memcpy(pbBuf, pbTestPattern, cbFill);
207
208 pbBuf += cbFill;
209 off += cbFill;
210 cbLeft -= cbFill;
211 }
212}
213
214static int tstPDMACStressTestFileWrite(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
215{
216 int rc = VINF_SUCCESS;
217
218 Assert(!pTestTask->fActive);
219
220 pTestTask->fActive = true;
221 pTestTask->fWrite = true;
222 pTestTask->DataSeg.cbSeg = RTRandU32Ex(512, TASK_TRANSFER_SIZE_MAX) & ~511;
223
224 uint64_t offMax;
225
226 /* Did we reached the maximum file size */
227 if (pTestFile->cbFileCurr < pTestFile->cbFileMax)
228 {
229 offMax = (pTestFile->cbFileMax - pTestFile->cbFileCurr) < pTestTask->DataSeg.cbSeg
230 ? pTestFile->cbFileMax - pTestTask->DataSeg.cbSeg
231 : pTestFile->cbFileCurr;
232 }
233 else
234 offMax = pTestFile->cbFileMax - pTestTask->DataSeg.cbSeg;
235
236 uint64_t offMin;
237
238 /*
239 * If we reached the maximum file size write in the whole file
240 * otherwise we will enforce the range for random offsets to let it grow
241 * more quickly.
242 */
243 if (pTestFile->cbFileCurr == pTestFile->cbFileMax)
244 offMin = 0;
245 else
246 offMin = RT_MIN(pTestFile->cbFileCurr, offMax);
247
248
249 pTestTask->off = RTRandU64Ex(offMin, offMax) & ~511;
250
251 /* Set new file size of required */
252 if ((uint64_t)pTestTask->off + pTestTask->DataSeg.cbSeg > pTestFile->cbFileCurr)
253 pTestFile->cbFileCurr = pTestTask->off + pTestTask->DataSeg.cbSeg;
254
255 AssertMsg(pTestFile->cbFileCurr <= pTestFile->cbFileMax,
256 ("Current file size (%llu) exceeds final size (%llu)\n",
257 pTestFile->cbFileCurr, pTestFile->cbFileMax));
258
259 /* Allocate data buffer. */
260 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
261 if (!pTestTask->DataSeg.pvSeg)
262 return VERR_NO_MEMORY;
263
264 /* Fill data into buffer. */
265 tstPDMACStressTestFileFillBuffer(pTestFile, pTestTask);
266
267 /* Engage */
268 rc = PDMR3AsyncCompletionEpWrite(pTestFile->hEndpoint, pTestTask->off,
269 &pTestTask->DataSeg, 1,
270 pTestTask->DataSeg.cbSeg,
271 pTestTask,
272 &pTestTask->hTask);
273
274 return rc;
275}
276
277static int tstPDMACStressTestFileRead(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
278{
279 int rc = VINF_SUCCESS;
280
281 Assert(!pTestTask->fActive);
282
283 pTestTask->fActive = true;
284 pTestTask->fWrite = false;
285 pTestTask->DataSeg.cbSeg = RTRandU32Ex(1, RT_MIN(pTestFile->cbFileCurr, TASK_TRANSFER_SIZE_MAX));
286
287 AssertMsg(pTestFile->cbFileCurr >= pTestTask->DataSeg.cbSeg, ("Impossible\n"));
288 pTestTask->off = RTRandU64Ex(0, pTestFile->cbFileCurr - pTestTask->DataSeg.cbSeg);
289
290 /* Allocate data buffer. */
291 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
292 if (!pTestTask->DataSeg.pvSeg)
293 return VERR_NO_MEMORY;
294
295 /* Engage */
296 rc = PDMR3AsyncCompletionEpRead(pTestFile->hEndpoint, pTestTask->off,
297 &pTestTask->DataSeg, 1,
298 pTestTask->DataSeg.cbSeg,
299 pTestTask,
300 &pTestTask->hTask);
301
302 return rc;
303}
304
305/**
306 * Returns true with the given chance in percent.
307 *
308 * @returns true or false
309 * @param iPercentage The percentage of the chance to return true.
310 */
311static bool tstPDMACTestIsTrue(int iPercentage)
312{
313 int uRnd = RTRandU32Ex(0, 100);
314
315 return (uRnd < iPercentage); /* This should be enough for our purpose */
316}
317
318static int tstPDMACTestFileThread(PVM pVM, PPDMTHREAD pThread)
319{
320 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pThread->pvUser;
321 int iWriteChance = 100; /* Chance to get a write task in percent. */
322 uint32_t cTasksStarted = 0;
323 int rc = VINF_SUCCESS;
324
325 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
326 return VINF_SUCCESS;
327
328 while (pTestFile->fRunning)
329 {
330 unsigned iTaskCurr = 0;
331
332
333 /* Fill all tasks */
334 while ( (pTestFile->cTasksActiveCurr < pTestFile->cTasksActiveMax)
335 && (iTaskCurr < pTestFile->cTasksActiveMax))
336 {
337 PPDMACTESTFILETASK pTask = &pTestFile->paTasks[iTaskCurr];
338
339 if (!pTask->fActive)
340 {
341 /* Read or write task? */
342 bool fWrite = tstPDMACTestIsTrue(iWriteChance);
343
344 ASMAtomicIncU32(&pTestFile->cTasksActiveCurr);
345
346 if (fWrite)
347 rc = tstPDMACStressTestFileWrite(pTestFile, pTask);
348 else
349 rc = tstPDMACStressTestFileRead(pTestFile, pTask);
350
351 AssertRC(rc);
352
353 cTasksStarted++;
354 }
355
356 iTaskCurr++;
357 }
358
359 /*
360 * Recalc write chance. The bigger the file the lower the chance to have a write.
361 * The minimum chance is 33 percent.
362 */
363 iWriteChance = 100 - (int)(((float)100.0 / pTestFile->cbFileMax) * (float)pTestFile->cbFileCurr);
364 iWriteChance = RT_MAX(33, iWriteChance);
365
366 /* Wait a random amount of time. (1ms - 100ms) */
367 RTThreadSleep(RTRandU32Ex(1, 100));
368 }
369
370 /* Wait for the rest to complete. */
371 while (pTestFile->cTasksActiveCurr)
372 RTThreadSleep(250);
373
374 RTPrintf("Thread exiting: processed %u tasks\n", cTasksStarted);
375 return rc;
376}
377
378static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2)
379{
380 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
381 PPDMACTESTFILETASK pTestTask = (PPDMACTESTFILETASK)pvUser;
382
383 if (pTestTask->fWrite)
384 {
385 /* @todo Do something sensible here. */
386 }
387 else
388 {
389 tstPDMACStressTestFileVerify(pTestFile, pTestTask); /* Will assert if it fails */
390 }
391
392 RTMemFree(pTestTask->DataSeg.pvSeg);
393 pTestTask->fActive = false;
394 AssertMsg(pTestFile->cTasksActiveCurr > 0, ("Trying to complete a non active task\n"));
395 ASMAtomicDecU32(&pTestFile->cTasksActiveCurr);
396}
397
398/**
399 * Sets up a test file creating the I/O thread.
400 *
401 * @returns VBox status code.
402 * @param pVM Pointer to the shared VM instance structure.
403 * @param pTestFile Pointer to the uninitialized test file structure.
404 * @param iTestId Unique test id.
405 */
406static int tstPDMACStressTestFileOpen(PVM pVM, PPDMACTESTFILE pTestFile, unsigned iTestId)
407{
408 int rc = VERR_NO_MEMORY;
409
410 /* Size is a multiple of 512 */
411 pTestFile->cbFileMax = RTRandU64Ex(FILE_SIZE_MIN, FILE_SIZE_MAX) & ~(511UL);
412 pTestFile->cbFileCurr = 0;
413 pTestFile->cbFileSegment = RTRandU32Ex(SEGMENT_SIZE_MIN, RT_MIN(pTestFile->cbFileMax, SEGMENT_SIZE_MAX)) & ~((size_t)511);
414
415 Assert(pTestFile->cbFileMax >= pTestFile->cbFileSegment);
416
417 /* Set up the segments array. */
418 pTestFile->cSegments = pTestFile->cbFileMax / pTestFile->cbFileSegment;
419 pTestFile->cSegments += ((pTestFile->cbFileMax % pTestFile->cbFileSegment) > 0) ? 1 : 0;
420
421 pTestFile->paSegs = (PPDMACTESTFILESEG)RTMemAllocZ(pTestFile->cSegments * sizeof(PDMACTESTFILESEG));
422 if (pTestFile->paSegs)
423 {
424 /* Init the segments */
425 for (unsigned i = 0; i < pTestFile->cSegments; i++)
426 {
427 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[i];
428
429 pSeg->off = (RTFOFF)i * pTestFile->cbFileSegment;
430 pSeg->cbSegment = pTestFile->cbFileSegment;
431
432 /* Let the buffer point to a random position in the test pattern. */
433 uint32_t offTestPattern = RTRandU64Ex(0, g_cbTestPattern - pSeg->cbSegment);
434
435 pSeg->pbData = g_pbTestPattern + offTestPattern;
436 }
437
438 /* Init task array. */
439 pTestFile->cTasksActiveMax = RTRandU32Ex(1, TASK_ACTIVE_MAX);
440 pTestFile->paTasks = (PPDMACTESTFILETASK)RTMemAllocZ(pTestFile->cTasksActiveMax * sizeof(PDMACTESTFILETASK));
441 if (pTestFile->paTasks)
442 {
443 /* Create the template */
444 char szDesc[256];
445
446 RTStrPrintf(szDesc, sizeof(szDesc), "Template-%d", iTestId);
447 rc = PDMR3AsyncCompletionTemplateCreateInternal(pVM, &pTestFile->pTemplate, tstPDMACStressTestFileTaskCompleted, pTestFile, szDesc);
448 if (RT_SUCCESS(rc))
449 {
450 /* Open the endpoint now. Because async completion endpoints cannot create files we have to do it before. */
451 char szFile[RTPATH_MAX];
452
453 RTStrPrintf(szFile, sizeof(szFile), "tstPDMAsyncCompletionStress-%d.tmp", iTestId);
454
455 RTFILE FileTmp;
456 rc = RTFileOpen(&FileTmp, szFile, RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE);
457 if (RT_SUCCESS(rc))
458 {
459 RTFileClose(FileTmp);
460
461 rc = PDMR3AsyncCompletionEpCreateForFile(&pTestFile->hEndpoint, szFile, PDMACEP_FILE_FLAGS_CACHING, pTestFile->pTemplate);
462 if (RT_SUCCESS(rc))
463 {
464 char szThreadDesc[256];
465
466 pTestFile->fRunning = true;
467
468 /* Create the thread creating the I/O for the given file. */
469 RTStrPrintf(szThreadDesc, sizeof(szThreadDesc), "PDMACThread-%d", iTestId);
470 rc = PDMR3ThreadCreate(pVM, &pTestFile->hThread, pTestFile, tstPDMACTestFileThread,
471 NULL, 0, RTTHREADTYPE_IO, szThreadDesc);
472 if (RT_SUCCESS(rc))
473 {
474 rc = PDMR3ThreadResume(pTestFile->hThread);
475 AssertRC(rc);
476
477 RTPrintf(TESTCASE ": Created test file %s cbFileMax=%llu cbFileSegment=%u cSegments=%u cTasksActiveMax=%u\n",
478 szFile, pTestFile->cbFileMax, pTestFile->cbFileSegment, pTestFile->cSegments, pTestFile->cTasksActiveMax);
479 return VINF_SUCCESS;
480 }
481
482 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
483 }
484
485 RTFileDelete(szFile);
486 }
487
488 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
489 }
490
491 RTMemFree(pTestFile->paTasks);
492 }
493 else
494 rc = VERR_NO_MEMORY;
495
496 RTMemFree(pTestFile->paSegs);
497 }
498 else
499 rc = VERR_NO_MEMORY;
500
501 RTPrintf(TESTCASE ": Opening test file with id %d failed rc=%Rrc\n", iTestId, rc);
502
503 return rc;
504}
505
506/**
507 * Closes a test file.
508 *
509 * @returns nothing.
510 * @param pTestFile Pointer to the test file.
511 */
512static void tstPDMACStressTestFileClose(PPDMACTESTFILE pTestFile)
513{
514 int rcThread;
515 int rc;
516
517 RTPrintf("Terminating I/O thread, please wait...\n");
518
519 /* Let the thread know that it should terminate. */
520 pTestFile->fRunning = false;
521
522 /* Wait for the thread to terminate. */
523 rc = PDMR3ThreadDestroy(pTestFile->hThread, &rcThread);
524
525 RTPrintf("Thread terminated with status code rc=%Rrc\n", rcThread);
526
527 /* Free resources */
528 RTMemFree(pTestFile->paTasks);
529 RTMemFree(pTestFile->paSegs);
530 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
531 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
532}
533
534/**
535 * Inits the test pattern.
536 *
537 * @returns VBox status code.
538 */
539static int tstPDMACStressTestPatternInit(void)
540{
541 RTPrintf(TESTCASE ": Creating test pattern. Please wait...\n");
542 g_cbTestPattern = TEST_PATTERN_SIZE;
543 g_pbTestPattern = (uint8_t *)RTMemAlloc(g_cbTestPattern);
544 if (!g_pbTestPattern)
545 return VERR_NO_MEMORY;
546
547 RTRandBytes(g_pbTestPattern, g_cbTestPattern);
548 return VINF_SUCCESS;
549}
550
551static void tstPDMACStressTestPatternDestroy(void)
552{
553 RTPrintf(TESTCASE ": Destroying test pattern\n");
554 RTMemFree(g_pbTestPattern);
555}
556
557int main(int argc, char *argv[])
558{
559 int rcRet = 0; /* error count */
560 int rc = VINF_SUCCESS;
561
562 RTR3InitAndSUPLib();
563
564 PVM pVM;
565 rc = VMR3Create(1, NULL, NULL, NULL, NULL, &pVM);
566 if (RT_SUCCESS(rc))
567 {
568 /*
569 * Little hack to avoid the VM_ASSERT_EMT assertion.
570 */
571 RTTlsSet(pVM->pUVM->vm.s.idxTLS, &pVM->pUVM->aCpus[0]);
572 pVM->pUVM->aCpus[0].pUVM = pVM->pUVM;
573 pVM->pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
574
575 rc = tstPDMACStressTestPatternInit();
576 if (RT_SUCCESS(rc))
577 {
578 unsigned cFilesOpened = 0;
579
580 /* Open the endpoints. */
581 for (cFilesOpened = 0; cFilesOpened < NR_OPEN_ENDPOINTS; cFilesOpened++)
582 {
583 rc = tstPDMACStressTestFileOpen(pVM, &g_aTestFiles[cFilesOpened], cFilesOpened);
584 if (RT_FAILURE(rc))
585 break;
586 }
587
588 if (RT_SUCCESS(rc))
589 {
590 /* Tests are running now. */
591 RTPrintf(TESTCASE ": Successfully opened all files. Running tests forever now or until an error is hit :)\n");
592 RTThreadSleep(RT_INDEFINITE_WAIT);
593 }
594
595 /* Close opened endpoints. */
596 for (unsigned i = 0; i < cFilesOpened; i++)
597 tstPDMACStressTestFileClose(&g_aTestFiles[i]);
598
599 tstPDMACStressTestPatternDestroy();
600 }
601 else
602 {
603 RTPrintf(TESTCASE ": failed to init test pattern!! rc=%Rrc\n", rc);
604 rcRet++;
605 }
606
607 rc = VMR3Destroy(pVM);
608 AssertMsg(rc == VINF_SUCCESS, ("%s: Destroying VM failed rc=%Rrc!!\n", __FUNCTION__, rc));
609 }
610 else
611 {
612 RTPrintf(TESTCASE ": failed to create VM!! rc=%Rrc\n", rc);
613 rcRet++;
614 }
615
616 return rcRet;
617}
618
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