Alexandre Julliard : msvcrt: Reimplement rand() and srand() to use per-thread data for the

Alexandre Julliard julliard at wine.codeweavers.com
Sat Jan 14 10:56:38 CST 2006


Module: wine
Branch: refs/heads/master
Commit: ad8cb6133edce109406be63c1425899a90fa6146
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=ad8cb6133edce109406be63c1425899a90fa6146

Author: Alexandre Julliard <julliard at 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;




More information about the wine-cvs mailing list