1
/* $Id: tstSSM.cpp 4071 2007-08-07 17:07:59Z vboxsync $ */
3
* Saved State Manager Testcase.
7
* Copyright (C) 2006-2007 innotek GmbH
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 as published by the Free Software Foundation,
13
* in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14
* distribution. VirtualBox OSE is distributed in the hope that it will
15
* be useful, but WITHOUT ANY WARRANTY of any kind.
19
/*******************************************************************************
21
*******************************************************************************/
28
#include <VBox/param.h>
29
#include <iprt/runtime.h>
30
#include <iprt/assert.h>
31
#include <iprt/stream.h>
32
#include <iprt/string.h>
33
#include <iprt/time.h>
36
const uint8_t gabPage[PAGE_SIZE] = {0};
38
const char gachMem1[] = "sdfg\1asdfa\177hjkl;sdfghjkl;dfghjkl;dfghjkl;\0\0asdf;kjasdf;lkjasd;flkjasd;lfkjasd\0;lfk";
40
uint8_t gabBigMem[8*1024*1024];
42
/** initializes gabBigMem with some non zero stuff. */
46
uint32_t *puch = (uint32_t *)&gabBigMem[0];
47
uint32_t *puchEnd = (uint32_t *)&gabBigMem[sizeof(gabBigMem)];
48
uint32_t u32 = 0xdeadbeef;
49
for (; puch < puchEnd; puch++)
53
u32 = (u32 << 1) | (u32 >> 31);
56
uint8_t *pb = &gabBigMem[0];
57
uint8_t *pbEnd = &gabBigMem[sizeof(gabBigMem)];
58
for (; pb < pbEnd; pb += 16)
61
RTStrPrintf(szTmp, sizeof(szTmp), "aaaa%08Xzzzz", (uint32_t)(uintptr_t)pb);
62
memcpy(pb, szTmp, 16);
68
* Execute state save operation.
70
* @returns VBox status code.
71
* @param pDevIns Device instance of the device which registered the data unit.
72
* @param pSSM SSM operation handle.
74
DECLCALLBACK(int) Item01Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
76
uint64_t u64Start = RTTimeNanoTS();
79
* Test writing some memory block.
81
int rc = SSMR3PutMem(pSSM, gachMem1, sizeof(gachMem1));
84
RTPrintf("Item01: #1 - SSMR3PutMem -> %Vrc\n", rc);
89
* Test writing a zeroterminated string.
91
rc = SSMR3PutStrZ(pSSM, "String");
94
RTPrintf("Item01: #1 - SSMR3PutMem -> %Vrc\n", rc);
100
* Test the individual integer put functions to see that they all work.
101
* (Testcases are also known as "The Land of The Ugly Code"...)
103
#define ITEM(suff,bits, val) \
104
rc = SSMR3Put##suff(pSSM, val); \
105
if (VBOX_FAILURE(rc)) \
107
RTPrintf("Item01: #" #suff " - SSMR3Put" #suff "(," #val ") -> %Vrc\n", rc); \
110
/* copy & past with the load one! */
111
ITEM(U8, uint8_t, 0xff);
112
ITEM(U8, uint8_t, 0x0);
113
ITEM(U8, uint8_t, 1);
114
ITEM(U8, uint8_t, 42);
115
ITEM(U8, uint8_t, 230);
116
ITEM(S8, int8_t, -128);
117
ITEM(S8, int8_t, 127);
118
ITEM(S8, int8_t, 12);
119
ITEM(S8, int8_t, -76);
120
ITEM(U16, uint16_t, 0xffff);
121
ITEM(U16, uint16_t, 0x0);
122
ITEM(S16, int16_t, 32767);
123
ITEM(S16, int16_t, -32768);
124
ITEM(U32, uint32_t, 4294967295U);
125
ITEM(U32, uint32_t, 0);
126
ITEM(U32, uint32_t, 42);
127
ITEM(U32, uint32_t, 2342342344U);
128
ITEM(S32, int32_t, -2147483647-1);
129
ITEM(S32, int32_t, 2147483647);
130
ITEM(S32, int32_t, 42);
131
ITEM(S32, int32_t, 568459834);
132
ITEM(S32, int32_t, -58758999);
133
ITEM(U64, uint64_t, 18446744073709551615ULL);
134
ITEM(U64, uint64_t, 0);
135
ITEM(U64, uint64_t, 42);
136
ITEM(U64, uint64_t, 593023944758394234ULL);
137
ITEM(S64, int64_t, 9223372036854775807LL);
138
ITEM(S64, int64_t, -9223372036854775807LL - 1);
139
ITEM(S64, int64_t, 42);
140
ITEM(S64, int64_t, 21398723459873LL);
141
ITEM(S64, int64_t, -5848594593453453245LL);
144
uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
145
RTPrintf("tstSSM: Saved 1st item in %RI64 ns\n", u64Elapsed);
150
* Prepare state load operation.
152
* @returns VBox status code.
153
* @param pDevIns Device instance of the device which registered the data unit.
154
* @param pSSM SSM operation handle.
156
DECLCALLBACK(int) Item01Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
159
* Load the memory block.
161
char achTmp[sizeof(gachMem1)];
162
int rc = SSMR3GetMem(pSSM, achTmp, sizeof(gachMem1));
163
if (VBOX_FAILURE(rc))
165
RTPrintf("Item01: #1 - SSMR3GetMem -> %Vrc\n", rc);
172
rc = SSMR3GetStrZ(pSSM, achTmp, sizeof(achTmp));
173
if (VBOX_FAILURE(rc))
175
RTPrintf("Item01: #2 - SSMR3GetStrZ -> %Vrc\n", rc);
180
* Test the individual integer put functions to see that they all work.
181
* (Testcases are also known as "The Land of The Ugly Code"...)
183
#define ITEM(suff, type, val) \
186
rc = SSMR3Get##suff(pSSM, &var); \
187
if (VBOX_FAILURE(rc)) \
189
RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %Vrc\n", rc); \
194
RTPrintf("Item01: #" #suff " - SSMR3Get" #suff "(," #val ") -> %d returned wrong value!\n", rc); \
195
return VERR_GENERAL_FAILURE; \
198
/* copy & past with the load one! */
199
ITEM(U8, uint8_t, 0xff);
200
ITEM(U8, uint8_t, 0x0);
201
ITEM(U8, uint8_t, 1);
202
ITEM(U8, uint8_t, 42);
203
ITEM(U8, uint8_t, 230);
204
ITEM(S8, int8_t, -128);
205
ITEM(S8, int8_t, 127);
206
ITEM(S8, int8_t, 12);
207
ITEM(S8, int8_t, -76);
208
ITEM(U16, uint16_t, 0xffff);
209
ITEM(U16, uint16_t, 0x0);
210
ITEM(S16, int16_t, 32767);
211
ITEM(S16, int16_t, -32768);
212
ITEM(U32, uint32_t, 4294967295U);
213
ITEM(U32, uint32_t, 0);
214
ITEM(U32, uint32_t, 42);
215
ITEM(U32, uint32_t, 2342342344U);
216
ITEM(S32, int32_t, -2147483647-1);
217
ITEM(S32, int32_t, 2147483647);
218
ITEM(S32, int32_t, 42);
219
ITEM(S32, int32_t, 568459834);
220
ITEM(S32, int32_t, -58758999);
221
ITEM(U64, uint64_t, 18446744073709551615ULL);
222
ITEM(U64, uint64_t, 0);
223
ITEM(U64, uint64_t, 42);
224
ITEM(U64, uint64_t, 593023944758394234ULL);
225
ITEM(S64, int64_t, 9223372036854775807LL);
226
ITEM(S64, int64_t, -9223372036854775807LL - 1);
227
ITEM(S64, int64_t, 42);
228
ITEM(S64, int64_t, 21398723459873LL);
229
ITEM(S64, int64_t, -5848594593453453245LL);
237
* Execute state save operation.
239
* @returns VBox status code.
240
* @param pDevIns Device instance of the device which registered the data unit.
241
* @param pSSM SSM operation handle.
243
DECLCALLBACK(int) Item02Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
245
uint64_t u64Start = RTTimeNanoTS();
250
size_t cb = sizeof(gabBigMem);
251
int rc = SSMR3PutU32(pSSM, cb);
252
if (VBOX_FAILURE(rc))
254
RTPrintf("Item02: PutU32 -> %Vrc\n", rc);
259
* Put 8MB of memory to the file in 3 chunks.
261
uint8_t *pbMem = &gabBigMem[0];
262
size_t cbChunk = cb / 47;
263
rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
264
if (VBOX_FAILURE(rc))
266
RTPrintf("Item02: PutMem(,%p,%#x) -> %Vrc\n", pbMem, cbChunk, rc);
274
rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
275
if (VBOX_FAILURE(rc))
277
RTPrintf("Item02: PutMem(,%p,%#x) -> %Vrc\n", pbMem, cbChunk, rc);
285
rc = SSMR3PutMem(pSSM, pbMem, cbChunk);
286
if (VBOX_FAILURE(rc))
288
RTPrintf("Item02: PutMem(,%p,%#x) -> %Vrc\n", pbMem, cbChunk, rc);
292
uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
293
RTPrintf("tstSSM: Saved 2nd item in %RI64 ns\n", u64Elapsed);
298
* Prepare state load operation.
300
* @returns VBox status code.
301
* @param pDevIns Device instance of the device which registered the data unit.
302
* @param pSSM SSM operation handle.
304
DECLCALLBACK(int) Item02Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
310
int rc = SSMR3GetU32(pSSM, &cb);
311
if (VBOX_FAILURE(rc))
313
RTPrintf("Item02: SSMR3GetU32 -> %Vrc\n", rc);
316
if (cb != sizeof(gabBigMem))
318
RTPrintf("Item02: loaded size doesn't match the real thing. %#x != %#x\n", cb, sizeof(gabBigMem));
319
return VERR_GENERAL_FAILURE;
323
* Load the memory chunk by chunk.
325
uint8_t *pbMem = &gabBigMem[0];
327
size_t cbChunk = sizeof(achTmp);
332
cbChunk = sizeof(achTmp) - (cbChunk % 47);
335
rc = SSMR3GetMem(pSSM, &achTmp[0], cbChunk);
336
if (VBOX_FAILURE(rc))
338
RTPrintf("Item02: SSMR3GetMem(,,%#x) -> %d offset %#x\n", cbChunk, rc, pbMem - &gabBigMem[0]);
341
if (memcmp(achTmp, pbMem, cbChunk))
343
RTPrintf("Item02: compare failed. mem offset=%#x cbChunk=%#x\n", pbMem - &gabBigMem[0], cbChunk);
344
return VERR_GENERAL_FAILURE;
357
* Execute state save operation.
359
* @returns VBox status code.
360
* @param pDevIns Device instance of the device which registered the data unit.
361
* @param pSSM SSM operation handle.
363
DECLCALLBACK(int) Item03Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
365
uint64_t u64Start = RTTimeNanoTS();
371
int rc = SSMR3PutU32(pSSM, cb);
372
if (VBOX_FAILURE(rc))
374
RTPrintf("Item03: PutU32 -> %Vrc\n", rc);
379
* Put 512 MB page by page.
381
const uint8_t *pu8Org = &gabBigMem[0];
384
rc = SSMR3PutMem(pSSM, pu8Org, PAGE_SIZE);
385
if (VBOX_FAILURE(rc))
387
RTPrintf("Item03: PutMem(,%p,%#x) -> %Vrc\n", pu8Org, PAGE_SIZE, rc);
394
if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
395
pu8Org = &gabBigMem[0];
398
uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
399
RTPrintf("tstSSM: Saved 3rd item in %RI64 ns\n", u64Elapsed);
404
* Prepare state load operation.
406
* @returns VBox status code.
407
* @param pDevIns Device instance of the device which registered the data unit.
408
* @param pSSM SSM operation handle.
410
DECLCALLBACK(int) Item03Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
416
int rc = SSMR3GetU32(pSSM, &cb);
417
if (VBOX_FAILURE(rc))
419
RTPrintf("Item03: SSMR3GetU32 -> %Vrc\n", rc);
424
RTPrintf("Item03: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
425
return VERR_GENERAL_FAILURE;
429
* Load the memory page by page.
431
const uint8_t *pu8Org = &gabBigMem[0];
434
char achPage[PAGE_SIZE];
435
rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
436
if (VBOX_FAILURE(rc))
438
RTPrintf("Item03: SSMR3GetMem(,,%#x) -> %Vrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
441
if (memcmp(achPage, pu8Org, PAGE_SIZE))
443
RTPrintf("Item03: compare failed. mem offset=%#x\n", 512*_1M - cb);
444
return VERR_GENERAL_FAILURE;
450
if (pu8Org > &gabBigMem[sizeof(gabBigMem)])
451
pu8Org = &gabBigMem[0];
459
* Execute state save operation.
461
* @returns VBox status code.
462
* @param pDevIns Device instance of the device which registered the data unit.
463
* @param pSSM SSM operation handle.
465
DECLCALLBACK(int) Item04Save(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
467
uint64_t u64Start = RTTimeNanoTS();
473
int rc = SSMR3PutU32(pSSM, cb);
474
if (VBOX_FAILURE(rc))
476
RTPrintf("Item04: PutU32 -> %Vrc\n", rc);
481
* Put 512 MB page by page.
485
rc = SSMR3PutMem(pSSM, gabPage, PAGE_SIZE);
486
if (VBOX_FAILURE(rc))
488
RTPrintf("Item04: PutMem(,%p,%#x) -> %Vrc\n", gabPage, PAGE_SIZE, rc);
496
uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
497
RTPrintf("tstSSM: Saved 4th item in %RI64 ns\n", u64Elapsed);
502
* Prepare state load operation.
504
* @returns VBox status code.
505
* @param pDevIns Device instance of the device which registered the data unit.
506
* @param pSSM SSM operation handle.
508
DECLCALLBACK(int) Item04Load(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t u32Version)
514
int rc = SSMR3GetU32(pSSM, &cb);
515
if (VBOX_FAILURE(rc))
517
RTPrintf("Item04: SSMR3GetU32 -> %Vrc\n", rc);
522
RTPrintf("Item04: loaded size doesn't match the real thing. %#x != %#x\n", cb, 512*_1M);
523
return VERR_GENERAL_FAILURE;
527
* Load the memory page by page.
531
char achPage[PAGE_SIZE];
532
rc = SSMR3GetMem(pSSM, &achPage[0], PAGE_SIZE);
533
if (VBOX_FAILURE(rc))
535
RTPrintf("Item04: SSMR3GetMem(,,%#x) -> %Vrc offset %#x\n", PAGE_SIZE, rc, 512*_1M - cb);
538
if (memcmp(achPage, gabPage, PAGE_SIZE))
540
RTPrintf("Item04: compare failed. mem offset=%#x\n", 512*_1M - cb);
541
return VERR_GENERAL_FAILURE;
552
int main(int argc, char **argv)
555
* Init runtime and static data.
558
RTPrintf("tstSSM: TESTING...\n");
560
const char *pszFilename = "SSMTestSave#1";
563
* Create empty VM structure and init SSM.
566
int rc = SUPInit(NULL);
567
if (VBOX_SUCCESS(rc))
568
rc = SUPPageAlloc((sizeof(*pVM) + PAGE_SIZE - 1) >> PAGE_SHIFT, (void **)&pVM);
569
if (VBOX_FAILURE(rc))
571
RTPrintf("Fatal error: SUP Failure! rc=%Vrc\n", rc);
575
rc = STAMR3Init(pVM);
576
if (VBOX_FAILURE(rc))
578
RTPrintf("Fatal error: STAMR3Init failed! rc=%Vrc\n", rc);
584
if (VBOX_FAILURE(rc))
586
RTPrintf("Fatal error: SSMR3Init failed! rc=%Vrc\n", rc);
592
* Register a few callbacks.
594
rc = SSMR3Register(pVM, NULL, "SSM Testcase Data Item no.1 (all types)", 1, 0, 256,
595
NULL, Item01Save, NULL,
596
NULL, Item01Load, NULL);
597
if (VBOX_FAILURE(rc))
599
RTPrintf("SSMR3Register #1 -> %Vrc\n", rc);
603
rc = SSMR3Register(pVM, NULL, "SSM Testcase Data Item no.2 (rand mem)", 2, 0, _1M * 8,
604
NULL, Item02Save, NULL,
605
NULL, Item02Load, NULL);
606
if (VBOX_FAILURE(rc))
608
RTPrintf("SSMR3Register #2 -> %Vrc\n", rc);
612
rc = SSMR3Register(pVM, NULL, "SSM Testcase Data Item no.3 (big mem)", 0, 123, 512*_1M,
613
NULL, Item03Save, NULL,
614
NULL, Item03Load, NULL);
615
if (VBOX_FAILURE(rc))
617
RTPrintf("SSMR3Register #3 -> %Vrc\n", rc);
621
rc = SSMR3Register(pVM, NULL, "SSM Testcase Data Item no.4 (big zero mem)", 0, 42, 512*_1M,
622
NULL, Item04Save, NULL,
623
NULL, Item04Load, NULL);
624
if (VBOX_FAILURE(rc))
626
RTPrintf("SSMR3Register #4 -> %Vrc\n", rc);
633
uint64_t u64Start = RTTimeNanoTS();
634
rc = SSMR3Save(pVM, pszFilename, SSMAFTER_DESTROY, NULL, NULL);
635
if (VBOX_FAILURE(rc))
637
RTPrintf("SSMR3Save #1 -> %Vrc\n", rc);
640
uint64_t u64Elapsed = RTTimeNanoTS() - u64Start;
641
RTPrintf("tstSSM: Saved in %RI64 ns\n", u64Elapsed);
646
u64Start = RTTimeNanoTS();
647
rc = SSMR3Load(pVM, pszFilename, SSMAFTER_RESUME, NULL, NULL);
648
if (VBOX_FAILURE(rc))
650
RTPrintf("SSMR3Load #1 -> %Vrc\n", rc);
653
u64Elapsed = RTTimeNanoTS() - u64Start;
654
RTPrintf("tstSSM: Loaded in %RI64 ns\n", u64Elapsed);
659
u64Start = RTTimeNanoTS();
660
rc = SSMR3ValidateFile(pszFilename);
661
if (VBOX_FAILURE(rc))
663
RTPrintf("SSMR3ValidateFile #1 -> %Vrc\n", rc);
666
u64Elapsed = RTTimeNanoTS() - u64Start;
667
RTPrintf("tstSSM: Validated in %RI64 ns\n", u64Elapsed);
672
u64Start = RTTimeNanoTS();
674
rc = SSMR3Open(pszFilename, 0, &pSSM);
675
if (VBOX_FAILURE(rc))
677
RTPrintf("SSMR3Open #1 -> %Vrc\n", rc);
680
u64Elapsed = RTTimeNanoTS() - u64Start;
681
RTPrintf("tstSSM: Opened in %RI64 ns\n", u64Elapsed);
684
u64Start = RTTimeNanoTS();
685
rc = SSMR3Seek(pSSM, "some unit that doesn't exist", 0, NULL);
686
if (rc != VERR_SSM_UNIT_NOT_FOUND)
688
RTPrintf("SSMR3Seek #1 negative -> %Vrc\n", rc);
691
u64Elapsed = RTTimeNanoTS() - u64Start;
692
RTPrintf("tstSSM: Failed seek in %RI64 ns\n", u64Elapsed);
695
rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, NULL);
696
if (VBOX_FAILURE(rc))
698
RTPrintf("SSMR3Seek #1 unit 2-> %Vrc\n", rc);
701
uint32_t u32Version = 0xbadc0ded;
702
rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.2 (rand mem)", 0, &u32Version);
703
if (VBOX_FAILURE(rc))
705
RTPrintf("SSMR3Seek #1 unit 2-> %Vrc\n", rc);
708
u64Start = RTTimeNanoTS();
709
rc = Item02Load(NULL, pSSM, u32Version);
710
if (VBOX_FAILURE(rc))
712
RTPrintf("Item02Load #1 -> %Vrc\n", rc);
715
u64Elapsed = RTTimeNanoTS() - u64Start;
716
RTPrintf("tstSSM: Loaded 2nd item in %RI64 ns\n", u64Elapsed);
719
u32Version = 0xbadc0ded;
720
rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.1 (all types)", 0, &u32Version);
721
if (VBOX_FAILURE(rc))
723
RTPrintf("SSMR3Seek #1 unit 1 -> %Vrc\n", rc);
726
u64Start = RTTimeNanoTS();
727
rc = Item01Load(NULL, pSSM, u32Version);
728
if (VBOX_FAILURE(rc))
730
RTPrintf("Item01Load #1 -> %Vrc\n", rc);
733
u64Elapsed = RTTimeNanoTS() - u64Start;
734
RTPrintf("tstSSM: Loaded 1st item in %RI64 ns\n", u64Elapsed);
737
u32Version = 0xbadc0ded;
738
rc = SSMR3Seek(pSSM, "SSM Testcase Data Item no.3 (big mem)", 123, &u32Version);
739
if (VBOX_FAILURE(rc))
741
RTPrintf("SSMR3Seek #3 unit 1 -> %Vrc\n", rc);
744
u64Start = RTTimeNanoTS();
745
rc = Item03Load(NULL, pSSM, u32Version);
746
if (VBOX_FAILURE(rc))
748
RTPrintf("Item01Load #3 -> %Vrc\n", rc);
751
u64Elapsed = RTTimeNanoTS() - u64Start;
752
RTPrintf("tstSSM: Loaded 3rd item in %RI64 ns\n", u64Elapsed);
755
rc = SSMR3Close(pSSM);
756
if (VBOX_FAILURE(rc))
758
RTPrintf("SSMR3Close #1 -> %Vrc\n", rc);
762
RTPrintf("tstSSM: SUCCESS\n");