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

random seed.
This commit is contained in:
Alexandre Julliard 2006-01-14 17:27:28 +01:00
parent 2ec3b96135
commit ad8cb6133e
5 changed files with 20 additions and 2 deletions

View File

@ -38,12 +38,26 @@ void _beep( unsigned int freq, unsigned int duration)
Beep(freq, duration); Beep(freq, duration);
} }
/*********************************************************************
* srand (MSVCRT.@)
*/
void MSVCRT_srand( unsigned int seed )
{
thread_data_t *data = msvcrt_get_thread_data();
data->random_seed = seed;
}
/********************************************************************* /*********************************************************************
* rand (MSVCRT.@) * rand (MSVCRT.@)
*/ */
int MSVCRT_rand(void) 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;
} }
/********************************************************************* /*********************************************************************

View File

@ -93,6 +93,7 @@ extern DWORD msvcrt_tls_index;
struct __thread_data { struct __thread_data {
int thread_errno; int thread_errno;
unsigned long thread_doserrno; unsigned long thread_doserrno;
unsigned int random_seed; /* seed for rand() */
char *strtok_next; /* next ptr for strtok() */ char *strtok_next; /* next ptr for strtok() */
unsigned char *mbstok_next; /* next ptr for mbstok() */ unsigned char *mbstok_next; /* next ptr for mbstok() */
MSVCRT_wchar_t *wcstok_next; /* next ptr for wcstok() */ 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_WEOF (MSVCRT_wint_t)(0xFFFF)
#define MSVCRT_EOF (-1) #define MSVCRT_EOF (-1)
#define MSVCRT_TMP_MAX 0x7fff #define MSVCRT_TMP_MAX 0x7fff
#define MSVCRT_RAND_MAX 0x7fff
#define MSVCRT_BUFSIZ 512 #define MSVCRT_BUFSIZ 512
#define MSVCRT_STDIN_FILENO 0 #define MSVCRT_STDIN_FILENO 0

View File

@ -695,7 +695,7 @@
@ cdecl sinh(double) @ cdecl sinh(double)
@ varargs sprintf(ptr str) MSVCRT_sprintf @ varargs sprintf(ptr str) MSVCRT_sprintf
@ cdecl sqrt(double) @ cdecl sqrt(double)
@ cdecl srand(long) @ cdecl srand(long) MSVCRT_srand
@ varargs sscanf(str str) MSVCRT_sscanf @ varargs sscanf(str str) MSVCRT_sscanf
@ cdecl strcat(str str) @ cdecl strcat(str str)
@ cdecl strchr(str long) @ cdecl strchr(str long)

View File

@ -303,6 +303,7 @@ static void test_defines(void)
CHECK_DEF(WEOF); CHECK_DEF(WEOF);
CHECK_DEF(EOF); CHECK_DEF(EOF);
CHECK_DEF(TMP_MAX); CHECK_DEF(TMP_MAX);
CHECK_DEF(RAND_MAX);
CHECK_DEF(BUFSIZ); CHECK_DEF(BUFSIZ);
CHECK_DEF(STDIN_FILENO); CHECK_DEF(STDIN_FILENO);
CHECK_DEF(STDOUT_FILENO); CHECK_DEF(STDOUT_FILENO);

View File

@ -44,6 +44,7 @@ thread_data_t *msvcrt_get_thread_data(void)
if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) ))) if (!(ptr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*ptr) )))
_amsg_exit( _RT_THREAD ); _amsg_exit( _RT_THREAD );
if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD ); if (!TlsSetValue( msvcrt_tls_index, ptr )) _amsg_exit( _RT_THREAD );
ptr->random_seed = 1;
} }
SetLastError( err ); SetLastError( err );
return ptr; return ptr;