VirtualBox

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

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

tstSSM.cpp: re-enable big config.

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette