VirtualBox

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

Last change on this file since 26944 was 26338, checked in by vboxsync, 15 years ago

AsyncCompletion: Introduce range locks to prevent concurrent access to the same file range. Fixes inconsistent data for tasks with unaligned tasks where we have to use bounce buffers (i.e block table updates when a VDI file grows)

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