Skip to content

Commit a8aed31

Browse files
author
Jeroen van Wolffelaar
committed
- Different approach to handling multiple random number generators,
now it is way more general, adding a new generator is way more easier. Also elimination the need for a lot of switches. - Made rand() Thread Safe - Made sure this doesn't compile anymore ;-) - PHPAPI functions now behave (almost) as intended, this is not yet the case for PHP_FUNCTION functions.
1 parent e6d996d commit a8aed31

File tree

6 files changed

+201
-149
lines changed

6 files changed

+201
-149
lines changed

ext/standard/Makefile.in

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ LTLIBRARY_SOURCES=\
55
dir.c dl.c dns.c exec.c file.c filestat.c flock_compat.c \
66
formatted_print.c fsock.c head.c html.c image.c info.c iptc.c lcg.c \
77
link.c mail.c math.c md5.c metaphone.c microtime.c pack.c pageinfo.c \
8-
parsedate.c quot_print.c rand.c rand_mt.c reg.c soundex.c string.c scanf.c \
8+
parsedate.c quot_print.c rand.c rand_sys.c rand_mt.c reg.c \
9+
soundex.c string.c scanf.c \
910
syslog.c type.c uniqid.c url.c url_scanner.c var.c assert.c \
1011
strnatcmp.c levenshtein.c incomplete_class.c url_scanner_ex.c \
1112
ftp_fopen_wrapper.c http_fopen_wrapper.c php_fopen_wrapper.c credits.c

ext/standard/basic_functions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,9 @@ typedef struct {
174174
int rand_generator; /* current ini-setting */
175175
int rand_generator_current; /* current (by overriding by [mt_]srand) */
176176

177+
/* rand_sys.c */
178+
unsigned int rand_sys_seed; /* Current seed for system-rand() (necessary for thread-safety) */
179+
177180
/* rand_mt.c */
178181
php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */
179182
php_uint32 *next; /* next random value is computed from here */

ext/standard/php_rand.h

Lines changed: 38 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
| Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
1616
| Zeev Suraski <zeev@zend.com> |
1717
| Pedro Melo <melo@ip.pt> |
18+
| Jeroen van Wolffelaar <jeroen@php.net> |
1819
| |
1920
| Based on code from: Shawn Cokus <Cokus@math.washington.edu> |
2021
+----------------------------------------------------------------------+
@@ -56,27 +57,51 @@
5657
* --Jeroen
5758
*/
5859

60+
/* TODO:
61+
* - make constants available to PHP-user
62+
* - MINFO section about which random number generators are available
63+
* - Nuke randmax by enhancing PHP_RAND_RANGE to work well in the case of a
64+
* greater request than the real (internal) randmax is
65+
* - Implement LCG
66+
* - Implement a real-random source? (via internet, and/or /dev/urandom?)
67+
* - Can lrand48 be thread-safe?
68+
* - Is random() useful sometimes?
69+
* - Which system algorithms are available, maybe name them after real
70+
* algorithm by compile-time detection?
71+
* - Get this to compile :-)
72+
*/
5973
#ifndef PHP_RAND_H
6074
#define PHP_RAND_H
6175

6276
#include <stdlib.h>
6377

64-
#ifndef RAND_MAX
65-
#define RAND_MAX (1<<15)
66-
#endif
78+
/* FIXME: that '_php_randgen_entry' needed, or not? */
79+
typedef struct _php_randgen_entry {
80+
void (*srand)(long seed);
81+
long (*rand)(void);
82+
long randmax;
83+
char *ini_str;
84+
} php_randgen_entry;
6785

68-
#if HAVE_LRAND48
69-
#define php_randmax_sys() 2147483647
70-
#else
71-
#define php_randmax_sys() RAND_MAX
72-
#endif
86+
php_randgen_entry *php_randgen_entries;
7387

74-
/*
75-
* Melo: it could be 2^^32 but we only use 2^^31 to maintain
76-
* compatibility with the previous php_rand
77-
*/
78-
#define php_randmax_mt() ((long)(0x7FFFFFFF)) /* 2^^31 - 1 */
88+
#define PHP_SRAND(which,seed) (php_randgen_entry[which]->srand(seed))
89+
#define PHP_RAND(which) (php_randgen_entry[which]->rand())
90+
#define PHP_RANDMAX(which) (php_randgen_entry[which].randmax)
91+
#define PHP_RAND_INISTR(which) (php_randgen_entry[which].ini_str)
92+
93+
/* Define random generator constants */
94+
#define PHP_RAND_SYS 0
95+
#define PHP_RAND_LRAND48 1
96+
#define PHP_RAND_MT 2
97+
#define PHP_RAND_LCG 3
98+
99+
#define PHP_RAND_DEFAULT PHP_RAND_MT
100+
101+
/* how many there are */
102+
#define PHP_RAND_NUMRANDS 4
79103

104+
/* Proto's */
80105
PHP_FUNCTION(srand);
81106
PHP_FUNCTION(rand);
82107
PHP_FUNCTION(getrandmax);
@@ -87,45 +112,6 @@ PHP_FUNCTION(mt_getrandmax);
87112
PHPAPI long php_rand(void);
88113
PHPAPI long php_rand_range(long min, long max);
89114
PHPAPI long php_randmax(void);
90-
long php_rand_mt(void);
91-
void php_srand_mt(long seed TSRMLS_DC);
92-
93-
/* Define rand Function wrapper */
94-
#ifdef HAVE_RANDOM
95-
#define php_rand_sys() random()
96-
#else
97-
#ifdef HAVE_LRAND48
98-
#define php_rand_sys() lrand48()
99-
#else
100-
#define php_rand_sys() rand()
101-
#endif
102-
#endif
103-
104-
/* Define srand Function wrapper */
105-
#ifdef HAVE_SRANDOM
106-
#define php_srand_sys(seed) srandom((unsigned int)seed)
107-
#else
108-
#ifdef HAVE_SRAND48
109-
#define php_srand_sys(seed) srand48((long)seed)
110-
#else
111-
#define php_srand_sys(seed) srand((unsigned int)seed)
112-
#endif
113-
#endif
114-
115-
/* Define random generator constants */
116-
#define RAND_SYS 1
117-
#define RAND_MT 2
118-
#define RAND_LCG 3
119-
#define RAND_SYS_STR "system"
120-
#define RAND_MT_STR "mt"
121-
#define RAND_LCG_STR "lcg"
122-
123-
#define RAND_DEFAULT RAND_MT
124-
#define RAND_DEFAULT_STR RAND_MT_STR
125-
126-
127-
/* BC */
128-
#define PHP_RAND_MAX php_randmax()
129115

130116
#endif /* PHP_RAND_H */
131117

0 commit comments

Comments
 (0)