VirtualBox

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

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

VMReq,*: Replaced VMREQDEST with VMCPUID because it's a pain to have to cast CPU IDs all the time.

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