Skip to content

Commit 05b9934

Browse files
committed
util.c - add support for building with WELLRNG512a
1 parent 79b9058 commit 05b9934

11 files changed

+266
-86
lines changed

embed.fnc

+12-3
Original file line numberDiff line numberDiff line change
@@ -1149,9 +1149,6 @@ p |void |do_vop |I32 optype \
11491149
|NN SV *left \
11501150
|NN SV *right
11511151
CDRdp |U8 |dowantarray
1152-
TXop |void |drand48_init_r |NN perl_drand48_t *random_state \
1153-
|U32 seed
1154-
TXop |double |drand48_r |NN perl_drand48_t *random_state
11551152
Adp |void |dump_all
11561153
p |void |dump_all_perl |bool justperl
11571154
Adhp |void |dump_eval
@@ -6273,6 +6270,18 @@ Tp |Signal_t|sighandler |int sig \
62736270
CTp |Signal_t|csighandler |int sig
62746271
Tp |Signal_t|sighandler |int sig
62756272
#endif
6273+
#if defined(PERL_USE_WELL512A_RNG)
6274+
TXop |double |drand01_wellrng512a_r \
6275+
|NN U32 *random_state
6276+
TXop |void |wellrng512a_init_r \
6277+
|NN U32 *random_state \
6278+
|U32 seed
6279+
TXop |U32 |wellrng512a_u_r|NN U32 *random_state
6280+
#else
6281+
TXop |void |drand48_init_r |NN perl_drand48_t *random_state \
6282+
|U32 seed
6283+
TXop |double |drand48_r |NN perl_drand48_t *random_state
6284+
#endif
62766285
#if defined(U64TYPE)
62776286
CRTip |unsigned|lsbit_pos64 |U64 word
62786287
CRTip |unsigned|msbit_pos64 |U64 word

embedvar.h

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

handy.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ from it, and are very unlikely to change
4343
=for apidoc_defn Amu|token|CAT2|token x|token y
4444
=for apidoc_defn Amu|string|STRINGIFY|token x
4545
46-
=for apidoc_defn Am|double|Drand01
47-
=for apidoc_defn Am|void|seedDrand01|Rand_seed_t x
46+
=for apidoc_defn AmT|double|Drand01
47+
=for apidoc_defn AmT|void|seedDrand01|Rand_seed_t x
48+
4849
=for apidoc_defn Am|char *|Gconvert|double x|Size_t n|bool t|char * b
4950
5051
=cut

intrpvar.h

+10-3
Original file line numberDiff line numberDiff line change
@@ -1018,17 +1018,24 @@ PERLVARA(I, op_exec_cnt, OP_max+2, UV) /* Counts of executed OPs of the given t
10181018
for profiling in DEBUGGING mode. */
10191019
#endif
10201020

1021-
PERLVAR(I, random_state, PL_RANDOM_STATE_TYPE)
1022-
10231021
PERLVARI(I, dump_re_max_len, STRLEN, 60)
10241022

1023+
#ifndef PERL_USE_WELL512A_RNG
1024+
PERLVAR(I, random_state, PL_RANDOM_STATE_TYPE)
1025+
#else
1026+
PERLVARA(I, random_state, PL_RANDOM_STATE_LENGTH, PL_RANDOM_STATE_TYPE)
1027+
#endif
1028+
10251029
/* For internal uses of randomness, this ensures the sequence of
10261030
* random numbers returned by rand() isn't modified by perl's internal
10271031
* use of randomness.
10281032
* This is important if the user has called srand() with a seed.
10291033
*/
1030-
1034+
#ifndef PERL_USE_WELL512A_RNG
10311035
PERLVAR(I, random_state_internal, PL_RANDOM_STATE_TYPE)
1036+
#else
1037+
PERLVARA(I, random_state_internal, PL_RANDOM_STATE_LENGTH, PL_RANDOM_STATE_TYPE)
1038+
#endif
10321039

10331040
PERLVARA(I, TR_SPECIAL_HANDLING_UTF8, UTF8_MAXBYTES, char)
10341041

perl.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ perl_construct(pTHXx)
288288
/* This is NOT the state used for C<rand()>, this is only
289289
* used in internal functionality */
290290
#ifdef NO_PERL_INTERNAL_RAND_SEED
291-
Perl_drand48_init_r(PL_PTR_RANDOM_STATE_INTERNAL, seed());
291+
Perl_drand01_init_r(PL_PTR_RANDOM_STATE_INTERNAL, seed());
292292
#else
293293
{
294294
UV seed;
@@ -301,7 +301,7 @@ perl_construct(pTHXx)
301301
/* use a randomly generated seed */
302302
seed = seed();
303303
}
304-
Perl_drand48_init_r(PL_PTR_RANDOM_STATE_INTERNAL, (U32)seed);
304+
Perl_drand01_init_r(PL_PTR_RANDOM_STATE_INTERNAL, (U32)seed);
305305
}
306306
#endif
307307

@@ -2070,6 +2070,10 @@ S_Internals_V(pTHX_ CV *cv)
20702070
# ifdef PERL_USE_UNSHARED_KEYS_IN_LARGE_HASHES
20712071
" PERL_USE_UNSHARED_KEYS_IN_LARGE_HASHES"
20722072
# endif
2073+
# ifdef PERL_USE_WELL512A_RNG
2074+
" PERL_USE_WELL512A_RNG"
2075+
# endif
2076+
20732077
# ifdef SILENT_NO_TAINT_SUPPORT
20742078
" SILENT_NO_TAINT_SUPPORT"
20752079
# endif
@@ -2475,7 +2479,7 @@ S_parse_body(pTHX_ char **env, XSINIT_t xsinit)
24752479
if (TAINT_get &&
24762480
PerlProc_getuid() == PerlProc_geteuid() &&
24772481
PerlProc_getgid() == PerlProc_getegid()) {
2478-
Perl_drand48_init_r(PL_PTR_RANDOM_STATE_INTERNAL, seed());
2482+
Perl_drand01_init_r(PL_PTR_RANDOM_STATE_INTERNAL, seed());
24792483
}
24802484
#endif
24812485
if (DEBUG_h_TEST)

proto.h

+28-10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sv.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -15918,8 +15918,10 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags,
1591815918
PL_globhook = proto_perl->Iglobhook;
1591915919

1592015920
PL_srand_called = proto_perl->Isrand_called;
15921-
Copy(PL_PTR_PROTO_RANDOM_STATE, PL_PTR_RANDOM_STATE, 1, PL_RANDOM_STATE_TYPE);
15922-
Copy(PL_PTR_PROTO_RANDOM_STATE_INTERNAL, PL_PTR_RANDOM_STATE_INTERNAL, 1, PL_RANDOM_STATE_TYPE);
15921+
Copy(PL_PTR_PROTO_RANDOM_STATE, PL_PTR_RANDOM_STATE,
15922+
PL_RANDOM_STATE_LENGTH, PL_RANDOM_STATE_TYPE);
15923+
Copy(PL_PTR_PROTO_RANDOM_STATE_INTERNAL, PL_PTR_RANDOM_STATE_INTERNAL,
15924+
PL_RANDOM_STATE_LENGTH, PL_RANDOM_STATE_TYPE);
1592315925
PL_srand_override = proto_perl->Isrand_override;
1592415926
PL_srand_override_next = proto_perl->Isrand_override_next;
1592515927

t/op/rand.t

+6-2
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,19 @@ EOM
126126
srand 12345;
127127
is(rand(1), $r, 'rand() without args is rand(1)');
128128

129-
130129
# This checks that rand without an argument is not
131130
# rand($_). (In case somebody got overzealous.)
132131
#
133132
cmp_ok($r, '<', 1, 'rand() without args is under 1');
134133
}
135134

136-
{ # [perl #115928] use a standard rand() implementation
135+
if ($Config{ccflags}!~/PERL_USE_WELL512A_RNG/){
136+
# [perl #115928] use a standard rand() implementation
137137
srand(1);
138138
is(int rand(1000), 41, "our own implementation behaves consistently");
139139
is(int rand(1000), 454, "and still consistently");
140+
} else {
141+
srand(1);
142+
is(int rand(1000), 133, "our implementation of WELLRNG512A behaves consistently");
143+
is(int rand(1000), 346, "and still consistently");
140144
}

t/run/runenv_randseed.t

+83-48
Original file line numberDiff line numberDiff line change
@@ -13,56 +13,91 @@ skip_all("This perl is built with NO_PERL_RAND_SEED")
1313
if $Config{ccflags} =~ /-DNO_PERL_RAND_SEED\b/;
1414
use strict;
1515
use warnings;
16+
my $test_code = <<'EOF_TEST_CODE';
17+
for my $l ("A".."E") {
18+
my $pid= fork;
19+
if ($pid) {
20+
push @pids, $pid;
21+
}
22+
elsif (!defined $pid) {
23+
print "$l:failed fork";
24+
} elsif (!$pid) {
25+
print "$l:", map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10;
26+
exit;
27+
}
28+
}
29+
waitpid $_,0 for @pids;
30+
EOF_TEST_CODE
1631

17-
for (1..2) {
18-
local $ENV{PERL_RAND_SEED} = 1;
19-
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
20-
"BLVIOAEZTJ", undef, "Test randomness with PERL_RAND_SEED=1");
21-
}
32+
if ($Config{ccflags}!~/PERL_USE_WELL512A_RNG/){
33+
for (1..2) {
34+
local $ENV{PERL_RAND_SEED} = 1;
35+
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
36+
"BLVIOAEZTJ", undef, "Test randomness with PERL_RAND_SEED=1");
37+
}
2238

23-
for (1..2) {
24-
local $ENV{PERL_RAND_SEED} = 2;
25-
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
26-
"XEOUOFRPQZ", undef, "Test randomness with PERL_RAND_SEED=2");
27-
}
39+
for (1..2) {
40+
local $ENV{PERL_RAND_SEED} = 2;
41+
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
42+
"XEOUOFRPQZ", undef, "Test randomness with PERL_RAND_SEED=2");
43+
}
2844

29-
my %got;
30-
for my $try (1..10) {
31-
local $ENV{PERL_RAND_SEED};
32-
my ($out,$err)= runperl_and_capture({}, ['-e',"print map { chr(rand(26)+65) } 1..10;"]);
33-
if ($err) { diag $err }
34-
$got{$out}++;
35-
}
36-
ok(8 <= keys %got, "Got at least 8 different strings");
37-
for (1..2) {
38-
local $ENV{PERL_RAND_SEED} = 1;
39-
my ($out,$err)= runperl_and_capture({}, ['-le',
40-
<<'EOF_TEST_CODE'
41-
for my $l ("A".."E") {
42-
my $pid= fork;
43-
if ($pid) {
44-
push @pids, $pid;
45-
}
46-
elsif (!defined $pid) {
47-
print "$l:failed fork";
48-
} elsif (!$pid) {
49-
print "$l:", map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10;
50-
exit;
51-
}
52-
}
53-
waitpid $_,0 for @pids;
54-
EOF_TEST_CODE
55-
]);
56-
is($err, "", "No exceptions forking.");
57-
my @parts= sort { $a cmp $b } split /\n/, $out;
58-
my @want= (
59-
"A:KNXDITWWJZ",
60-
"B:WDQJGTBJQS",
61-
"C:ZGYCCINIHE",
62-
"D:UGLGAEXFBP",
63-
"E:MQLTNZGZQB"
64-
);
65-
is("@parts","@want","Works as expected with forks.");
66-
}
45+
my %got;
46+
for my $try (1..10) {
47+
local $ENV{PERL_RAND_SEED};
48+
my ($out,$err)= runperl_and_capture({}, ['-e',"print map { chr(rand(26)+65) } 1..10;"]);
49+
if ($err) { diag $err }
50+
$got{$out}++;
51+
}
52+
ok(8 <= keys %got, "Got at least 8 different strings");
53+
for (1..2) {
54+
local $ENV{PERL_RAND_SEED} = 1;
55+
my ($out,$err)= runperl_and_capture({}, ['-le', $test_code]);
56+
is($err, "", "No exceptions forking.");
57+
my @parts= sort { $a cmp $b } split /\n/, $out;
58+
my @want= (
59+
"A:KNXDITWWJZ",
60+
"B:WDQJGTBJQS",
61+
"C:ZGYCCINIHE",
62+
"D:UGLGAEXFBP",
63+
"E:MQLTNZGZQB"
64+
);
65+
is("@parts","@want","Works as expected with forks.");
66+
}
67+
} else {
68+
for (1..2) {
69+
local $ENV{PERL_RAND_SEED} = 1;
70+
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
71+
"DJSFVUOCEP", undef, "Test randomness with PERL_RAND_SEED=1");
72+
}
6773

74+
for (1..2) {
75+
local $ENV{PERL_RAND_SEED} = 2;
76+
fresh_perl_is("print map { chr(utf8::unicode_to_native(rand(26)+65)) } 1..10",
77+
"HYLBKECYNV", undef, "Test randomness with PERL_RAND_SEED=2");
78+
}
79+
80+
my %got;
81+
for my $try (1..10) {
82+
local $ENV{PERL_RAND_SEED};
83+
my ($out,$err)= runperl_and_capture({}, ['-e',"print map { chr(rand(26)+65) } 1..10;"]);
84+
if ($err) { diag $err }
85+
$got{$out}++;
86+
}
87+
ok(8 <= keys %got, "Got at least 8 different strings");
88+
for (1..2) {
89+
local $ENV{PERL_RAND_SEED} = 1;
90+
my ($out,$err)= runperl_and_capture({}, ['-le', $test_code]);
91+
is($err, "", "No exceptions forking.");
92+
my @parts= sort { $a cmp $b } split /\n/, $out;
93+
my @want= (
94+
"A:GPYNXCIGON",
95+
"B:FAIKJCRQID",
96+
"C:TOSQBPNSUS",
97+
"D:POQSAQWNFD",
98+
"E:LXUSDWIRZB"
99+
);
100+
is("@parts","@want","Works as expected with forks.");
101+
}
102+
}
68103
done_testing();

0 commit comments

Comments
 (0)