- Timestamp:
- Feb 14, 2007 9:35:02 AM (18 years ago)
- 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 1 1 /* $Id$ */ 2 2 /** @file 3 * InnoTek Portable Runtime - File System, Generic Stubs.3 * InnoTek Portable Runtime - Random Numbers and Byte Streams, Generic Stubs. 4 4 */ 5 5 … … 24 24 * Header Files * 25 25 *******************************************************************************/ 26 #define LOG_GROUP RTLOGGROUP_FS 27 28 #include <iprt/fs.h> 26 #include <iprt/rand.h> 29 27 #include <iprt/err.h> 30 #include <iprt/log.h> 31 #include <iprt/assert.h> 32 #include "internal/fs.h" 28 #include "internal/rand.h" 33 29 34 30 35 36 RTR3DECL(int) RTFsQuerySizes(const char *pszFsPath, RTFOFF *pcbTotal, RTFOFF *pcbFree, 37 uint32_t *pcbBlock, uint32_t *pcbSector) 31 void rtRandLazyInitNative(void) 38 32 { 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;49 33 } 50 34 51 35 52 RTR3DECL(int) RTFsQuerySerial(const char *pszFsPath, uint32_t *pu32Serial)36 int rtRandGenBytesNative(void *pv, size_t cb) 53 37 { 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; 58 41 } 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 1 1 /* $Id$ */ 2 2 /** @file 3 * InnoTek Portable Runtime - Internal RT Timeheader3 * InnoTek Portable Runtime - Internal RTRand header 4 4 */ 5 5 … … 20 20 */ 21 21 22 #ifndef __internal_ time_h__23 #define __internal_ time_h__22 #ifndef __internal_rand_h__ 23 #define __internal_rand_h__ 24 24 25 25 #include <iprt/types.h> … … 27 27 __BEGIN_DECLS 28 28 29 #ifdef IN_RING3 29 /** 30 * Initialize OS facilities for generating random bytes. 31 */ 32 void rtRandLazyInitNative(void); 30 33 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 */ 41 int rtRandGenBytesNative(void *pv, size_t cb); 33 42 34 #endif 43 void rtRandGenBytesFallback(void *pv, size_t cb); 35 44 36 45 __END_DECLS -
trunk/src/VBox/Runtime/misc/rand.cpp
r327 r890 28 28 #include <iprt/asm.h> 29 29 #include <iprt/err.h> 30 #include <iprt/assert.h> 31 #include <iprt/thread.h> 30 32 #include "internal/rand.h" 31 32 33 33 34 … … 36 37 *******************************************************************************/ 37 38 /** Lazy init. */ 38 static volatile bool g_fInitialized = false; 39 40 39 static volatile bool g_fInitialized = false; 40 /** The context variable for the fallback path. */ 41 static uint32_t g_u32Ctx; 42 43 44 /******************************************************************************* 45 * Internal Functions * 46 *******************************************************************************/ 47 static uint32_t rtRandGenBytesFallbackU31(uint32_t *pCtx); 48 49 50 /** 51 * Lazy initialization of the native and fallback random byte sources. 52 * 53 */ 41 54 static void rtRandLazyInit(void) 42 55 { 56 /* 57 * Seed the fallback random code. 58 */ 59 g_u32Ctx = (uint32_t)(ASMReadTSC() >> 8); 60 43 61 /* 44 62 * Call host specific init. 45 63 */ 46 47 /* 48 * Seed the fallback random code. 49 */ 64 rtRandLazyInitNative(); 65 g_fInitialized = true; 50 66 } 51 67 … … 59 75 static void rtRandGenBytes(void *pv, size_t cb) 60 76 { 77 Assert(cb); 61 78 if (RT_UNLIKELY(!g_fInitialized)) 62 79 rtRandLazyInit(); … … 64 81 int rc = rtRandGenBytesNative(pv, cb); 65 82 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 */ 93 RTDECL(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 */ 107 RTDECL(int32_t) RTRandS32Ex(int32_t i32First, int32_t i32Last) 73 108 { 74 109 /* get 4 random bytes. */ … … 83 118 /* squeeze it into the requested range. */ 84 119 uint32_t offLast = i32Last - i32First; 85 if (u.off > offLast s)120 if (u.off > offLast) 86 121 { 87 122 do 88 123 { 89 124 u.off >>= 1; 90 } while (u.off > offLast s);125 } while (u.off > offLast); 91 126 } 92 127 return i32First + u.off; … … 94 129 95 130 131 /** 132 * Generate a 32-bit signed random number. 133 * 134 * @returns The random number. 135 */ 96 136 RTDECL(int32_t) RTRandS32(void) 97 137 { … … 100 140 101 141 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 */ 102 149 RTDECL(uint32_t) RTRandU32Ex(uint32_t u32First, uint32_t u32Last) 103 150 { … … 113 160 /* squeeze it into the requested range. */ 114 161 const uint32_t offLast = u32Last - u32First; 115 if (u.off > offLast s)162 if (u.off > offLast) 116 163 { 117 164 do 118 165 { 119 166 u.off >>= 1; 120 } while (u.off > offLast s);167 } while (u.off > offLast); 121 168 } 122 169 return u32First + u.off; … … 124 171 125 172 173 /** 174 * Generate a 32-bit unsigned random number. 175 * 176 * @returns The random number. 177 */ 126 178 RTDECL(uint32_t) RTRandU32(void) 127 179 { … … 130 182 131 183 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 */ 191 RTDECL(int64_t) RTRandS64Ex(int64_t i64First, int64_t i64Last) 133 192 { 134 193 /* get 8 random bytes. */ … … 136 195 { 137 196 uint64_t off; 138 uint8_t ab[ 4];197 uint8_t ab[8]; 139 198 } u; 140 199 rtRandGenBytes(&u.ab, sizeof(u)); 141 200 142 143 201 /* squeeze it into the requested range. */ 144 202 uint64_t offLast = i64Last - i64First; 145 if (u.off > offLast s)203 if (u.off > offLast) 146 204 { 147 205 do 148 206 { 149 207 u.off >>= 1; 150 } while (u.off > offLast s);208 } while (u.off > offLast); 151 209 } 152 210 return i64First + u.off; … … 154 212 155 213 214 /** 215 * Generate a 64-bit signed random number. 216 * 217 * @returns The random number. 218 */ 156 219 RTDECL(int64_t) RTRandS64(void) 157 220 { … … 160 223 161 224 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 */ 162 232 RTDECL(uint64_t) RTRandU64Ex(uint64_t u64First, uint64_t u64Last) 163 233 { 164 /* get 4random bytes. */234 /* get 8 random bytes. */ 165 235 union 166 236 { 167 237 uint64_t off; 168 uint8_t ab[ 4];238 uint8_t ab[8]; 169 239 } u; 170 240 rtRandGenBytes(&u.ab, sizeof(u)); 171 241 172 173 242 /* squeeze it into the requested range. */ 174 243 const uint64_t offLast = u64Last - u64First; 175 if (u.off > offLast s)244 if (u.off > offLast) 176 245 { 177 246 do 178 247 { 179 248 u.off >>= 1; 180 } while (u.off > offLast s);249 } while (u.off > offLast); 181 250 } 182 251 return u64First + u.off; … … 184 253 185 254 255 /** 256 * Generate a 64-bit unsigned random number. 257 * 258 * @returns The random number. 259 */ 186 260 RTDECL(uint64_t) RTRandU64(void) 187 261 { … … 190 264 191 265 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 */ 272 void 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 */ 346 static 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.