VirtualBox

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

Last change on this file since 44401 was 41965, checked in by vboxsync, 12 years ago

VMM: ran scm. Mostly svn:keywords changes (adding Revision).

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