VirtualBox

Changeset 9264 in vbox for trunk/src/VBox


Ignore:
Timestamp:
May 30, 2008 7:33:43 PM (17 years ago)
Author:
vboxsync
Message:

Changed pseudo random generator initialization to use a single 32-bit seed. Fixed the bug that caused hanging on duplicates.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/testcase/tstVD.cpp

    r9262 r9264  
    244244
    245245/**
    246  * @todo I failed to make Windows' sscanf to process %llx format
    247  *       specification properly. If someone knows how to do it
    248  *       please re-write the format spec the way it stays the
    249  *       same on all platforms. We probably need RTStrScanf()
    250  *       anyway.
    251  */
    252 
    253 #define RT_PRND_SEED_FSPEC_OUT "%016llx#%016llx#%016llx#%016llx#%016llx#%08x#%08x"
    254 #ifdef RT_OS_WINDOWS
    255 # define RT_PRND_SEED_FSPEC_IN "%I64x#%I64x#%I64x#%I64x#%I64x#%x#%x"
    256 #else
    257 # define RT_PRND_SEED_FSPEC_IN "%llx#%llx#%llx#%llx#%llx#%x#%x"
    258 #endif
    259 
    260 /**
    261246 * Initialize seeds.
    262247 * 
     
    267252 * for seeds, the period of the RNG.
    268253 */
    269 RTDECL(int) RTPRandInit(PRNDCTX pCtx, const char *pszSeedInfo)
    270 {
    271     if (pszSeedInfo)
    272     {
    273         int nFieldsRead = sscanf(pszSeedInfo, RT_PRND_SEED_FSPEC_IN,
    274                &pCtx->x, &pCtx->y, &pCtx->z, &pCtx->w, &pCtx->c, &pCtx->u32x, &pCtx->u32y);
    275         if (nFieldsRead != 7 || pCtx->x > UINT64_MAX-1 || pCtx->y > UINT64_MAX-1 ||
    276             pCtx->z > UINT64_MAX-1 || pCtx->w > UINT64_MAX-1 ||
    277             pCtx->c > ((1ull << 62) + (1ull << 47) + 1) || pCtx->u32y == 0)
    278             return VERR_INVALID_PARAMETER;
    279     }
    280     else
    281     {
    282         pCtx->x = RTRandU64Ex(0, UINT64_MAX-1);
    283         pCtx->y = RTRandU64Ex(0, UINT64_MAX-1);
    284         pCtx->z = RTRandU64Ex(0, UINT64_MAX-1);
    285         pCtx->w = RTRandU64Ex(0, UINT64_MAX-1);
    286         pCtx->c = RTRandU64Ex(0, (1ull << 62) + (1ull << 47) + 1);
    287         pCtx->u32x = RTRandU32();
    288         pCtx->u32y = RTRandU32Ex(1, UINT32_MAX);
    289     }
     254RTDECL(int) RTPRandInit(PRNDCTX pCtx, uint32_t u32Seed)
     255{
     256    if (u32Seed == 0)
     257        u32Seed = (uint32_t)(ASMReadTSC() >> 8);
     258    /* Zero is not a good seed. */
     259    if (u32Seed == 0)
     260        u32Seed = 362436069;
     261    pCtx->x = u32Seed;
     262    pCtx->y = 17280675555674358941ll;
     263    pCtx->z = 6376492577913983186ll;
     264    pCtx->w = 9064188857900113776ll;
     265    pCtx->c = 123456789;
     266    pCtx->u32x = 2282008;
     267    pCtx->u32y = u32Seed;
    290268    return VINF_SUCCESS;
    291269}
    292270
    293 RTDECL(int) RTPRandGetSeedInfo(PRNDCTX pCtx, char **ppszSeedInfo)
    294 {
    295     return RTStrAPrintf(ppszSeedInfo, RT_PRND_SEED_FSPEC_OUT,
    296                           pCtx->x, pCtx->y, pCtx->z, pCtx->w, pCtx->c, pCtx->u32x, pCtx->u32y);
     271RTDECL(uint32_t) RTPRandGetSeedInfo(PRNDCTX pCtx)
     272{
     273    return pCtx->u32y;
    297274}
    298275
     
    384361typedef struct Segment *PSEGMENT;
    385362
    386 static void initializeRandomGenerator(PRNDCTX pCtx, const char *pszSeedInfo)
    387 {
    388     int rc = RTPRandInit(pCtx, pszSeedInfo);
    389     if (VBOX_FAILURE(rc))
    390     {
     363static void initializeRandomGenerator(PRNDCTX pCtx, uint32_t u32Seed)
     364{
     365    int rc = RTPRandInit(pCtx, u32Seed);
     366    if (VBOX_FAILURE(rc))
    391367        RTPrintf("ERROR: Failed to initialize random generator. RC=%Vrc\n", rc);
    392     }
    393368    else
    394369    {
    395         char *pszNewSeedInfo = NULL;
    396         rc = RTPRandGetSeedInfo(pCtx, &pszNewSeedInfo);
    397         if (VBOX_FAILURE(rc))
    398         {
    399             RTPrintf("ERROR: Failed to get seed values. RC=%Vrc\n", rc);
    400         }
    401         else
    402         {
    403             RTPrintf("INFO: Random generator seed used: %s\n", pszNewSeedInfo);
    404             RTMemFree(pszNewSeedInfo);
    405         }
    406     }
    407    
     370        RTPrintf("INFO: Random generator seed used: %x\n", RTPRandGetSeedInfo(pCtx));   
     371        RTLogPrintf("INFO: Random generator seed used: %x\n", RTPRandGetSeedInfo(pCtx));   
     372    }
    408373}
    409374
     
    420385    for (i = 0; i < nSegments; i++)
    421386    {
    422         bool fDuplicateFound = false;
     387        bool fDuplicateFound;
    423388        do
    424389        {
    425390            pSegment[i].u64Offset = RTPRandU64Ex(pCtx, 0, u64DiskSize / u32SectorSize - 1) * u32SectorSize;
     391            fDuplicateFound = false;
    426392            for (uint32_t j = 0; j < i; j++)
    427393                if (pSegment[i].u64Offset == pSegment[j].u64Offset)
     394                {
    428395                    fDuplicateFound = true;
     396                    break;
     397                }
    429398        } while (fDuplicateFound);
    430399    }
     
    519488                             pSegment->u64Offset, pSegment->u32Length, i, ((uint8_t*)pvBuf)[i],
    520489                             pSegment->u8Value);
     490                    RTLogPrintf("ERROR: Segment at %Lx of %d bytes is corrupt at offset %x (found %x instead of %x)\n",
     491                             pSegment->u64Offset, pSegment->u32Length, i, ((uint8_t*)pvBuf)[i],
     492                             pSegment->u8Value);
    521493                    return VERR_INTERNAL_ERROR;
    522494                }
     
    531503                                     const char *pszBaseFilename,
    532504                                     const char *pszDiffFilename,
    533                                      const char *pszSeedInfo)
     505                                     uint32_t u32Seed)
    534506{
    535507    int rc;
     
    592564
    593565    RNDCTX ctx;
    594     initializeRandomGenerator(&ctx, pszSeedInfo);
     566    initializeRandomGenerator(&ctx, u32Seed);
    595567    generateRandomSegments(&ctx, paBaseSegments, nSegments, _1M, u64DiskSize, u32SectorSize, 0u, 127u);
    596568    generateRandomSegments(&ctx, paDiffSegments, nSegments, _1M, u64DiskSize, u32SectorSize, 128u, 255u);
    597569
    598     PSEGMENT pSegment;
    599     /*RTPrintf("Base segments:\n");
     570    /*PSEGMENT pSegment;
     571    RTPrintf("Base segments:\n");
    600572    for (pSegment = paBaseSegments; pSegment->u32Length; pSegment++)
    601573        RTPrintf("off: %08Lx len: %04x val: %02x\n", pSegment->u64Offset, pSegment->u32Length, pSegment->u8Value);*/
     
    641613    int rc;
    642614
    643     const char *pszSeedInfo = NULL;
     615    uint32_t u32Seed = 0; // Means choose random
    644616
    645617    if (argc > 1)
    646         pszSeedInfo = argv[1];
     618        if (sscanf(argv[1], "%x", &u32Seed) != 1)
     619        {
     620            RTPrintf("ERROR: Invalid parameter %s. Valid usage is %s <32-bit seed>.\n",
     621                     argv[1], argv[0]);
     622            return 1;
     623        }
    647624
    648625    RTR3Init();
     
    708685    }
    709686
    710     rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", pszSeedInfo);
     687    rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", u32Seed);
    711688    if (VBOX_FAILURE(rc))
    712689    {
     
    714691        g_cErrors++;
    715692    }
    716     rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", pszSeedInfo);
     693    rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", u32Seed);
    717694    if (VBOX_FAILURE(rc))
    718695    {
     
    720697        g_cErrors++;
    721698    }
    722     rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", pszSeedInfo);
     699    rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", u32Seed);
    723700    if (VBOX_FAILURE(rc))
    724701    {
     
    726703        g_cErrors++;
    727704    }
    728     rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", pszSeedInfo);
     705    rc = tstVDOpenCreateWriteMerge("VMDK", "tmpVDBase.vmdk", "tmpVDDiff.vmdk", u32Seed);
    729706    if (VBOX_FAILURE(rc))
    730707    {
     
    743720    RTFileDelete("tmpVDDiff.vmdk");
    744721#if 0
    745     rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", pszSeedInfo);
     722    rc = tstVDOpenCreateWriteMerge("VDI", "tmpVDBase.vdi", "tmpVDDiff.vdi", u32Seed);
    746723    if (VBOX_FAILURE(rc))
    747724    {
Note: See TracChangeset for help on using the changeset viewer.

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