VirtualBox

source: vbox/trunk/src/VBox/VMM/testcase/tstSSM.cpp@ 41294

Last change on this file since 41294 was 39078, checked in by vboxsync, 13 years ago

VMM: -Wunused-parameter

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 25.3 KB
Line 
1/* $Id: tstSSM.cpp 39078 2011-10-21 14:18:22Z vboxsync $ */
2/** @file
3 * Saved State Manager Testcase.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Oracle Corporation
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
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#include <VBox/vmm/ssm.h>
23#include "VMInternal.h" /* createFakeVM */
24#include <VBox/vmm/vm.h>
25#include <VBox/vmm/uvm.h>
26#include <VBox/vmm/mm.h>
27#include <VBox/vmm/stam.h>
28
29#include <VBox/log.h>
30#include <VBox/sup.h>
31#include <VBox/err.h>
32#include <VBox/param.h>
33#include <iprt/assert.h>
34#include <iprt/initterm.h>
35#include <iprt/mem.h>
36#include <iprt/stream.h>
37#include <iprt/string.h>
38#include <iprt/time.h>
39#include <iprt/thread.h>
40#include <iprt/path.h>
41
42
43/*******************************************************************************
44* Defined Constants And Macros *
45*******************************************************************************/
46#define TSTSSM_BIG_CONFIG 1
47
48#ifdef TSTSSM_BIG_CONFIG
49# define TSTSSM_ITEM_SIZE (512*_1M)
50#else
51# define TSTSSM_ITEM_SIZE (5*_1M)
52#endif
53
54
55/*******************************************************************************
56* Global Variables *
57*******************************************************************************/
58const uint8_t gabPage[PAGE_SIZE] = {0};
59const char gachMem1[] = "sdfg\1asdfa\177hjkl;sdfghjkl;dfghjkl;dfghjkl;\0\0asdf;kjasdf;lkjasd;flkjasd;lfkjasd\0;lfk";
60#ifdef TSTSSM_BIG_CONFIG
61uint8_t gabBigMem[_1M];
62#else
63uint8_t gabBigMem[8*_1M];
64#endif
65
66
67/** initializes gabBigMem with some non zero stuff. */
68void initBigMem(void)
69{
70#if 0
71 uint32_t *puch = (uint32_t *)&gabBigMem[0];
72 uint32_t *puchEnd = (uint32_t *)&gabBigMem[sizeof(gabBigMem)];
73 uint32_t u32 = 0xdeadbeef;
74 for (; puch < puchEnd; puch++)
75 {
76 *puch = u32;
77 u32 += 19;
78 u32 = (u32 << 1) | (u32 >> 31);
79 }
80#else
81 uint8_t *pb = &gabBigMem[0];
82 uint8_t *pbEnd = &gabBigMem[sizeof(gabBigMem)];
83 for (; pb < pbEnd; pb += 16)
84 {
85 char szTmp[17];
86 RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb);
87 memcpy(pb, szTmp, 16);
88 }
89
90 /* add some zero pages */
91 memset(&gabBigMem[sizeof(gabBigMem) / 4], 0, PAGE_SIZE * 4);
92 memset(&gabBigMem[sizeof(gabBigMem) / 4 * 3], 0, PAGE_SIZE * 4);
93#endif
94}
95
96/**
97 * Execute state save operation.
98 *
99 * @returns VBox status code.
100 * @param pDevIns Device instance of the device which registered the data unit.
101 * @param pSSM SSM operation handle.
102 */
103DECLCALLBACK(int) Item01Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
104{
105 uint64_t u64Start = RTTimeNanoTS();
106 NOREF(pDevIns);
107
108 /*
109 * Test writing some memory block.
110 */
111 int rc = SSMR3PutMem(pSSM, gachMem1, sizeof(gachMem1));
112 if (RT_FAILURE(rc))
113 {
114 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
115 return rc;
116 }
117
118 /*
119 * Test writing a zeroterminated string.
120 */
121 rc = SSMR3PutStrZ(pSSM, "String");
122 if (RT_FAILURE(rc))
123 {
124 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
125 return rc;
126 }
127
128
129 /*
130 * Test the individual integer put functions to see that they all work.
131 * (Testcases are also known as "The Land of The Ugly Code"...)
132 */
133#define ITEM(suff,bits, val) \
134 rc = SSMR3Put##suff(pSSM, val); \
135 if (RT_FAILURE(rc)) \
136 { \
137 RTPrintf("Item01: #" #suff " - SSMR3Put" #suff "(," #val ") -> %Rrc\n", rc); \
138 return rc; \
139 }
140 /* copy & past with the load one! */
141 ITEM(U8, uint8_t, 0xff);
142 ITEM(U8, uint8_t, 0x0);
143 ITEM(U8, uint8_t, 1);
144 ITEM(U8, uint8_t, 42);
145 ITEM(U8, uint8_t, 230);
146 ITEM(S8, int8_t, -128);
147 ITEM(S8, int8_t, 127);
148 ITEM(S8, int8_t, 12);
149 ITEM(S8, int8_t, -76);
150 ITEM(U16, uint16_t, 0xffff);
151 ITEM(U16, uint16_t, 0x0);
152 ITEM(S16, int16_t, 32767);
153 ITEM(S16, int16_t, -32768);
154 ITEM(U32, uint32_t, 4294967295U);
155 ITEM(U32, uint32_t, 0);
156 ITEM(U32, uint32_t, 42);
157 ITEM(U32, uint32_t, 2342342344U);
158 ITEM(S32, int32_t, -2147483647-1);
159 ITEM(S32, int32_t, 2147483647);
160 ITEM(S32, int32_t, 42);
161 ITEM(S32, int32_t, 568459834);
162 ITEM(S32, int32_t, -58758999);
163 ITEM(U64, uint64_t, 18446744073709551615ULL);
164 ITEM(U64, uint64_t, 0);
165 ITEM(U64, uint64_t, 42);
166 ITEM(U64, uint64_t, 593023944758394234ULL);
167 ITEM(S64, int64_t, 9223372036854775807LL);
168 ITEM(S64, int64_t, -9223372036854775807LL - 1);
169 ITEM(S64, int64_t, 42);
170 ITEM(S64, int64_t, 21398723459873LL);
171 ITEM(S64, int64_t, -5848594593453453245LL);
172#undef ITEM
173
174 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
175 RTPrintf("tstSSM: Saved 1st item in %'RI64 ns\n", u64Elapsed);
176 return 0;
177}
178
179/**
180 * Prepare state load operation.
181 *
182 * @returns VBox status code.
183 * @param pDevIns Device instance of the device which registered the data unit.
184 * @param pSSM SSM operation handle.
185 * @param uVersion The data layout version.
186 * @param uPass The data pass.
187 */
188DECLCALLBACK(int) Item01Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
189{
190 NOREF(pDevIns); NOREF(uPass);
191 if (uVersion != 0)
192 {
193 RTPrintf("Item01: uVersion=%#x, expected 0\n", uVersion);
194 return VERR_GENERAL_FAILURE;
195 }
196
197 /*
198 * Load the memory block.
199 */
200 char achTmp[sizeof(gachMem1)];
201 int rc = SSMR3GetMem(pSSM, achTmp, sizeof(gachMem1));
202 if (RT_FAILURE(rc))
203 {
204 RTPrintf("Item01: #1 - SSMR3GetMem -> %Rrc\n", rc);
205 return rc;
206 }
207
208 /*
209 * Load the string.
210 */
211 rc = SSMR3GetStrZ(pSSM, achTmp, sizeof(achTmp));
212 if (RT_FAILURE(rc))
213 {
214 RTPrintf("Item01: #2 - SSMR3GetStrZ -> %Rrc\n", rc);
215 return rc;
216 }
217
218 /*
219 * Test the individual integer put functions to see that they all work.
220 * (Testcases are also known as "The Land of The Ugly Code"...)
221 */
222#define ITEM(suff, type, val) \
223 do { \
224 type var = {0}; \
225 rc = SSMR3Get##suff(pSSM, &var); \
226 if (RT_FAILURE(rc)) \
227 { \
228 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %Rrc\n", rc); \
229 return rc; \
230 } \
231 if (var != val) \
232 { \
233 RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %d returned wrong value!\n", rc); \
234 return VERR_GENERAL_FAILURE; \
235 } \
236 } while (0)
237 /* copy & past with the load one! */
238 ITEM(U8, uint8_t, 0xff);
239 ITEM(U8, uint8_t, 0x0);
240 ITEM(U8, uint8_t, 1);
241 ITEM(U8, uint8_t, 42);
242 ITEM(U8, uint8_t, 230);
243 ITEM(S8, int8_t, -128);
244 ITEM(S8, int8_t, 127);
245 ITEM(S8, int8_t, 12);
246 ITEM(S8, int8_t, -76);
247 ITEM(U16, uint16_t, 0xffff);
248 ITEM(U16, uint16_t, 0x0);
249 ITEM(S16, int16_t, 32767);
250 ITEM(S16, int16_t, -32768);
251 ITEM(U32, uint32_t, 4294967295U);
252 ITEM(U32, uint32_t, 0);
253 ITEM(U32, uint32_t, 42);
254 ITEM(U32, uint32_t, 2342342344U);
255 ITEM(S32, int32_t, -2147483647-1);
256 ITEM(S32, int32_t, 2147483647);
257 ITEM(S32, int32_t, 42);
258 ITEM(S32, int32_t, 568459834);
259 ITEM(S32, int32_t, -58758999);
260 ITEM(U64, uint64_t, 18446744073709551615ULL);
261 ITEM(U64, uint64_t, 0);
262 ITEM(U64, uint64_t, 42);
263 ITEM(U64, uint64_t, 593023944758394234ULL);
264 ITEM(S64, int64_t, 9223372036854775807LL);
265 ITEM(S64, int64_t, -9223372036854775807LL - 1);
266 ITEM(S64, int64_t, 42);
267 ITEM(S64, int64_t, 21398723459873LL);
268 ITEM(S64, int64_t, -5848594593453453245LL);
269#undef ITEM
270
271 return 0;
272}
273
274
275/**
276 * Execute state save operation.
277 *
278 * @returns VBox status code.
279 * @param pDevIns Device instance of the device which registered the data unit.
280 * @param pSSM SSM operation handle.
281 */
282DECLCALLBACK(int) Item02Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
283{
284 NOREF(pDevIns);
285 uint64_t u64Start = RTTimeNanoTS();
286
287 /*
288 * Put the size.
289 */
290 uint32_t cb = sizeof(gabBigMem);
291 int rc = SSMR3PutU32(pSSM, cb);
292 if (RT_FAILURE(rc))
293 {
294 RTPrintf("Item02: PutU32 -> %Rrc\n", rc);
295 return rc;
296 }
297
298 /*
299 * Put 8MB of memory to the file in 3 chunks.
300 */
301 uint8_t *pbMem = &gabBigMem[0];
302 uint32_t cbChunk = cb / 47;
303 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
304 if (RT_FAILURE(rc))
305 {
306 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
307 return rc;
308 }
309 cb -= cbChunk;
310 pbMem += cbChunk;
311
312 /* next piece. */
313 cbChunk *= 19;
314 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
315 if (RT_FAILURE(rc))
316 {
317 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
318 return rc;
319 }
320 cb -= cbChunk;
321 pbMem += cbChunk;
322
323 /* last piece. */
324 cbChunk = cb;
325 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
326 if (RT_FAILURE(rc))
327 {
328 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
329 return rc;
330 }
331
332 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
333 RTPrintf("tstSSM: Saved 2nd item in %'RI64 ns\n", u64Elapsed);
334 return 0;
335}
336
337/**
338 * Prepare state load operation.
339 *
340 * @returns VBox status code.
341 * @param pDevIns Device instance of the device which registered the data unit.
342 * @param pSSM SSM operation handle.
343 * @param uVersion The data layout version.
344 * @param uPass The data pass.
345 */
346DECLCALLBACK(int) Item02Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
347{
348 NOREF(pDevIns); NOREF(uPass);
349 if (uVersion != 0)
350 {
351 RTPrintf("Item02: uVersion=%#x, expected 0\n", uVersion);
352 return VERR_GENERAL_FAILURE;
353 }
354
355 /*
356 * Load the size.
357 */
358 uint32_t cb;
359 int rc = SSMR3GetU32(pSSM, &cb);
360 if (RT_FAILURE(rc))
361 {
362 RTPrintf("Item02: SSMR3GetU32 -> %Rrc\n", rc);
363 return rc;
364 }
365 if (cb != sizeof(gabBigMem))
366 {
367 RTPrintf("Item02: loaded size doesn't match the real thing. %#x != %#x\n", cb, sizeof(gabBigMem));
368 return VERR_GENERAL_FAILURE;
369 }
370
371 /*
372 * Load the memory chunk by chunk.
373 */
374 uint8_t *pbMem = &gabBigMem[0];
375 char achTmp[16383];
376 uint32_t cbChunk = sizeof(achTmp);
377 while (cb > 0)
378 {
379 cbChunk -= 7;
380 if (cbChunk < 64)
381 cbChunk = sizeof(achTmp) - (cbChunk % 47);
382 if (cbChunk > cb)
383 cbChunk = cb;
384 rc = SSMR3GetMem(pSSM, &achTmp[0], cbChunk);
385 if (RT_FAILURE(rc))
386 {
387 RTPrintf("Item02: SSMR3GetMem(,,%#x) -> %d offset %#x\n", cbChunk, rc, pbMem - &gabBigMem[0]);
388 return rc;
389 }
390 if (memcmp(achTmp, pbMem, cbChunk))
391 {
392 RTPrintf("Item02: compare failed. mem offset=%#x cbChunk=%#x\n", pbMem - &gabBigMem[0], cbChunk);
393 return VERR_GENERAL_FAILURE;
394 }
395
396 /* next */
397 pbMem += cbChunk;
398 cb -= cbChunk;
399 }
400
401 return 0;
402}
403
404
405/**
406 * Execute state save operation.
407 *
408 * @returns VBox status code.
409 * @param pDevIns Device instance of the device which registered the data unit.
410 * @param pSSM SSM operation handle.
411 */
412DECLCALLBACK(int) Item03Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
413{
414 NOREF(pDevIns);
415 uint64_t u64Start = RTTimeNanoTS();
416
417 /*
418 * Put the size.
419 */
420 uint32_t cb = TSTSSM_ITEM_SIZE;
421 int rc = SSMR3PutU32(pSSM, cb);
422 if (RT_FAILURE(rc))
423 {
424 RTPrintf("Item03: PutU32 -> %Rrc\n", rc);
425 return rc;
426 }
427
428 /*
429 * Put 512 MB page by page.
430 */
431 const uint8_t *pu8Org = &gabBigMem[0];
432 while (cb > 0)
433 {
434 rc = SSMR3PutMem(pSSM, pu8Org, PAGE_SIZE);
435 if (RT_FAILURE(rc))
436 {
437 RTPrintf("Item03: PutMem(,%p,%#x) -> %Rrc\n", pu8Org, PAGE_SIZE, rc);
438 return rc;
439 }
440
441 /* next */
442 cb -= PAGE_SIZE;
443 pu8Org += PAGE_SIZE;
444 if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
445 pu8Org = &gabBigMem[0];
446 }
447
448 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
449 RTPrintf("tstSSM: Saved 3rd item in %'RI64 ns\n", u64Elapsed);
450 return 0;
451}
452
453/**
454 * Prepare state load operation.
455 *
456 * @returns VBox status code.
457 * @param pDevIns Device instance of the device which registered the data unit.
458 * @param pSSM SSM operation handle.
459 * @param uVersion The data layout version.
460 * @param uPass The data pass.
461 */
462DECLCALLBACK(int) Item03Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
463{
464 NOREF(pDevIns); NOREF(uPass);
465 if (uVersion != 123)
466 {
467 RTPrintf("Item03: uVersion=%#x, expected 123\n", uVersion);
468 return VERR_GENERAL_FAILURE;
469 }
470
471 /*
472 * Load the size.
473 */
474 uint32_t cb;
475 int rc = SSMR3GetU32(pSSM, &cb);
476 if (RT_FAILURE(rc))
477 {
478 RTPrintf("Item03: SSMR3GetU32 -> %Rrc\n", rc);
479 return rc;
480 }
481 if (cb != TSTSSM_ITEM_SIZE)
482 {
483 RTPrintf("Item03: loaded size doesn't match the real thing. %#x != %#x\n", cb, TSTSSM_ITEM_SIZE);
484 return VERR_GENERAL_FAILURE;
485 }
486
487 /*
488 * Load the memory page by page.
489 */
490 const uint8_t *pu8Org = &gabBigMem[0];
491 while (cb > 0)
492 {
493 char achPage[PAGE_SIZE];
494 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
495 if (RT_FAILURE(rc))
496 {
497 RTPrintf("Item03: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, TSTSSM_ITEM_SIZE - cb);
498 return rc;
499 }
500 if (memcmp(achPage, pu8Org, PAGE_SIZE))
501 {
502 RTPrintf("Item03: compare failed. mem offset=%#x\n", TSTSSM_ITEM_SIZE - cb);
503 return VERR_GENERAL_FAILURE;
504 }
505
506 /* next */
507 cb -= PAGE_SIZE;
508 pu8Org += PAGE_SIZE;
509 if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
510 pu8Org = &gabBigMem[0];
511 }
512
513 return 0;
514}
515
516
517/**
518 * Execute state save operation.
519 *
520 * @returns VBox status code.
521 * @param pDevIns Device instance of the device which registered the data unit.
522 * @param pSSM SSM operation handle.
523 */
524DECLCALLBACK(int) Item04Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
525{
526 NOREF(pDevIns);
527 uint64_t u64Start = RTTimeNanoTS();
528
529 /*
530 * Put the size.
531 */
532 uint32_t cb = 512*_1M;
533 int rc = SSMR3PutU32(pSSM, cb);
534 if (RT_FAILURE(rc))
535 {
536 RTPrintf("Item04: PutU32 -> %Rrc\n", rc);
537 return rc;
538 }
539
540 /*
541 * Put 512 MB page by page.
542 */
543 while (cb > 0)
544 {
545 rc = SSMR3PutMem(pSSM, gabPage, PAGE_SIZE);
546 if (RT_FAILURE(rc))
547 {
548 RTPrintf("Item04: PutMem(,%p,%#x) -> %Rrc\n", gabPage, PAGE_SIZE, rc);
549 return rc;
550 }
551
552 /* next */
553 cb -= PAGE_SIZE;
554 }
555
556 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
557 RTPrintf("tstSSM: Saved 4th item in %'RI64 ns\n", u64Elapsed);
558 return 0;
559}
560
561/**
562 * Prepare state load operation.
563 *
564 * @returns VBox status code.
565 * @param pDevIns Device instance of the device which registered the data unit.
566 * @param pSSM SSM operation handle.
567 * @param uVersion The data layout version.
568 * @param uPass The data pass.
569 */
570DECLCALLBACK(int) Item04Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
571{
572 NOREF(pDevIns); NOREF(uPass);
573 if (uVersion != 42)
574 {
575 RTPrintf("Item04: uVersion=%#x, expected 42\n", uVersion);
576 return VERR_GENERAL_FAILURE;
577 }
578
579 /*
580 * Load the size.
581 */
582 uint32_t cb;
583 int rc = SSMR3GetU32(pSSM, &cb);
584 if (RT_FAILURE(rc))
585 {
586 RTPrintf("Item04: SSMR3GetU32 -> %Rrc\n", rc);
587 return rc;
588 }
589 if (cb != 512*_1M)
590 {
591 RTPrintf("Item04: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
592 return VERR_GENERAL_FAILURE;
593 }
594
595 /*
596 * Load the memory page by page.
597 */
598 while (cb > 0)
599 {
600 char achPage[PAGE_SIZE];
601 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
602 if (RT_FAILURE(rc))
603 {
604 RTPrintf("Item04: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
605 return rc;
606 }
607 if (memcmp(achPage, gabPage, PAGE_SIZE))
608 {
609 RTPrintf("Item04: compare failed. mem offset=%#x\n", 512*_1M - cb);
610 return VERR_GENERAL_FAILURE;
611 }
612
613 /* next */
614 cb -= PAGE_SIZE;
615 }
616
617 return 0;
618}
619
620
621/**
622 * Creates a mockup VM structure for testing SSM.
623 *
624 * @returns 0 on success, 1 on failure.
625 * @param ppVM Where to store the VM handle.
626 *
627 * @todo Move this to VMM/VM since it's stuff done by several testcases.
628 */
629static int createFakeVM(PVM *ppVM)
630{
631 /*
632 * Allocate and init the UVM structure.
633 */
634 PUVM pUVM = (PUVM)RTMemAllocZ(sizeof(*pUVM));
635 AssertReturn(pUVM, 1);
636 pUVM->u32Magic = UVM_MAGIC;
637 pUVM->vm.s.idxTLS = RTTlsAlloc();
638 int rc = RTTlsSet(pUVM->vm.s.idxTLS, &pUVM->aCpus[0]);
639 if (RT_SUCCESS(rc))
640 {
641 pUVM->aCpus[0].pUVM = pUVM;
642 pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
643
644 rc = STAMR3InitUVM(pUVM);
645 if (RT_SUCCESS(rc))
646 {
647 rc = MMR3InitUVM(pUVM);
648 if (RT_SUCCESS(rc))
649 {
650 /*
651 * Allocate and init the VM structure.
652 */
653 PVM pVM;
654 rc = SUPR3PageAlloc((sizeof(*pVM) + PAGE_SIZE - 1) >> PAGE_SHIFT, (void **)&pVM);
655 if (RT_SUCCESS(rc))
656 {
657 pVM->enmVMState = VMSTATE_CREATED;
658 pVM->pVMR3 = pVM;
659 pVM->pUVM = pUVM;
660 pVM->cCpus = 1;
661 pVM->aCpus[0].pVMR3 = pVM;
662 pVM->aCpus[0].hNativeThread = RTThreadNativeSelf();
663
664 pUVM->pVM = pVM;
665 *ppVM = pVM;
666 return 0;
667 }
668
669 RTPrintf("Fatal error: failed to allocated pages for the VM structure, rc=%Rrc\n", rc);
670 }
671 else
672 RTPrintf("Fatal error: MMR3InitUVM failed, rc=%Rrc\n", rc);
673 }
674 else
675 RTPrintf("Fatal error: SSMR3InitUVM failed, rc=%Rrc\n", rc);
676 }
677 else
678 RTPrintf("Fatal error: RTTlsSet failed, rc=%Rrc\n", rc);
679
680 *ppVM = NULL;
681 return 1;
682}
683
684
685int main(int argc, char **argv)
686{
687 /*
688 * Init runtime and static data.
689 */
690 RTR3InitExe(argc, &argv, RTR3INIT_FLAGS_SUPLIB);
691 RTPrintf("tstSSM: TESTING...\n");
692 initBigMem();
693 const char *pszFilename = "SSMTestSave#1";
694
695 /*
696 * Create an fake VM structure and init SSM.
697 */
698 int rc = SUPR3Init(NULL);
699 if (RT_FAILURE(rc))
700 {
701 RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc);
702 return 1;
703 }
704 PVM pVM;
705 if (createFakeVM(&pVM))
706 return 1;
707
708 /*
709 * Register a few callbacks.
710 */
711 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256, NULL,
712 NULL, NULL, NULL,
713 NULL, Item01Save, NULL,
714 NULL, Item01Load, NULL);
715 if (RT_FAILURE(rc))
716 {
717 RTPrintf("SSMR3Register #1 -> %Rrc\n", rc);
718 return 1;
719 }
720
721 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8, NULL,
722 NULL, NULL, NULL,
723 NULL, Item02Save, NULL,
724 NULL, Item02Load, NULL);
725 if (RT_FAILURE(rc))
726 {
727 RTPrintf("SSMR3Register #2 -> %Rrc\n", rc);
728 return 1;
729 }
730
731 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M, NULL,
732 NULL, NULL, NULL,
733 NULL, Item03Save, NULL,
734 NULL, Item03Load, NULL);
735 if (RT_FAILURE(rc))
736 {
737 RTPrintf("SSMR3Register #3 -> %Rrc\n", rc);
738 return 1;
739 }
740
741 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M, NULL,
742 NULL, NULL, NULL,
743 NULL, Item04Save, NULL,
744 NULL, Item04Load, NULL);
745 if (RT_FAILURE(rc))
746 {
747 RTPrintf("SSMR3Register #4 -> %Rrc\n", rc);
748 return 1;
749 }
750
751 /*
752 * Attempt a save.
753 */
754 uint64_t u64Start = RTTimeNanoTS();
755 rc = SSMR3Save(pVM, pszFilename, NULL, NULL, SSMAFTER_DESTROY, NULL, NULL);
756 if (RT_FAILURE(rc))
757 {
758 RTPrintf("SSMR3Save #1 -> %Rrc\n", rc);
759 return 1;
760 }
761 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
762 RTPrintf("tstSSM: Saved in %'RI64 ns\n", u64Elapsed);
763
764 RTFSOBJINFO Info;
765 rc = RTPathQueryInfo(pszFilename, &Info, RTFSOBJATTRADD_NOTHING);
766 if (RT_FAILURE(rc))
767 {
768 RTPrintf("tstSSM: failed to query file size: %Rrc\n", rc);
769 return 1;
770 }
771 RTPrintf("tstSSM: file size %'RI64 bytes\n", Info.cbObject);
772
773 /*
774 * Attempt a load.
775 */
776 u64Start = RTTimeNanoTS();
777 rc = SSMR3Load(pVM, pszFilename, NULL /*pStreamOps*/, NULL /*pStreamOpsUser*/,
778 SSMAFTER_RESUME, NULL /*pfnProgress*/, NULL /*pvProgressUser*/);
779 if (RT_FAILURE(rc))
780 {
781 RTPrintf("SSMR3Load #1 -> %Rrc\n", rc);
782 return 1;
783 }
784 u64Elapsed = RTTimeNanoTS() - u64Start;
785 RTPrintf("tstSSM: Loaded in %'RI64 ns\n", u64Elapsed);
786
787 /*
788 * Validate it.
789 */
790 u64Start = RTTimeNanoTS();
791 rc = SSMR3ValidateFile(pszFilename, false /* fChecksumIt*/ );
792 if (RT_FAILURE(rc))
793 {
794 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
795 return 1;
796 }
797 u64Elapsed = RTTimeNanoTS() - u64Start;
798 RTPrintf("tstSSM: Validated without checksumming in %'RI64 ns\n", u64Elapsed);
799
800 u64Start = RTTimeNanoTS();
801 rc = SSMR3ValidateFile(pszFilename, true /* fChecksumIt */);
802 if (RT_FAILURE(rc))
803 {
804 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
805 return 1;
806 }
807 u64Elapsed = RTTimeNanoTS() - u64Start;
808 RTPrintf("tstSSM: Validated and checksummed in %'RI64 ns\n", u64Elapsed);
809
810 /*
811 * Open it and read.
812 */
813 u64Start = RTTimeNanoTS();
814 PSSMHANDLE pSSM;
815 rc = SSMR3Open(pszFilename, 0, &pSSM);
816 if (RT_FAILURE(rc))
817 {
818 RTPrintf("SSMR3Open #1 -> %Rrc\n", rc);
819 return 1;
820 }
821 u64Elapsed = RTTimeNanoTS() - u64Start;
822 RTPrintf("tstSSM: Opened in %'RI64 ns\n", u64Elapsed);
823
824 /* negative */
825 u64Start = RTTimeNanoTS();
826 rc = SSMR3Seek(pSSM, "some unit that doesn't exist", 0, NULL);
827 if (rc != VERR_SSM_UNIT_NOT_FOUND)
828 {
829 RTPrintf("SSMR3Seek #1 negative -> %Rrc\n", rc);
830 return 1;
831 }
832 u64Elapsed = RTTimeNanoTS() - u64Start;
833 RTPrintf("tstSSM: Failed seek in %'RI64 ns\n", u64Elapsed);
834
835 /* another negative, now only the instance number isn't matching. */
836 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, NULL);
837 if (rc != VERR_SSM_UNIT_NOT_FOUND)
838 {
839 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc\n", rc);
840 return 1;
841 }
842
843 /* 2nd unit */
844 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, NULL);
845 if (RT_FAILURE(rc))
846 {
847 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [2]\n", rc);
848 return 1;
849 }
850 uint32_t uVersion = 0xbadc0ded;
851 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, &uVersion);
852 if (RT_FAILURE(rc))
853 {
854 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [3]\n", rc);
855 return 1;
856 }
857 u64Start = RTTimeNanoTS();
858 rc = Item02Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
859 if (RT_FAILURE(rc))
860 {
861 RTPrintf("Item02Load #1 -> %Rrc\n", rc);
862 return 1;
863 }
864 u64Elapsed = RTTimeNanoTS() - u64Start;
865 RTPrintf("tstSSM: Loaded 2nd item in %'RI64 ns\n", u64Elapsed);
866
867 /* 1st unit */
868 uVersion = 0xbadc0ded;
869 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.1 (all types)", 1, &uVersion);
870 if (RT_FAILURE(rc))
871 {
872 RTPrintf("SSMR3Seek #1 unit 1 -> %Rrc\n", rc);
873 return 1;
874 }
875 u64Start = RTTimeNanoTS();
876 rc = Item01Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
877 if (RT_FAILURE(rc))
878 {
879 RTPrintf("Item01Load #1 -> %Rrc\n", rc);
880 return 1;
881 }
882 u64Elapsed = RTTimeNanoTS() - u64Start;
883 RTPrintf("tstSSM: Loaded 1st item in %'RI64 ns\n", u64Elapsed);
884
885 /* 3st unit */
886 uVersion = 0xbadc0ded;
887 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.3 (big mem)", 0, &uVersion);
888 if (RT_FAILURE(rc))
889 {
890 RTPrintf("SSMR3Seek #3 unit 1 -> %Rrc\n", rc);
891 return 1;
892 }
893 u64Start = RTTimeNanoTS();
894 rc = Item03Load(NULL, pSSM, uVersion, SSM_PASS_FINAL);
895 if (RT_FAILURE(rc))
896 {
897 RTPrintf("Item01Load #3 -> %Rrc\n", rc);
898 return 1;
899 }
900 u64Elapsed = RTTimeNanoTS() - u64Start;
901 RTPrintf("tstSSM: Loaded 3rd item in %'RI64 ns\n", u64Elapsed);
902
903 /* close */
904 rc = SSMR3Close(pSSM);
905 if (RT_FAILURE(rc))
906 {
907 RTPrintf("SSMR3Close #1 -> %Rrc\n", rc);
908 return 1;
909 }
910
911 RTPrintf("tstSSM: SUCCESS\n");
912 return 0;
913}
914
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