VirtualBox

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

Last change on this file since 26263 was 26240, checked in by vboxsync, 15 years ago

AsyncCompletion: Cleanup

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.2 KB
Line 
1/* $Id: tstPDMAsyncCompletionStress.cpp 26240 2010-02-04 15:35:02Z 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.215389.xyz. 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 tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2);
162
163static void tstPDMACStressTestFileVerify(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
164{
165 size_t cbLeft = pTestTask->DataSeg.cbSeg;
166 RTFOFF off = pTestTask->off;
167 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
168
169 while (cbLeft)
170 {
171 size_t cbCompare;
172 unsigned iSeg = off / pTestFile->cbFileSegment;
173 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
174 uint8_t *pbTestPattern;
175 unsigned offSeg = off - pSeg->off;
176
177 cbCompare = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
178 pbTestPattern = pSeg->pbData + offSeg;
179
180 if (memcmp(pbBuf, pbTestPattern, cbCompare))
181 AssertMsgFailed(("Unexpected data for off=%RTfoff size=%u\n", pTestTask->off, pTestTask->DataSeg.cbSeg));
182
183 pbBuf += cbCompare;
184 off += cbCompare;
185 cbLeft -= cbCompare;
186 }
187}
188
189static void tstPDMACStressTestFileFillBuffer(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
190{
191 uint8_t *pbBuf = (uint8_t *)pTestTask->DataSeg.pvSeg;
192 size_t cbLeft = pTestTask->DataSeg.cbSeg;
193 RTFOFF off = pTestTask->off;
194
195 Assert(pTestTask->fWrite && pTestTask->fActive);
196
197 while (cbLeft)
198 {
199 size_t cbFill;
200 unsigned iSeg = off / pTestFile->cbFileSegment;
201 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[iSeg];
202 uint8_t *pbTestPattern;
203 unsigned offSeg = off - pSeg->off;
204
205 cbFill = RT_MIN(cbLeft, pSeg->cbSegment - offSeg);
206 pbTestPattern = pSeg->pbData + offSeg;
207
208 memcpy(pbBuf, pbTestPattern, cbFill);
209
210 pbBuf += cbFill;
211 off += cbFill;
212 cbLeft -= cbFill;
213 }
214}
215
216static int tstPDMACStressTestFileWrite(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
217{
218 int rc = VINF_SUCCESS;
219
220 Assert(!pTestTask->fActive);
221
222 pTestTask->fActive = true;
223 pTestTask->fWrite = true;
224 pTestTask->DataSeg.cbSeg = RTRandU32Ex(512, TASK_TRANSFER_SIZE_MAX) & ~511;
225
226 uint64_t offMax;
227
228 /* Did we reached the maximum file size */
229 if (pTestFile->cbFileCurr < pTestFile->cbFileMax)
230 {
231 offMax = (pTestFile->cbFileMax - pTestFile->cbFileCurr) < pTestTask->DataSeg.cbSeg
232 ? pTestFile->cbFileMax - pTestTask->DataSeg.cbSeg
233 : pTestFile->cbFileCurr;
234 }
235 else
236 offMax = pTestFile->cbFileMax - pTestTask->DataSeg.cbSeg;
237
238 uint64_t offMin;
239
240 /*
241 * If we reached the maximum file size write in the whole file
242 * otherwise we will enforce the range for random offsets to let it grow
243 * more quickly.
244 */
245 if (pTestFile->cbFileCurr == pTestFile->cbFileMax)
246 offMin = 0;
247 else
248 offMin = RT_MIN(pTestFile->cbFileCurr, offMax);
249
250
251 pTestTask->off = RTRandU64Ex(offMin, offMax) & ~511;
252
253 /* Set new file size of required */
254 if ((uint64_t)pTestTask->off + pTestTask->DataSeg.cbSeg > pTestFile->cbFileCurr)
255 pTestFile->cbFileCurr = pTestTask->off + pTestTask->DataSeg.cbSeg;
256
257 AssertMsg(pTestFile->cbFileCurr <= pTestFile->cbFileMax,
258 ("Current file size (%llu) exceeds final size (%llu)\n",
259 pTestFile->cbFileCurr, pTestFile->cbFileMax));
260
261 /* Allocate data buffer. */
262 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
263 if (!pTestTask->DataSeg.pvSeg)
264 return VERR_NO_MEMORY;
265
266 /* Fill data into buffer. */
267 tstPDMACStressTestFileFillBuffer(pTestFile, pTestTask);
268
269 /* Engage */
270 rc = PDMR3AsyncCompletionEpWrite(pTestFile->hEndpoint, pTestTask->off,
271 &pTestTask->DataSeg, 1,
272 pTestTask->DataSeg.cbSeg,
273 pTestTask,
274 &pTestTask->hTask);
275
276 return rc;
277}
278
279static int tstPDMACStressTestFileRead(PPDMACTESTFILE pTestFile, PPDMACTESTFILETASK pTestTask)
280{
281 int rc = VINF_SUCCESS;
282
283 Assert(!pTestTask->fActive);
284
285 pTestTask->fActive = true;
286 pTestTask->fWrite = false;
287 pTestTask->DataSeg.cbSeg = RTRandU32Ex(1, RT_MIN(pTestFile->cbFileCurr, TASK_TRANSFER_SIZE_MAX));
288
289 AssertMsg(pTestFile->cbFileCurr >= pTestTask->DataSeg.cbSeg, ("Impossible\n"));
290 pTestTask->off = RTRandU64Ex(0, pTestFile->cbFileCurr - pTestTask->DataSeg.cbSeg);
291
292 /* Allocate data buffer. */
293 pTestTask->DataSeg.pvSeg = RTMemAlloc(pTestTask->DataSeg.cbSeg);
294 if (!pTestTask->DataSeg.pvSeg)
295 return VERR_NO_MEMORY;
296
297 /* Engage */
298 rc = PDMR3AsyncCompletionEpRead(pTestFile->hEndpoint, pTestTask->off,
299 &pTestTask->DataSeg, 1,
300 pTestTask->DataSeg.cbSeg,
301 pTestTask,
302 &pTestTask->hTask);
303
304 return rc;
305}
306
307/**
308 * Returns true with the given chance in percent.
309 *
310 * @returns true or false
311 * @param iPercentage The percentage of the chance to return true.
312 */
313static bool tstPDMACTestIsTrue(int iPercentage)
314{
315 int uRnd = RTRandU32Ex(0, 100);
316
317 return (uRnd < iPercentage); /* This should be enough for our purpose */
318}
319
320static int tstPDMACTestFileThread(PVM pVM, PPDMTHREAD pThread)
321{
322 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pThread->pvUser;
323 int iWriteChance = 100; /* Chance to get a write task in percent. */
324 uint32_t cTasksStarted = 0;
325 int rc = VINF_SUCCESS;
326
327 if (pThread->enmState == PDMTHREADSTATE_INITIALIZING)
328 return VINF_SUCCESS;
329
330 while (pTestFile->fRunning)
331 {
332 unsigned iTaskCurr = 0;
333
334
335 /* Fill all tasks */
336 while ( (pTestFile->cTasksActiveCurr < pTestFile->cTasksActiveMax)
337 && (iTaskCurr < pTestFile->cTasksActiveMax))
338 {
339 PPDMACTESTFILETASK pTask = &pTestFile->paTasks[iTaskCurr];
340
341 if (!pTask->fActive)
342 {
343 /* Read or write task? */
344 bool fWrite = tstPDMACTestIsTrue(iWriteChance);
345
346 ASMAtomicIncU32(&pTestFile->cTasksActiveCurr);
347
348 if (fWrite)
349 rc = tstPDMACStressTestFileWrite(pTestFile, pTask);
350 else
351 rc = tstPDMACStressTestFileRead(pTestFile, pTask);
352
353 AssertRC(rc);
354
355 if (rc != VINF_AIO_TASK_PENDING)
356 tstPDMACStressTestFileTaskCompleted(pVM, pTask, pTestFile);
357
358 cTasksStarted++;
359 }
360
361 iTaskCurr++;
362 }
363
364 /*
365 * Recalc write chance. The bigger the file the lower the chance to have a write.
366 * The minimum chance is 33 percent.
367 */
368 iWriteChance = 100 - (int)(((float)100.0 / pTestFile->cbFileMax) * (float)pTestFile->cbFileCurr);
369 iWriteChance = RT_MAX(33, iWriteChance);
370
371 /* Wait a random amount of time. (1ms - 100ms) */
372 RTThreadSleep(RTRandU32Ex(1, 100));
373 }
374
375 /* Wait for the rest to complete. */
376 while (pTestFile->cTasksActiveCurr)
377 RTThreadSleep(250);
378
379 RTPrintf("Thread exiting: processed %u tasks\n", cTasksStarted);
380 return rc;
381}
382
383static void tstPDMACStressTestFileTaskCompleted(PVM pVM, void *pvUser, void *pvUser2)
384{
385 PPDMACTESTFILE pTestFile = (PPDMACTESTFILE)pvUser2;
386 PPDMACTESTFILETASK pTestTask = (PPDMACTESTFILETASK)pvUser;
387
388 if (pTestTask->fWrite)
389 {
390 /* @todo Do something sensible here. */
391 }
392 else
393 {
394 tstPDMACStressTestFileVerify(pTestFile, pTestTask); /* Will assert if it fails */
395 }
396
397 RTMemFree(pTestTask->DataSeg.pvSeg);
398 pTestTask->fActive = false;
399 AssertMsg(pTestFile->cTasksActiveCurr > 0, ("Trying to complete a non active task\n"));
400 ASMAtomicDecU32(&pTestFile->cTasksActiveCurr);
401}
402
403/**
404 * Sets up a test file creating the I/O thread.
405 *
406 * @returns VBox status code.
407 * @param pVM Pointer to the shared VM instance structure.
408 * @param pTestFile Pointer to the uninitialized test file structure.
409 * @param iTestId Unique test id.
410 */
411static int tstPDMACStressTestFileOpen(PVM pVM, PPDMACTESTFILE pTestFile, unsigned iTestId)
412{
413 int rc = VERR_NO_MEMORY;
414
415 /* Size is a multiple of 512 */
416 pTestFile->cbFileMax = RTRandU64Ex(FILE_SIZE_MIN, FILE_SIZE_MAX) & ~(511UL);
417 pTestFile->cbFileCurr = 0;
418 pTestFile->cbFileSegment = RTRandU32Ex(SEGMENT_SIZE_MIN, RT_MIN(pTestFile->cbFileMax, SEGMENT_SIZE_MAX)) & ~((size_t)511);
419
420 Assert(pTestFile->cbFileMax >= pTestFile->cbFileSegment);
421
422 /* Set up the segments array. */
423 pTestFile->cSegments = pTestFile->cbFileMax / pTestFile->cbFileSegment;
424 pTestFile->cSegments += ((pTestFile->cbFileMax % pTestFile->cbFileSegment) > 0) ? 1 : 0;
425
426 pTestFile->paSegs = (PPDMACTESTFILESEG)RTMemAllocZ(pTestFile->cSegments * sizeof(PDMACTESTFILESEG));
427 if (pTestFile->paSegs)
428 {
429 /* Init the segments */
430 for (unsigned i = 0; i < pTestFile->cSegments; i++)
431 {
432 PPDMACTESTFILESEG pSeg = &pTestFile->paSegs[i];
433
434 pSeg->off = (RTFOFF)i * pTestFile->cbFileSegment;
435 pSeg->cbSegment = pTestFile->cbFileSegment;
436
437 /* Let the buffer point to a random position in the test pattern. */
438 uint32_t offTestPattern = RTRandU64Ex(0, g_cbTestPattern - pSeg->cbSegment);
439
440 pSeg->pbData = g_pbTestPattern + offTestPattern;
441 }
442
443 /* Init task array. */
444 pTestFile->cTasksActiveMax = RTRandU32Ex(1, TASK_ACTIVE_MAX);
445 pTestFile->paTasks = (PPDMACTESTFILETASK)RTMemAllocZ(pTestFile->cTasksActiveMax * sizeof(PDMACTESTFILETASK));
446 if (pTestFile->paTasks)
447 {
448 /* Create the template */
449 char szDesc[256];
450
451 RTStrPrintf(szDesc, sizeof(szDesc), "Template-%d", iTestId);
452 rc = PDMR3AsyncCompletionTemplateCreateInternal(pVM, &pTestFile->pTemplate, tstPDMACStressTestFileTaskCompleted, pTestFile, szDesc);
453 if (RT_SUCCESS(rc))
454 {
455 /* Open the endpoint now. Because async completion endpoints cannot create files we have to do it before. */
456 char szFile[RTPATH_MAX];
457
458 RTStrPrintf(szFile, sizeof(szFile), "tstPDMAsyncCompletionStress-%d.tmp", iTestId);
459
460 RTFILE FileTmp;
461 rc = RTFileOpen(&FileTmp, szFile, RTFILE_O_READWRITE | RTFILE_O_CREATE | RTFILE_O_DENY_NONE);
462 if (RT_SUCCESS(rc))
463 {
464 RTFileClose(FileTmp);
465
466 rc = PDMR3AsyncCompletionEpCreateForFile(&pTestFile->hEndpoint, szFile, PDMACEP_FILE_FLAGS_CACHING, pTestFile->pTemplate);
467 if (RT_SUCCESS(rc))
468 {
469 char szThreadDesc[256];
470
471 pTestFile->fRunning = true;
472
473 /* Create the thread creating the I/O for the given file. */
474 RTStrPrintf(szThreadDesc, sizeof(szThreadDesc), "PDMACThread-%d", iTestId);
475 rc = PDMR3ThreadCreate(pVM, &pTestFile->hThread, pTestFile, tstPDMACTestFileThread,
476 NULL, 0, RTTHREADTYPE_IO, szThreadDesc);
477 if (RT_SUCCESS(rc))
478 {
479 rc = PDMR3ThreadResume(pTestFile->hThread);
480 AssertRC(rc);
481
482 RTPrintf(TESTCASE ": Created test file %s cbFileMax=%llu cbFileSegment=%u cSegments=%u cTasksActiveMax=%u\n",
483 szFile, pTestFile->cbFileMax, pTestFile->cbFileSegment, pTestFile->cSegments, pTestFile->cTasksActiveMax);
484 return VINF_SUCCESS;
485 }
486
487 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
488 }
489
490 RTFileDelete(szFile);
491 }
492
493 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
494 }
495
496 RTMemFree(pTestFile->paTasks);
497 }
498 else
499 rc = VERR_NO_MEMORY;
500
501 RTMemFree(pTestFile->paSegs);
502 }
503 else
504 rc = VERR_NO_MEMORY;
505
506 RTPrintf(TESTCASE ": Opening test file with id %d failed rc=%Rrc\n", iTestId, rc);
507
508 return rc;
509}
510
511/**
512 * Closes a test file.
513 *
514 * @returns nothing.
515 * @param pTestFile Pointer to the test file.
516 */
517static void tstPDMACStressTestFileClose(PPDMACTESTFILE pTestFile)
518{
519 int rcThread;
520 int rc;
521
522 RTPrintf("Terminating I/O thread, please wait...\n");
523
524 /* Let the thread know that it should terminate. */
525 pTestFile->fRunning = false;
526
527 /* Wait for the thread to terminate. */
528 rc = PDMR3ThreadDestroy(pTestFile->hThread, &rcThread);
529
530 RTPrintf("Thread terminated with status code rc=%Rrc\n", rcThread);
531
532 /* Free resources */
533 RTMemFree(pTestFile->paTasks);
534 RTMemFree(pTestFile->paSegs);
535 PDMR3AsyncCompletionEpClose(pTestFile->hEndpoint);
536 PDMR3AsyncCompletionTemplateDestroy(pTestFile->pTemplate);
537}
538
539/**
540 * Inits the test pattern.
541 *
542 * @returns VBox status code.
543 */
544static int tstPDMACStressTestPatternInit(void)
545{
546 RTPrintf(TESTCASE ": Creating test pattern. Please wait...\n");
547 g_cbTestPattern = TEST_PATTERN_SIZE;
548 g_pbTestPattern = (uint8_t *)RTMemAlloc(g_cbTestPattern);
549 if (!g_pbTestPattern)
550 return VERR_NO_MEMORY;
551
552 RTRandBytes(g_pbTestPattern, g_cbTestPattern);
553 return VINF_SUCCESS;
554}
555
556static void tstPDMACStressTestPatternDestroy(void)
557{
558 RTPrintf(TESTCASE ": Destroying test pattern\n");
559 RTMemFree(g_pbTestPattern);
560}
561
562int main(int argc, char *argv[])
563{
564 int rcRet = 0; /* error count */
565 int rc = VINF_SUCCESS;
566
567 RTR3InitAndSUPLib();
568
569 PVM pVM;
570 rc = VMR3Create(1, NULL, NULL, NULL, NULL, &pVM);
571 if (RT_SUCCESS(rc))
572 {
573 /*
574 * Little hack to avoid the VM_ASSERT_EMT assertion.
575 */
576 RTTlsSet(pVM->pUVM->vm.s.idxTLS, &pVM->pUVM->aCpus[0]);
577 pVM->pUVM->aCpus[0].pUVM = pVM->pUVM;
578 pVM->pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
579
580 rc = tstPDMACStressTestPatternInit();
581 if (RT_SUCCESS(rc))
582 {
583 unsigned cFilesOpened = 0;
584
585 /* Open the endpoints. */
586 for (cFilesOpened = 0; cFilesOpened < NR_OPEN_ENDPOINTS; cFilesOpened++)
587 {
588 rc = tstPDMACStressTestFileOpen(pVM, &g_aTestFiles[cFilesOpened], cFilesOpened);
589 if (RT_FAILURE(rc))
590 break;
591 }
592
593 if (RT_SUCCESS(rc))
594 {
595 /* Tests are running now. */
596 RTPrintf(TESTCASE ": Successfully opened all files. Running tests forever now or until an error is hit :)\n");
597 RTThreadSleep(RT_INDEFINITE_WAIT);
598 }
599
600 /* Close opened endpoints. */
601 for (unsigned i = 0; i < cFilesOpened; i++)
602 tstPDMACStressTestFileClose(&g_aTestFiles[i]);
603
604 tstPDMACStressTestPatternDestroy();
605 }
606 else
607 {
608 RTPrintf(TESTCASE ": failed to init test pattern!! rc=%Rrc\n", rc);
609 rcRet++;
610 }
611
612 rc = VMR3Destroy(pVM);
613 AssertMsg(rc == VINF_SUCCESS, ("%s: Destroying VM failed rc=%Rrc!!\n", __FUNCTION__, rc));
614 }
615 else
616 {
617 RTPrintf(TESTCASE ": failed to create VM!! rc=%Rrc\n", rc);
618 rcRet++;
619 }
620
621 return rcRet;
622}
623
Note: See TracBrowser for help on using the repository browser.

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