VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstVMREQ.cpp@ 14806

Last change on this file since 14806 was 13818, checked in by vboxsync, 16 years ago

VMM: %Vrc -> %Rrc, %Vra -> %Rra.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 8.9 KB
Line 
1/* $Id: tstVMREQ.cpp 13818 2008-11-04 22:59:47Z vboxsync $ */
2/** @file
3 * VMM Testcase.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#include <VBox/vm.h>
27#include <VBox/vmm.h>
28#include <VBox/cpum.h>
29#include <VBox/err.h>
30#include <VBox/log.h>
31#include <iprt/assert.h>
32#include <iprt/runtime.h>
33#include <iprt/semaphore.h>
34#include <iprt/stream.h>
35#include <iprt/thread.h>
36#include <iprt/time.h>
37
38
39/*******************************************************************************
40* Defined Constants And Macros *
41*******************************************************************************/
42#define TESTCASE "tstVMREQ"
43
44/*******************************************************************************
45* Global Variables *
46*******************************************************************************/
47/** the error count. */
48static int g_cErrors = 0;
49
50
51/**
52 * Testings va_list passing in VMSetRuntimeError.
53 */
54static DECLCALLBACK(void) MyAtRuntimeError(PVM pVM, void *pvUser, bool fFatal, const char *pszErrorId, const char *pszFormat, va_list va)
55{
56 if (strcmp((const char *)pvUser, "user argument"))
57 {
58 RTPrintf(TESTCASE ": pvUser=%p:{%s}!\n", pvUser, (const char *)pvUser);
59 g_cErrors++;
60 }
61 if (fFatal)
62 {
63 RTPrintf(TESTCASE ": fFatal=%d!\n", fFatal);
64 g_cErrors++;
65 }
66 if (strcmp(pszErrorId, "enum"))
67 {
68 RTPrintf(TESTCASE ": pszErrorId=%p:{%s}!\n", pszErrorId, pszErrorId);
69 g_cErrors++;
70 }
71 if (strcmp(pszFormat, "some %s string"))
72 {
73 RTPrintf(TESTCASE ": pszFormat=%p:{%s}!\n", pszFormat, pszFormat);
74 g_cErrors++;
75 }
76
77 char szBuf[1024];
78 RTStrPrintfV(szBuf, sizeof(szBuf), pszFormat, va);
79 if (strcmp(szBuf, "some error string"))
80 {
81 RTPrintf(TESTCASE ": RTStrPrintfV -> '%s'!\n", szBuf);
82 g_cErrors++;
83 }
84}
85
86
87/**
88 * The function PassVA and PassVA2 calls.
89 */
90static DECLCALLBACK(int) PassVACallback(PVM pVM, unsigned u4K, unsigned u1G, const char *pszFormat, va_list *pva)
91{
92 if (u4K != _4K)
93 {
94 RTPrintf(TESTCASE ": u4K=%#x!\n", u4K);
95 g_cErrors++;
96 }
97 if (u1G != _1G)
98 {
99 RTPrintf(TESTCASE ": u1G=%#x!\n", u1G);
100 g_cErrors++;
101 }
102
103 if (strcmp(pszFormat, "hello %s"))
104 {
105 RTPrintf(TESTCASE ": pszFormat=%p:{%s}!\n", pszFormat, pszFormat);
106 g_cErrors++;
107 }
108
109 char szBuf[1024];
110 RTStrPrintfV(szBuf, sizeof(szBuf), pszFormat, *pva);
111 if (strcmp(szBuf, "hello world"))
112 {
113 RTPrintf(TESTCASE ": RTStrPrintfV -> '%s'!\n", szBuf);
114 g_cErrors++;
115 }
116
117 return VINF_SUCCESS;
118}
119
120
121/**
122 * Functions that tests passing a va_list * argument in a request,
123 * similar to VMSetRuntimeError.
124 */
125static void PassVA2(PVM pVM, const char *pszFormat, va_list va)
126{
127#if 0 /** @todo test if this is a GCC problem only or also happens with AMD64+VCC80... */
128 void *pvVA = &va;
129#else
130 va_list va2;
131 va_copy(va2, va);
132 void *pvVA = va2;
133#endif
134
135 PVMREQ pReq;
136 int rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PassVACallback, 5,
137 pVM, _4K, _1G, pszFormat, pvVA);
138 if (RT_SUCCESS(rc))
139 rc = pReq->iStatus;
140 VMR3ReqFree(pReq);
141
142#if 1
143 va_end(va2);
144#endif
145}
146
147
148/**
149 * Functions that tests passing a va_list * argument in a request,
150 * similar to VMSetRuntimeError.
151 */
152static void PassVA(PVM pVM, const char *pszFormat, ...)
153{
154 /* 1st test */
155 va_list va1;
156 va_start(va1, pszFormat);
157 PVMREQ pReq;
158 int rc = VMR3ReqCall(pVM, VMREQDEST_ANY, &pReq, RT_INDEFINITE_WAIT, (PFNRT)PassVACallback, 5,
159 pVM, _4K, _1G, pszFormat, &va1);
160 if (RT_SUCCESS(rc))
161 rc = pReq->iStatus;
162 VMR3ReqFree(pReq);
163 va_end(va1);
164
165 /* 2nd test */
166 va_list va2;
167 va_start(va2, pszFormat);
168 PassVA2(pVM, pszFormat, va2);
169 va_end(va2);
170}
171
172
173/**
174 * Thread function which allocates and frees requests like wildfire.
175 */
176static DECLCALLBACK(int) Thread(RTTHREAD Thread, void *pvUser)
177{
178 int rc = VINF_SUCCESS;
179 PVM pVM = (PVM)pvUser;
180 for (unsigned i = 0; i < 100000; i++)
181 {
182 PVMREQ apReq[17];
183 const unsigned cReqs = i % RT_ELEMENTS(apReq);
184 unsigned iReq;
185 for (iReq = 0; iReq < cReqs; iReq++)
186 {
187 rc = VMR3ReqAlloc(pVM, &apReq[iReq], VMREQTYPE_INTERNAL, VMREQDEST_ANY);
188 if (RT_FAILURE(rc))
189 {
190 RTPrintf(TESTCASE ": i=%d iReq=%d cReqs=%d rc=%Rrc (alloc)\n", i, iReq, cReqs, rc);
191 return rc;
192 }
193 apReq[iReq]->iStatus = iReq + i;
194 }
195
196 for (iReq = 0; iReq < cReqs; iReq++)
197 {
198 if (apReq[iReq]->iStatus != (int)(iReq + i))
199 {
200 RTPrintf(TESTCASE ": i=%d iReq=%d cReqs=%d: iStatus=%d != %d\n", i, iReq, cReqs, apReq[iReq]->iStatus, iReq + i);
201 return VERR_GENERAL_FAILURE;
202 }
203 rc = VMR3ReqFree(apReq[iReq]);
204 if (RT_FAILURE(rc))
205 {
206 RTPrintf(TESTCASE ": i=%d iReq=%d cReqs=%d rc=%Rrc (free)\n", i, iReq, cReqs, rc);
207 return rc;
208 }
209 }
210 //if (!(i % 10000))
211 // RTPrintf(TESTCASE ": i=%d\n", i);
212 }
213
214 return VINF_SUCCESS;
215}
216
217
218
219int main(int argc, char **argv)
220{
221 RTR3InitAndSUPLib();
222 RTPrintf(TESTCASE ": TESTING...\n");
223
224 /*
225 * Create empty VM.
226 */
227 PVM pVM;
228 int rc = VMR3Create(1, NULL, NULL, NULL, NULL, &pVM);
229 if (RT_SUCCESS(rc))
230 {
231 /*
232 * Do testing.
233 */
234 uint64_t u64StartTS = RTTimeNanoTS();
235 RTTHREAD Thread0;
236 rc = RTThreadCreate(&Thread0, Thread, pVM, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "REQ1");
237 if (RT_SUCCESS(rc))
238 {
239 RTTHREAD Thread1;
240 rc = RTThreadCreate(&Thread1, Thread, pVM, 0, RTTHREADTYPE_DEFAULT, RTTHREADFLAGS_WAITABLE, "REQ1");
241 if (RT_SUCCESS(rc))
242 {
243 int rcThread1;
244 rc = RTThreadWait(Thread1, RT_INDEFINITE_WAIT, &rcThread1);
245 if (RT_FAILURE(rc))
246 {
247 RTPrintf(TESTCASE ": RTThreadWait(Thread1,,) failed, rc=%Rrc\n", rc);
248 g_cErrors++;
249 }
250 if (RT_FAILURE(rcThread1))
251 g_cErrors++;
252 }
253 else
254 {
255 RTPrintf(TESTCASE ": RTThreadCreate(&Thread1,,,,) failed, rc=%Rrc\n", rc);
256 g_cErrors++;
257 }
258
259 int rcThread0;
260 rc = RTThreadWait(Thread0, RT_INDEFINITE_WAIT, &rcThread0);
261 if (RT_FAILURE(rc))
262 {
263 RTPrintf(TESTCASE ": RTThreadWait(Thread1,,) failed, rc=%Rrc\n", rc);
264 g_cErrors++;
265 }
266 if (RT_FAILURE(rcThread0))
267 g_cErrors++;
268 }
269 else
270 {
271 RTPrintf(TESTCASE ": RTThreadCreate(&Thread0,,,,) failed, rc=%Rrc\n", rc);
272 g_cErrors++;
273 }
274 uint64_t u64ElapsedTS = RTTimeNanoTS() - u64StartTS;
275 RTPrintf(TESTCASE ": %llu ns elapsed\n", u64ElapsedTS);
276
277 /*
278 * Print stats.
279 */
280 STAMR3Print(pVM, "/VM/Req/*");
281
282 /*
283 * Testing va_list fun.
284 */
285 RTPrintf(TESTCASE ": va_list argument test...\n");
286 PassVA(pVM, "hello %s", "world");
287 VMR3AtRuntimeErrorRegister(pVM, MyAtRuntimeError, (void *)"user argument");
288 VMSetRuntimeError(pVM, false, "enum", "some %s string", "error");
289
290 /*
291 * Cleanup.
292 */
293 rc = VMR3Destroy(pVM);
294 if (!RT_SUCCESS(rc))
295 {
296 RTPrintf(TESTCASE ": error: failed to destroy vm! rc=%Rrc\n", rc);
297 g_cErrors++;
298 }
299 }
300 else
301 {
302 RTPrintf(TESTCASE ": fatal error: failed to create vm! rc=%Rrc\n", rc);
303 g_cErrors++;
304 }
305
306 /*
307 * Summary and return.
308 */
309 if (!g_cErrors)
310 RTPrintf(TESTCASE ": SUCCESS\n");
311 else
312 RTPrintf(TESTCASE ": FAILURE - %d errors\n", g_cErrors);
313
314 return !!g_cErrors;
315}
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