cvs: /php4/ext/standard basic_functions.c basic_functions.h rand.c
| From: | Sascha Schumann | Date: | Mon, 13 Dec 1999 18:31:59 +0000 |
| Subject: | cvs: /php4/ext/standard basic_functions.c basic_functions.h rand.c | ||
| Groups: | php.version4 | ||
| Request: | Send a blank email to php-version4+get-7866@lists.php.net to get a copy of this message | ||
sas Mon Dec 13 13:31:59 1999 EDT
Modified files:
/php4/ext/standard basic_functions.c basic_functions.h rand.c
Log:
Make rand.c thread-safe.
Index: php4/ext/standard/basic_functions.c
diff -u php4/ext/standard/basic_functions.c:1.133 php4/ext/standard/basic_functions.c:1.134
--- php4/ext/standard/basic_functions.c:1.133 Sun Dec 12 11:14:39 1999
+++ php4/ext/standard/basic_functions.c Mon Dec 13 13:31:28 1999
@@ -363,11 +363,19 @@
void test_class_startup(void);
+static void basic_globals_ctor(BLS_D)
+{
+ BG(next) = NULL;
+ BG(left) = -1;
+}
+
PHP_MINIT_FUNCTION(basic)
{
ELS_FETCH();
#ifdef ZTS
- basic_globals_id = ts_allocate_id(sizeof(php_basic_globals), NULL, NULL);
+ basic_globals_id = ts_allocate_id(sizeof(php_basic_globals), (ts_allocate_ctor)
basic_globals_ctor, NULL);
+#else
+ basic_globals_ctor(BLS_C);
#endif
REGISTER_DOUBLE_CONSTANT("M_PI", M_PI, CONST_CS | CONST_PERSISTENT);
Index: php4/ext/standard/basic_functions.h
diff -u php4/ext/standard/basic_functions.h:1.34 php4/ext/standard/basic_functions.h:1.35
--- php4/ext/standard/basic_functions.h:1.34 Sun Dec 12 11:48:54 1999
+++ php4/ext/standard/basic_functions.h Mon Dec 13 13:31:29 1999
@@ -29,7 +29,7 @@
*/
-/* $Id: basic_functions.h,v 1.34 1999/12/12 16:48:54 sas Exp $ */
+/* $Id: basic_functions.h,v 1.35 1999/12/13 18:31:29 sas Exp $ */
#ifndef _BASIC_FUNCTIONS_H
#define _BASIC_FUNCTIONS_H
@@ -111,6 +111,18 @@
typedef int php_stat_len;
#endif
+#if SIZEOF_INT == 4
+/* Most 32-bit and 64-bit systems have 32-bit ints */
+typedef unsigned int uint32;
+#elif SIZEOF_LONG == 4
+/* 16-bit systems? */
+typedef unsigned long uint32;
+#else
+#error Need type which holds 32 bits
+#endif
+
+#define MT_N (624)
+
typedef struct {
HashTable *user_shutdown_function_names;
HashTable putenv_ht;
@@ -132,6 +144,11 @@
php_stat_len CurrentStatLength;
struct stat sb;
struct stat lsb;
+
+ /* rand.c */
+ uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */
+ uint32 *next; /* next random value is computed from here */
+ int left; /* can *next++ this many times before reloading */
} php_basic_globals;
#ifdef ZTS
Index: php4/ext/standard/rand.c
diff -u php4/ext/standard/rand.c:1.7 php4/ext/standard/rand.c:1.8
--- php4/ext/standard/rand.c:1.7 Wed Oct 6 12:34:36 1999
+++ php4/ext/standard/rand.c Mon Dec 13 13:31:29 1999
@@ -19,7 +19,7 @@
| Based on code from: Shawn Cokus <Cokus@math.washington.edu> |
+----------------------------------------------------------------------+
*/
-/* $Id: rand.c,v 1.7 1999/10/06 16:34:36 andrei Exp $ */
+/* $Id: rand.c,v 1.8 1999/12/13 18:31:29 sas Exp $ */
#include <stdlib.h>
@@ -27,6 +27,8 @@
#include "phpmath.h"
#include "php_rand.h"
+#include "basic_functions.h"
+
/*
This is the ``Mersenne Twister'' random number generator MT19937, which
generates pseudorandom integers uniformly distributed in 0..(2^32 - 1)
@@ -77,26 +79,20 @@
uint32 must be an unsigned integer type capable of holding at least 32
bits; exactly 32 should be fastest, but 64 is better on an Alpha with
GCC at -O3 optimization so try your options and see what's best for you
-
+
Melo: we should put some ifdefs here to catch those alphas...
*/
-typedef unsigned int uint32;
-#define N (624) /* length of state vector */
+#define N MT_N /* length of state vector */
#define M (397) /* a period parameter */
#define K (0x9908B0DFU) /* a magic constant */
#define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */
#define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */
#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */
#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */
-
-static uint32 state[N+1]; /* state vector + 1 extra to not violate ANSI C */
-static uint32 *next; /* next random value is computed from here */
-static int left = -1; /* can *next++ this many times before reloading */
-
-static void seedMT(uint32 seed)
+static void seedMT(uint32 seed BLS_DC)
{
/*
We initialize state[0..(N-1)] via the generator
@@ -144,31 +140,31 @@
so-- that's why the only change I made is to restrict to odd seeds.
*/
- register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
+ register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = BG(state);
register int j;
- for(left=0, *s++=x, j=N; --j;
+ for(BG(left)=0, *s++=x, j=N; --j;
*s++ = (x*=69069U) & 0xFFFFFFFFU);
}
-static uint32 reloadMT(void)
+static uint32 reloadMT(BLS_D)
{
- register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
+ register uint32 *p0=BG(state), *p2=BG(state)+2, *pM=BG(state)+M, s0, s1;
register int j;
- if(left < -1)
- seedMT(4357U);
+ if(BG(left) < -1)
+ seedMT(4357U BLS_CC);
- left=N-1, next=state+1;
+ BG(left)=N-1, BG(next)=BG(state)+1;
- for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
+ for(s0=BG(state)[0], s1=BG(state)[1], j=N-M+1; --j; s0=s1, s1=*p2++)
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
- for(pM=state, j=M; --j; s0=s1, s1=*p2++)
+ for(pM=BG(state), j=M; --j; s0=s1, s1=*p2++)
*p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
- s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
+ s1=BG(state)[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
s1 ^= (s1 >> 11);
s1 ^= (s1 << 7) & 0x9D2C5680U;
s1 ^= (s1 << 15) & 0xEFC60000U;
@@ -179,11 +175,12 @@
static inline uint32 randomMT(void)
{
uint32 y;
+ BLS_FETCH();
- if(--left < 0)
- return(reloadMT());
+ if(--BG(left) < 0)
+ return(reloadMT(BLS_C));
- y = *next++;
+ y = *BG(next)++;
y ^= (y >> 11);
y ^= (y << 7) & 0x9D2C5680U;
y ^= (y << 15) & 0xEFC60000U;
@@ -217,12 +214,13 @@
PHP_FUNCTION(mt_srand)
{
pval **arg;
+ BLS_FETCH();
if (ARG_COUNT(ht) != 1 || getParametersEx(1, &arg) == FAILURE) {
WRONG_PARAM_COUNT;
}
convert_to_long_ex(arg);
- seedMT((*arg)->value.lval);
+ seedMT((*arg)->value.lval BLS_CC);
}
/* }}} */