VirtualBox

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

最後變更 在這個檔案從22108是 22025,由 vboxsync 提交於 16 年 前

SSM: Detect zero pages in ssmR3DataWriteBig and store them using a 3 byte record instead of passing them on to LZF. LZF is kind of fast, but ASMMemIsZeroPage + memset is way faster.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Id
檔案大小: 24.4 KB
 
1/* $Id: tstSSM.cpp 22025 2009-08-06 11:36:08Z 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.alldomusa.eu.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
94 /* add some zero pages */
95 memset(&gabBigMem[sizeof(gabBigMem) / 4], 0, PAGE_SIZE * 4);
96 memset(&gabBigMem[sizeof(gabBigMem) / 4 * 3], 0, PAGE_SIZE * 4);
97#endif
98}
99
100/**
101 * Execute state save operation.
102 *
103 * @returns VBox status code.
104 * @param pDevIns Device instance of the device which registered the data unit.
105 * @param pSSM SSM operation handle.
106 */
107DECLCALLBACK(int) Item01Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
108{
109 uint64_t u64Start = RTTimeNanoTS();
110
111 /*
112 * Test writing some memory block.
113 */
114 int rc = SSMR3PutMem(pSSM, gachMem1, sizeof(gachMem1));
115 if (RT_FAILURE(rc))
116 {
117 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
118 return rc;
119 }
120
121 /*
122 * Test writing a zeroterminated string.
123 */
124 rc = SSMR3PutStrZ(pSSM, "String");
125 if (RT_FAILURE(rc))
126 {
127 RTPrintf("Item01: #1 - SSMR3PutMem -> %Rrc\n", rc);
128 return rc;
129 }
130
131
132 /*
133 * Test the individual integer put functions to see that they all work.
134 * (Testcases are also known as "The Land of The Ugly Code"...)
135 */
136#define ITEM(suff,bits, val) \
137 rc = SSMR3Put##suff(pSSM, val); \
138 if (RT_FAILURE(rc)) \
139 { \
140 RTPrintf("Item01: #" #suff " - SSMR3Put" #suff "(," #val ") -> %Rrc\n", rc); \
141 return rc; \
142 }
143 /* copy & past with the load one! */
144 ITEM(U8, uint8_t, 0xff);
145 ITEM(U8, uint8_t, 0x0);
146 ITEM(U8, uint8_t, 1);
147 ITEM(U8, uint8_t, 42);
148 ITEM(U8, uint8_t, 230);
149 ITEM(S8, int8_t, -128);
150 ITEM(S8, int8_t, 127);
151 ITEM(S8, int8_t, 12);
152 ITEM(S8, int8_t, -76);
153 ITEM(U16, uint16_t, 0xffff);
154 ITEM(U16, uint16_t, 0x0);
155 ITEM(S16, int16_t, 32767);
156 ITEM(S16, int16_t, -32768);
157 ITEM(U32, uint32_t, 4294967295U);
158 ITEM(U32, uint32_t, 0);
159 ITEM(U32, uint32_t, 42);
160 ITEM(U32, uint32_t, 2342342344U);
161 ITEM(S32, int32_t, -2147483647-1);
162 ITEM(S32, int32_t, 2147483647);
163 ITEM(S32, int32_t, 42);
164 ITEM(S32, int32_t, 568459834);
165 ITEM(S32, int32_t, -58758999);
166 ITEM(U64, uint64_t, 18446744073709551615ULL);
167 ITEM(U64, uint64_t, 0);
168 ITEM(U64, uint64_t, 42);
169 ITEM(U64, uint64_t, 593023944758394234ULL);
170 ITEM(S64, int64_t, 9223372036854775807LL);
171 ITEM(S64, int64_t, -9223372036854775807LL - 1);
172 ITEM(S64, int64_t, 42);
173 ITEM(S64, int64_t, 21398723459873LL);
174 ITEM(S64, int64_t, -5848594593453453245LL);
175#undef ITEM
176
177 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
178 RTPrintf("tstSSM: Saved 1st item in %'RI64 ns\n", u64Elapsed);
179 return 0;
180}
181
182/**
183 * Prepare state load operation.
184 *
185 * @returns VBox status code.
186 * @param pDevIns Device instance of the device which registered the data unit.
187 * @param pSSM SSM operation handle.
188 */
189DECLCALLBACK(int) Item01Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
190{
191 if (u32Version != 0)
192 {
193 RTPrintf("Item01: u32Version=%#x, expected 0\n", u32Version);
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 uint64_t u64Start = RTTimeNanoTS();
285
286 /*
287 * Put the size.
288 */
289 uint32_t cb = sizeof(gabBigMem);
290 int rc = SSMR3PutU32(pSSM, cb);
291 if (RT_FAILURE(rc))
292 {
293 RTPrintf("Item02: PutU32 -> %Rrc\n", rc);
294 return rc;
295 }
296
297 /*
298 * Put 8MB of memory to the file in 3 chunks.
299 */
300 uint8_t *pbMem = &gabBigMem[0];
301 uint32_t cbChunk = cb / 47;
302 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
303 if (RT_FAILURE(rc))
304 {
305 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
306 return rc;
307 }
308 cb -= cbChunk;
309 pbMem += cbChunk;
310
311 /* next piece. */
312 cbChunk *= 19;
313 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
314 if (RT_FAILURE(rc))
315 {
316 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
317 return rc;
318 }
319 cb -= cbChunk;
320 pbMem += cbChunk;
321
322 /* last piece. */
323 cbChunk = cb;
324 rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
325 if (RT_FAILURE(rc))
326 {
327 RTPrintf("Item02: PutMem(,%p,%#x) -> %Rrc\n", pbMem, cbChunk, rc);
328 return rc;
329 }
330
331 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
332 RTPrintf("tstSSM: Saved 2nd item in %'RI64 ns\n", u64Elapsed);
333 return 0;
334}
335
336/**
337 * Prepare state load operation.
338 *
339 * @returns VBox status code.
340 * @param pDevIns Device instance of the device which registered the data unit.
341 * @param pSSM SSM operation handle.
342 */
343DECLCALLBACK(int) Item02Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
344{
345 if (u32Version != 0)
346 {
347 RTPrintf("Item02: u32Version=%#x, expected 0\n", u32Version);
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 */
455DECLCALLBACK(int) Item03Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
456{
457 if (u32Version != 123)
458 {
459 RTPrintf("Item03: u32Version=%#x, expected 123\n", u32Version);
460 return VERR_GENERAL_FAILURE;
461 }
462
463 /*
464 * Load the size.
465 */
466 uint32_t cb;
467 int rc = SSMR3GetU32(pSSM, &cb);
468 if (RT_FAILURE(rc))
469 {
470 RTPrintf("Item03: SSMR3GetU32 -> %Rrc\n", rc);
471 return rc;
472 }
473 if (cb != TSTSSM_ITEM_SIZE)
474 {
475 RTPrintf("Item03: loaded size doesn't match the real thing. %#x != %#x\n", cb, TSTSSM_ITEM_SIZE);
476 return VERR_GENERAL_FAILURE;
477 }
478
479 /*
480 * Load the memory page by page.
481 */
482 const uint8_t *pu8Org = &gabBigMem[0];
483 while (cb > 0)
484 {
485 char achPage[PAGE_SIZE];
486 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
487 if (RT_FAILURE(rc))
488 {
489 RTPrintf("Item03: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, TSTSSM_ITEM_SIZE - cb);
490 return rc;
491 }
492 if (memcmp(achPage, pu8Org, PAGE_SIZE))
493 {
494 RTPrintf("Item03: compare failed. mem offset=%#x\n", TSTSSM_ITEM_SIZE - cb);
495 return VERR_GENERAL_FAILURE;
496 }
497
498 /* next */
499 cb -= PAGE_SIZE;
500 pu8Org += PAGE_SIZE;
501 if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
502 pu8Org = &gabBigMem[0];
503 }
504
505 return 0;
506}
507
508
509/**
510 * Execute state save operation.
511 *
512 * @returns VBox status code.
513 * @param pDevIns Device instance of the device which registered the data unit.
514 * @param pSSM SSM operation handle.
515 */
516DECLCALLBACK(int) Item04Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
517{
518 uint64_t u64Start = RTTimeNanoTS();
519
520 /*
521 * Put the size.
522 */
523 uint32_t cb = 512*_1M;
524 int rc = SSMR3PutU32(pSSM, cb);
525 if (RT_FAILURE(rc))
526 {
527 RTPrintf("Item04: PutU32 -> %Rrc\n", rc);
528 return rc;
529 }
530
531 /*
532 * Put 512 MB page by page.
533 */
534 while (cb > 0)
535 {
536 rc = SSMR3PutMem(pSSM, gabPage, PAGE_SIZE);
537 if (RT_FAILURE(rc))
538 {
539 RTPrintf("Item04: PutMem(,%p,%#x) -> %Rrc\n", gabPage, PAGE_SIZE, rc);
540 return rc;
541 }
542
543 /* next */
544 cb -= PAGE_SIZE;
545 }
546
547 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
548 RTPrintf("tstSSM: Saved 4th item in %'RI64 ns\n", u64Elapsed);
549 return 0;
550}
551
552/**
553 * Prepare state load operation.
554 *
555 * @returns VBox status code.
556 * @param pDevIns Device instance of the device which registered the data unit.
557 * @param pSSM SSM operation handle.
558 */
559DECLCALLBACK(int) Item04Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
560{
561 if (u32Version != 42)
562 {
563 RTPrintf("Item04: u32Version=%#x, expected 42\n", u32Version);
564 return VERR_GENERAL_FAILURE;
565 }
566
567 /*
568 * Load the size.
569 */
570 uint32_t cb;
571 int rc = SSMR3GetU32(pSSM, &cb);
572 if (RT_FAILURE(rc))
573 {
574 RTPrintf("Item04: SSMR3GetU32 -> %Rrc\n", rc);
575 return rc;
576 }
577 if (cb != 512*_1M)
578 {
579 RTPrintf("Item04: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
580 return VERR_GENERAL_FAILURE;
581 }
582
583 /*
584 * Load the memory page by page.
585 */
586 while (cb > 0)
587 {
588 char achPage[PAGE_SIZE];
589 rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
590 if (RT_FAILURE(rc))
591 {
592 RTPrintf("Item04: SSMR3GetMem(,,%#x) -> %Rrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
593 return rc;
594 }
595 if (memcmp(achPage, gabPage, PAGE_SIZE))
596 {
597 RTPrintf("Item04: compare failed. mem offset=%#x\n", 512*_1M - cb);
598 return VERR_GENERAL_FAILURE;
599 }
600
601 /* next */
602 cb -= PAGE_SIZE;
603 }
604
605 return 0;
606}
607
608
609/**
610 * Creates a mockup VM structure for testing SSM.
611 *
612 * @returns 0 on success, 1 on failure.
613 * @param ppVM Where to store the VM handle.
614 *
615 * @todo Move this to VMM/VM since it's stuff done by several testcases.
616 */
617static int createFakeVM(PVM *ppVM)
618{
619 /*
620 * Allocate and init the UVM structure.
621 */
622 PUVM pUVM = (PUVM)RTMemAllocZ(sizeof(*pUVM));
623 AssertReturn(pUVM, 1);
624 pUVM->u32Magic = UVM_MAGIC;
625 pUVM->vm.s.idxTLS = RTTlsAlloc();
626 int rc = RTTlsSet(pUVM->vm.s.idxTLS, &pUVM->aCpus[0]);
627 if (RT_SUCCESS(rc))
628 {
629 pUVM->aCpus[0].pUVM = pUVM;
630 pUVM->aCpus[0].vm.s.NativeThreadEMT = RTThreadNativeSelf();
631
632 rc = STAMR3InitUVM(pUVM);
633 if (RT_SUCCESS(rc))
634 {
635 rc = MMR3InitUVM(pUVM);
636 if (RT_SUCCESS(rc))
637 {
638 /*
639 * Allocate and init the VM structure.
640 */
641 PVM pVM;
642 rc = SUPR3PageAlloc((sizeof(*pVM) + PAGE_SIZE - 1) >> PAGE_SHIFT, (void **)&pVM);
643 if (RT_SUCCESS(rc))
644 {
645 pVM->enmVMState = VMSTATE_CREATED;
646 pVM->pVMR3 = pVM;
647 pVM->pUVM = pUVM;
648 pVM->cCPUs = 1;
649 pVM->aCpus[0].pVMR3 = pVM;
650 pVM->aCpus[0].hNativeThread = RTThreadNativeSelf();
651
652 pUVM->pVM = pVM;
653 *ppVM = pVM;
654 return 0;
655 }
656
657 RTPrintf("Fatal error: failed to allocated pages for the VM structure, rc=%Rrc\n", rc);
658 }
659 else
660 RTPrintf("Fatal error: MMR3InitUVM failed, rc=%Rrc\n", rc);
661 }
662 else
663 RTPrintf("Fatal error: SSMR3InitUVM failed, rc=%Rrc\n", rc);
664 }
665 else
666 RTPrintf("Fatal error: RTTlsSet failed, rc=%Rrc\n", rc);
667
668 *ppVM = NULL;
669 return 1;
670}
671
672
673int main(int argc, char **argv)
674{
675 /*
676 * Init runtime and static data.
677 */
678 RTR3InitAndSUPLib();
679 RTPrintf("tstSSM: TESTING...\n");
680 initBigMem();
681 const char *pszFilename = "SSMTestSave#1";
682
683 /*
684 * Create an fake VM structure and init SSM.
685 */
686 int rc = SUPR3Init(NULL);
687 if (RT_FAILURE(rc))
688 {
689 RTPrintf("Fatal error: SUP Failure! rc=%Rrc\n", rc);
690 return 1;
691 }
692 PVM pVM;
693 if (createFakeVM(&pVM))
694 return 1;
695
696 /*
697 * Register a few callbacks.
698 */
699 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256, NULL,
700 NULL, Item01Save, NULL,
701 NULL, Item01Load, NULL);
702 if (RT_FAILURE(rc))
703 {
704 RTPrintf("SSMR3Register #1 -> %Rrc\n", rc);
705 return 1;
706 }
707
708 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8, NULL,
709 NULL, Item02Save, NULL,
710 NULL, Item02Load, NULL);
711 if (RT_FAILURE(rc))
712 {
713 RTPrintf("SSMR3Register #2 -> %Rrc\n", rc);
714 return 1;
715 }
716
717 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M, NULL,
718 NULL, Item03Save, NULL,
719 NULL, Item03Load, NULL);
720 if (RT_FAILURE(rc))
721 {
722 RTPrintf("SSMR3Register #3 -> %Rrc\n", rc);
723 return 1;
724 }
725
726 rc = SSMR3RegisterDevice(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M, NULL,
727 NULL, Item04Save, NULL,
728 NULL, Item04Load, NULL);
729 if (RT_FAILURE(rc))
730 {
731 RTPrintf("SSMR3Register #4 -> %Rrc\n", rc);
732 return 1;
733 }
734
735 /*
736 * Attempt a save.
737 */
738 uint64_t u64Start = RTTimeNanoTS();
739 rc = SSMR3Save(pVM, pszFilename, SSMAFTER_DESTROY, NULL, NULL);
740 if (RT_FAILURE(rc))
741 {
742 RTPrintf("SSMR3Save #1 -> %Rrc\n", rc);
743 return 1;
744 }
745 uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
746 RTPrintf("tstSSM: Saved in %'RI64 ns\n", u64Elapsed);
747
748 RTFSOBJINFO Info;
749 rc = RTPathQueryInfo(pszFilename, &Info, RTFSOBJATTRADD_NOTHING);
750 if (RT_FAILURE(rc))
751 {
752 RTPrintf("tstSSM: failed to query file size: %Rrc\n", rc);
753 return 1;
754 }
755 RTPrintf("tstSSM: file size %'RI64 bytes\n", Info.cbObject);
756
757 /*
758 * Attempt a load.
759 */
760 u64Start = RTTimeNanoTS();
761 rc = SSMR3Load(pVM, pszFilename, SSMAFTER_RESUME, NULL, NULL);
762 if (RT_FAILURE(rc))
763 {
764 RTPrintf("SSMR3Load #1 -> %Rrc\n", rc);
765 return 1;
766 }
767 u64Elapsed = RTTimeNanoTS() - u64Start;
768 RTPrintf("tstSSM: Loaded in %'RI64 ns\n", u64Elapsed);
769
770 /*
771 * Validate it.
772 */
773 u64Start = RTTimeNanoTS();
774 rc = SSMR3ValidateFile(pszFilename, false /* fChecksumIt*/ );
775 if (RT_FAILURE(rc))
776 {
777 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
778 return 1;
779 }
780 u64Elapsed = RTTimeNanoTS() - u64Start;
781 RTPrintf("tstSSM: Validated without checksumming in %'RI64 ns\n", u64Elapsed);
782
783 u64Start = RTTimeNanoTS();
784 rc = SSMR3ValidateFile(pszFilename, true /* fChecksumIt */);
785 if (RT_FAILURE(rc))
786 {
787 RTPrintf("SSMR3ValidateFile #1 -> %Rrc\n", rc);
788 return 1;
789 }
790 u64Elapsed = RTTimeNanoTS() - u64Start;
791 RTPrintf("tstSSM: Validated and checksummed in %'RI64 ns\n", u64Elapsed);
792
793 /*
794 * Open it and read.
795 */
796 u64Start = RTTimeNanoTS();
797 PSSMHANDLE pSSM;
798 rc = SSMR3Open(pszFilename, 0, &pSSM);
799 if (RT_FAILURE(rc))
800 {
801 RTPrintf("SSMR3Open #1 -> %Rrc\n", rc);
802 return 1;
803 }
804 u64Elapsed = RTTimeNanoTS() - u64Start;
805 RTPrintf("tstSSM: Opened in %'RI64 ns\n", u64Elapsed);
806
807 /* negative */
808 u64Start = RTTimeNanoTS();
809 rc = SSMR3Seek(pSSM, "some unit that doesn't exist", 0, NULL);
810 if (rc != VERR_SSM_UNIT_NOT_FOUND)
811 {
812 RTPrintf("SSMR3Seek #1 negative -> %Rrc\n", rc);
813 return 1;
814 }
815 u64Elapsed = RTTimeNanoTS() - u64Start;
816 RTPrintf("tstSSM: Failed seek in %'RI64 ns\n", u64Elapsed);
817
818 /* another negative, now only the instance number isn't matching. */
819 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, NULL);
820 if (rc != VERR_SSM_UNIT_NOT_FOUND)
821 {
822 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc\n", rc);
823 return 1;
824 }
825
826 /* 2nd unit */
827 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, NULL);
828 if (RT_FAILURE(rc))
829 {
830 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [2]\n", rc);
831 return 1;
832 }
833 uint32_t u32Version = 0xbadc0ded;
834 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 2, &u32Version);
835 if (RT_FAILURE(rc))
836 {
837 RTPrintf("SSMR3Seek #1 unit 2 -> %Rrc [3]\n", rc);
838 return 1;
839 }
840 u64Start = RTTimeNanoTS();
841 rc = Item02Load(NULL, pSSM, u32Version);
842 if (RT_FAILURE(rc))
843 {
844 RTPrintf("Item02Load #1 -> %Rrc\n", rc);
845 return 1;
846 }
847 u64Elapsed = RTTimeNanoTS() - u64Start;
848 RTPrintf("tstSSM: Loaded 2nd item in %'RI64 ns\n", u64Elapsed);
849
850 /* 1st unit */
851 u32Version = 0xbadc0ded;
852 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.1 (all types)", 1, &u32Version);
853 if (RT_FAILURE(rc))
854 {
855 RTPrintf("SSMR3Seek #1 unit 1 -> %Rrc\n", rc);
856 return 1;
857 }
858 u64Start = RTTimeNanoTS();
859 rc = Item01Load(NULL, pSSM, u32Version);
860 if (RT_FAILURE(rc))
861 {
862 RTPrintf("Item01Load #1 -> %Rrc\n", rc);
863 return 1;
864 }
865 u64Elapsed = RTTimeNanoTS() - u64Start;
866 RTPrintf("tstSSM: Loaded 1st item in %'RI64 ns\n", u64Elapsed);
867
868 /* 3st unit */
869 u32Version = 0xbadc0ded;
870 rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.3 (big mem)", 0, &u32Version);
871 if (RT_FAILURE(rc))
872 {
873 RTPrintf("SSMR3Seek #3 unit 1 -> %Rrc\n", rc);
874 return 1;
875 }
876 u64Start = RTTimeNanoTS();
877 rc = Item03Load(NULL, pSSM, u32Version);
878 if (RT_FAILURE(rc))
879 {
880 RTPrintf("Item01Load #3 -> %Rrc\n", rc);
881 return 1;
882 }
883 u64Elapsed = RTTimeNanoTS() - u64Start;
884 RTPrintf("tstSSM: Loaded 3rd item in %'RI64 ns\n", u64Elapsed);
885
886 /* close */
887 rc = SSMR3Close(pSSM);
888 if (RT_FAILURE(rc))
889 {
890 RTPrintf("SSMR3Close #1 -> %Rrc\n", rc);
891 return 1;
892 }
893
894 RTPrintf("tstSSM: SUCCESS\n");
895 return 0;
896}
897
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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