Module: wine Branch: refs/heads/master Commit: ad8cb6133edce109406be63c1425899a90fa6146 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=ad8cb6133edce109406be63c...
Author: Alexandre Julliard julliard@winehq.org Date: Sat Jan 14 17:27:28 2006 +0100
msvcrt: Reimplement rand() and srand() to use per-thread data for the random seed.
---
dlls/msvcrt/misc.c | 16 +++++++++++++++- dlls/msvcrt/msvcrt.h | 2 ++ dlls/msvcrt/msvcrt.spec | 2 +- dlls/msvcrt/tests/headers.c | 1 + dlls/msvcrt/thread.c | 1 + 5 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcrt/misc.c b/dlls/msvcrt/misc.c index 83f798d..6455e39 100644 --- a/dlls/msvcrt/misc.c +++ b/dlls/msvcrt/misc.c @@ -39,11 +39,25 @@ void _beep( unsigned int freq, unsigned }
/********************************************************************* + * srand (MSVCRT.@) + */ +void MSVCRT_srand( unsigned int seed ) +{ + thread_data_t *data = msvcrt_get_thread_data(); + data->random_seed = seed; +} + +/********************************************************************* * rand (MSVCRT.@) */ int MSVCRT_rand(void) { - return (rand() & 0x7fff); + thread_data_t *data = msvcrt_get_thread_data(); + + /* this is the algorithm used by MSVC, according to + * http://en.wikipedia.org/wiki/List_of_pseudorandom_number_generators */ + data->random_seed = data->random_seed * 214013 + 2531011; + return (data->random_seed >> 16) & MSVCRT_RAND_MAX; }
/********************************************************************* diff --git a/dlls/msvcrt/msvcrt.h b/dlls/msvcrt/msvcrt.h index 9923def..2502d4b 100644 --- a/dlls/msvcrt/msvcrt.h +++ b/dlls/msvcrt/msvcrt.h @@ -93,6 +93,7 @@ extern DWORD msvcrt_tls_index; struct __thread_data { int thread_errno; unsigned long thread_doserrno; + unsigned int random_seed; /* seed for rand() */ char *strtok_next; /* next ptr for strtok() */ unsigned char *mbstok_next; /* next ptr for mbstok() */ MSVCRT_wchar_t *wcstok_next; /* next ptr for wcstok() */ @@ -375,6 +376,7 @@ struct MSVCRT__stati64 { #define MSVCRT_WEOF (MSVCRT_wint_t)(0xFFFF) #define MSVCRT_EOF (-1) #define MSVCRT_TMP_MAX 0x7fff +#define MSVCRT_RAND_MAX 0x7fff #define MSVCRT_BUFSIZ 512
#define MSVCRT_STDIN_FILENO 0 diff --git a/dlls/msvcrt/msvcrt.spec b/dlls/msvcrt/msvcrt.spec index 4620dff..a24f11b 100644 --- a/dlls/msvcrt/msvcrt.spec +++ b/dlls/msvcrt/msvcrt.spec @@ -695,7 +695,7 @@ @ cdecl sinh(double) @ varargs sprintf(ptr str) MSVCRT_sprintf @ cdecl sqrt(double) -@ cdecl srand(long) +@ cdecl srand(long) MSVCRT_srand @ varargs sscanf(str str) MSVCRT_sscanf @ cdecl strcat(str str) @ cdecl strchr(str long) diff --git a/dlls/msvcrt/tests/headers.c b/dlls/msvcrt/tests/headers.c index a25ce01..840212a 100644 --- a/dlls/msvcrt/tests/headers.c +++ b/dlls/msvcrt/tests/headers.c @@ -303,6 +303,7 @@ static void test_defines(void) CHECK_DEF(WEOF); CHECK_DEF(EOF); CHECK_DEF(TMP_MAX); + CHECK_DEF(RAND_MAX); CHECK_DEF(BUFSIZ); CHECK_DEF(STDIN_FILENO); CHECK_DEF(STDOUT_FILENO); diff --git a/dlls/msvcrt/thread.c b/dlls/msvcrt/thread.c index 262aa57..3362b4f 100644 --- a/dlls/msvcrt/thread.c +++ b/dlls/msvcrt/thread.c @@ -44,6 +44,7 @@ thread_data_t *msvcrt_get_thread_data(vo if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) _amsg_exit( _RT_THREAD ); if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD ); + ptr->random_seed = 1; } SetLastError( err ); return ptr;