VirtualBox

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

Last change on this file since 36198 was 35346, checked in by vboxsync, 14 years ago

VMM reorg: Moving the public include files from include/VBox to include/VBox/vmm.

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