VirtualBox

Changeset 890 in vbox for trunk/src


Ignore:
Timestamp:
Feb 14, 2007 9:35:02 AM (18 years ago)
Author:
vboxsync
Message:

RTRand API (feel free to improve the fallback code).

Location:
trunk/src/VBox/Runtime
Files:
1 edited
2 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/generic/rand-stubs-generic.cpp

    r839 r890  
    11/* $Id$ */
    22/** @file
    3  * InnoTek Portable Runtime - File System, Generic Stubs.
     3 * InnoTek Portable Runtime - Random Numbers and Byte Streams, Generic Stubs.
    44 */
    55
     
    2424*   Header Files                                                               *
    2525*******************************************************************************/
    26 #define LOG_GROUP RTLOGGROUP_FS
    27 
    28 #include <iprt/fs.h>
     26#include <iprt/rand.h>
    2927#include <iprt/err.h>
    30 #include <iprt/log.h>
    31 #include <iprt/assert.h>
    32 #include "internal/fs.h"
     28#include "internal/rand.h"
    3329
    3430
    35 
    36 RTR3DECL(int) RTFsQuerySizes(const char *pszFsPath, RTFOFF *pcbTotal, RTFOFF *pcbFree,
    37                              uint32_t *pcbBlock, uint32_t *pcbSector)
     31void rtRandLazyInitNative(void)
    3832{
    39     if (pcbTotal)
    40         *pcbTotal = _2G;
    41     if (pcbFree)
    42         *pcbFree = _1G;
    43     if (pcbBlock)
    44         *pcbBlock = _4K;
    45     if (pcbSector)
    46         *pcbSector = 512;
    47     LogFlow(("RTFsQuerySizes: success stub!\n"));
    48     return VINF_SUCCESS;
    4933}
    5034
    5135
    52 RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)
     36int rtRandGenBytesNative(void *pv, size_t cb)
    5337{
    54     if (pu32Serial)
    55         *pu32Serial = 0xc0ffee;
    56     LogFlow(("RTFsQuerySerial: success stub!\n"));
    57     return VINF_SUCCESS;
     38    NOREF(pv);
     39    NOREF(cb);
     40    return VERR_NOT_SUPPORTED;
    5841}
    59 
    60 
    61 RTR3DECL(int) RTFsQueryProperties(const char *pszFsPath, PRTFSPROPERTIES pProperties)
    62 {
    63     pProperties->cbMaxComponent = 255;
    64     pProperties->fCaseSensitive = true;
    65     pProperties->fCompressed = false;
    66     pProperties->fFileCompression = false;
    67     pProperties->fReadOnly = false;
    68     pProperties->fRemote = false;
    69     pProperties->fSupportsUnicode = true;
    70     LogFlow(("RTFsQueryProperties: success stub!\n"));
    71     return VINF_SUCCESS;
    72 }
    73 
     42                   
  • trunk/src/VBox/Runtime/include/internal/rand.h

    r839 r890  
    11/* $Id$ */
    22/** @file
    3  * InnoTek Portable Runtime - Internal RTTime header
     3 * InnoTek Portable Runtime - Internal RTRand header
    44 */
    55
     
    2020 */
    2121
    22 #ifndef __internal_time_h__
    23 #define __internal_time_h__
     22#ifndef __internal_rand_h__
     23#define __internal_rand_h__
    2424
    2525#include <iprt/types.h>
     
    2727__BEGIN_DECLS
    2828
    29 #ifdef IN_RING3
     29/**
     30 * Initialize OS facilities for generating random bytes.
     31 */
     32void rtRandLazyInitNative(void);
    3033
    31 extern uint64_t g_u64ProgramStartNanoTS;
    32 extern uint64_t g_u64ProgramStartMilliTS;
     34/**
     35 * Generate random bytes using OS facilities.
     36 *
     37 * @returns VINF_SUCCESS on success, some error status code on failure.
     38 * @param   pv      Where to store the random bytes.
     39 * @param   cb      How many random bytes to store.
     40 */
     41int rtRandGenBytesNative(void *pv, size_t cb);
    3342
    34 #endif
     43void rtRandGenBytesFallback(void *pv, size_t cb);
    3544
    3645__END_DECLS
  • trunk/src/VBox/Runtime/misc/rand.cpp

    r327 r890  
    2828#include <iprt/asm.h>
    2929#include <iprt/err.h>
     30#include <iprt/assert.h>
     31#include <iprt/thread.h>
    3032#include "internal/rand.h"
    31 
    3233
    3334
     
    3637*******************************************************************************/
    3738/** Lazy init. */
    38 static volatile bool g_fInitialized = false;
    39 
    40 
     39static volatile bool    g_fInitialized = false;
     40/** The context variable for the fallback path. */
     41static uint32_t         g_u32Ctx;
     42
     43
     44/*******************************************************************************
     45*   Internal Functions                                                         *
     46*******************************************************************************/
     47static uint32_t rtRandGenBytesFallbackU31(uint32_t *pCtx);
     48
     49
     50/**
     51 * Lazy initialization of the native and fallback random byte sources.
     52 *
     53 */
    4154static void rtRandLazyInit(void)
    4255{
     56    /*
     57     * Seed the fallback random code.
     58     */
     59    g_u32Ctx = (uint32_t)(ASMReadTSC() >> 8);
     60
    4361    /*
    4462     * Call host specific init.
    4563     */
    46 
    47     /*
    48      * Seed the fallback random code.
    49      */
     64    rtRandLazyInitNative();
     65    g_fInitialized = true;
    5066}
    5167
     
    5975static void rtRandGenBytes(void *pv, size_t cb)
    6076{
     77    Assert(cb);
    6178    if (RT_UNLIKELY(!g_fInitialized))
    6279        rtRandLazyInit();
     
    6481    int rc = rtRandGenBytesNative(pv, cb);
    6582    if (RT_FAILURE(rc))
    66     {
    67         /* fallback */
    68     }
    69 }
    70 
    71 
    72 RTDECL(int32_t) RTRandS32Ex(uint32_t i32First, int32_t i32Last)
     83        rtRandGenBytesFallback(pv, cb);
     84}
     85
     86
     87/**
     88 * Fills a buffer with random bytes.
     89 *
     90 * @param   pv  Where to store the random bytes.
     91 * @param   cb  Number of bytes to generate.
     92 */
     93RTDECL(void) RTRandBytes(void *pv, size_t cb)
     94{
     95    if (cb)
     96        rtRandGenBytes(pv, cb);
     97}
     98
     99
     100/**
     101 * Generate a 32-bit signed random number in the set [i32First..i32Last].
     102 *
     103 * @returns The random number.
     104 * @param   i32First    First number in the set.
     105 * @param   i32Last     Last number in the set.
     106 */
     107RTDECL(int32_t) RTRandS32Ex(int32_t i32First, int32_t i32Last)
    73108{
    74109    /* get 4 random bytes. */
     
    83118    /* squeeze it into the requested range. */
    84119    uint32_t offLast = i32Last - i32First;
    85     if (u.off > offLasts)
     120    if (u.off > offLast)
    86121    {
    87122        do
    88123        {
    89124            u.off >>= 1;
    90         } while (u.off > offLasts);
     125        } while (u.off > offLast);
    91126    }
    92127    return i32First + u.off;
     
    94129
    95130
     131/**
     132 * Generate a 32-bit signed random number.
     133 *
     134 * @returns The random number.
     135 */
    96136RTDECL(int32_t) RTRandS32(void)
    97137{
     
    100140
    101141
     142/**
     143 * Generate a 32-bit unsigned random number in the set [u32First..u32Last].
     144 *
     145 * @returns The random number.
     146 * @param   u32First    First number in the set.
     147 * @param   u32Last     Last number in the set.
     148 */
    102149RTDECL(uint32_t) RTRandU32Ex(uint32_t u32First, uint32_t u32Last)
    103150{
     
    113160    /* squeeze it into the requested range. */
    114161    const uint32_t offLast = u32Last - u32First;
    115     if (u.off > offLasts)
     162    if (u.off > offLast)
    116163    {
    117164        do
    118165        {
    119166            u.off >>= 1;
    120         } while (u.off > offLasts);
     167        } while (u.off > offLast);
    121168    }
    122169    return u32First + u.off;
     
    124171
    125172
     173/**
     174 * Generate a 32-bit unsigned random number.
     175 *
     176 * @returns The random number.
     177 */
    126178RTDECL(uint32_t) RTRandU32(void)
    127179{
     
    130182
    131183
    132 RTDECL(int64_t) RTRandS64Ex(uint32_t i64First, int64_t i64Last)
     184/**
     185 * Generate a 32-bit signed random number in the set [i32First..i32Last].
     186 *
     187 * @returns The random number.
     188 * @param   i32First    First number in the set.
     189 * @param   i32Last     Last number in the set.
     190 */
     191RTDECL(int64_t) RTRandS64Ex(int64_t i64First, int64_t i64Last)
    133192{
    134193    /* get 8 random bytes. */
     
    136195    {
    137196        uint64_t    off;
    138         uint8_t     ab[4];
     197        uint8_t     ab[8];
    139198    } u;
    140199    rtRandGenBytes(&u.ab, sizeof(u));
    141200
    142 
    143201    /* squeeze it into the requested range. */
    144202    uint64_t offLast = i64Last - i64First;
    145     if (u.off > offLasts)
     203    if (u.off > offLast)
    146204    {
    147205        do
    148206        {
    149207            u.off >>= 1;
    150         } while (u.off > offLasts);
     208        } while (u.off > offLast);
    151209    }
    152210    return i64First + u.off;
     
    154212
    155213
     214/**
     215 * Generate a 64-bit signed random number.
     216 *
     217 * @returns The random number.
     218 */
    156219RTDECL(int64_t) RTRandS64(void)
    157220{
     
    160223
    161224
     225/**
     226 * Generate a 64-bit unsigned random number in the set [u64First..u64Last].
     227 *
     228 * @returns The random number.
     229 * @param   u64First    First number in the set.
     230 * @param   u64Last     Last number in the set.
     231 */
    162232RTDECL(uint64_t) RTRandU64Ex(uint64_t u64First, uint64_t u64Last)
    163233{
    164     /* get 4 random bytes. */
     234    /* get 8 random bytes. */
    165235    union
    166236    {
    167237        uint64_t    off;
    168         uint8_t     ab[4];
     238        uint8_t     ab[8];
    169239    } u;
    170240    rtRandGenBytes(&u.ab, sizeof(u));
    171241
    172 
    173242    /* squeeze it into the requested range. */
    174243    const uint64_t offLast = u64Last - u64First;
    175     if (u.off > offLasts)
     244    if (u.off > offLast)
    176245    {
    177246        do
    178247        {
    179248            u.off >>= 1;
    180         } while (u.off > offLasts);
     249        } while (u.off > offLast);
    181250    }
    182251    return u64First + u.off;
     
    184253
    185254
     255/**
     256 * Generate a 64-bit unsigned random number.
     257 *
     258 * @returns The random number.
     259 */
    186260RTDECL(uint64_t) RTRandU64(void)
    187261{
     
    190264
    191265
     266/**
     267 * Fallback random byte source.
     268 *
     269 * @param   pv  Where to store the random bytes.
     270 * @param   cb  Number of bytes to generate.
     271 */
     272void rtRandGenBytesFallback(void *pv, size_t cb)
     273{
     274    uint8_t *pb = (uint8_t *)pv;
     275    for (unsigned i = 0;; i++)
     276    {
     277        uint32_t u32 = rtRandGenBytesFallbackU31(&g_u32Ctx);
     278
     279        *pb++ = (uint8_t)u32;
     280        if (!--cb)
     281            break;
     282
     283        u32 >>= 8;
     284        *pb++ = (uint8_t)u32;
     285        if (!--cb)
     286            break;
     287
     288        u32 >>= 8;
     289        *pb++ = (uint8_t)u32;
     290        if (!--cb)
     291            break;
     292
     293        /* Is this really a good idea? */
     294        if (!(i % 3))
     295        {
     296            if (i)
     297                RTThreadYield();
     298            *pb++ = (uint8_t)ASMReadTSC();
     299            if (!--cb)
     300                break;
     301        }
     302    }
     303
     304}
     305
     306
     307/*-
     308 * Copyright (c) 1990, 1993
     309 *      The Regents of the University of California.  All rights reserved.
     310 *
     311 * Redistribution and use in source and binary forms, with or without
     312 * modification, are permitted provided that the following conditions
     313 * are met:
     314 * 1. Redistributions of source code must retain the above copyright
     315 *    notice, this list of conditions and the following disclaimer.
     316 * 2. Redistributions in binary form must reproduce the above copyright
     317 *    notice, this list of conditions and the following disclaimer in the
     318 *    documentation and/or other materials provided with the distribution.
     319 * 4. Neither the name of the University nor the names of its contributors
     320 *    may be used to endorse or promote products derived from this software
     321 *    without specific prior written permission.
     322 *
     323 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     324 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     325 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     326 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     327 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     328 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     329 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     330 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     331 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     332 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     333 * SUCH DAMAGE.
     334 */
     335
     336/* The core of:
     337__FBSDID("$FreeBSD: /repoman/r/ncvs/src/lib/libc/stdlib/rand.c,v 1.16 2007/01/09 00:28:10 imp Exp $");
     338*/
     339
     340/**
     341 * Generates an unsigned 31 bit pseudo random number.
     342 *
     343 * @returns pseudo random number.
     344 * @param   pCtx    The context.
     345 */
     346static uint32_t rtRandGenBytesFallbackU31(uint32_t *pCtx)
     347{
     348    /*
     349     * Compute x = (7^5 * x) mod (2^31 - 1)
     350     * without overflowing 31 bits:
     351     *      (2^31 - 1) = 127773 * (7^5) + 2836
     352     *
     353     * From "Random number generators: good ones are hard to find",  Park and
     354     * Miller, Communications of the ACM, vol. 31, no. 10, October 1988, p. 1195.
     355     */
     356    uint32_t Ctx = *pCtx;
     357    if (!Ctx) /* must not be zero. */
     358        Ctx = 0x20070212;
     359    uint32_t Hi = Ctx / 127773;
     360    uint32_t Lo = Ctx % 127773;
     361    int32_t x = 16807 * Lo  -  2836 * Hi;
     362    if (x < 0)
     363        x += INT32_MAX;
     364    *pCtx = x;
     365    return x % INT32_MAX;
     366}
     367
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