VirtualBox

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

Last change on this file since 93308 was 93308, checked in by vboxsync, 3 years ago

VMM: VC++ 19.2 update 11 build adjustments (lossy floating point conversions). bugref:8489

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