mirror of
git://git.code.sf.net/p/cdesktopenv/code
synced 2025-03-09 15:50:02 +00:00
Fix a few issues with $RANDOM seeding in subshells (#339)
This commit fixes an issue I found in the subshell $RANDOM
reseeding code.
The main issue is a performance regression in the shbench fibonacci
benchmark, introduced in commit af6a32d1. Performance dropped in
this benchmark because $RANDOM is always reseeded and restored,
even when it's never used in a subshell. Performance results from
before and after this performance fix (results are on Linux with
CC=gcc and CCFLAGS='-O2 -D_std_malloc'):
$ ./shbench -b bench/fibonacci.ksh -l 100 ./ksh-0f06a2e ./ksh-af6a32d ./ksh-f31e368 ./ksh-randfix
benchmarking ./ksh-0f06a2e, ./ksh-af6a32d, ./ksh-f31e368, ./ksh-randfix ...
*** fibonacci.ksh ***
# ./ksh-0f06a2e # Recent version of ksh93u+m
# ./ksh-af6a32d # Commit that introduced the regression
# ./ksh-f31e368 # Commit without the regression
# ./ksh-randfix # Ksh93u+m with this patch applied
-------------------------------------------------------------------------------------------------
name ./ksh-0f06a2e ./ksh-af6a32d ./ksh-f31e368 ./ksh-randfix
-------------------------------------------------------------------------------------------------
fibonacci.ksh 0.481 [0.459-0.515] 0.472 [0.455-0.504] 0.396 [0.380-0.442] 0.407 [0.385-0.439]
-------------------------------------------------------------------------------------------------
src/cmd/ksh93/include/variables.h,
src/cmd/ksh93/sh/{init,subshell}.c:
- Rather than reseed $RANDOM every time a subshell is created, add
a sh_save_rand_seed() function that does this only when the
$RANDOM variable is used in a subshell. This function is called
by the $RANDOM discipline functions nget_rand() and put_rand().
As a minor optimization, sh_save_rand_seed doesn't reseed if it's
called from put_rand().
- Because $RANDOM may have a seed of zero (i.e., RANDOM=0),
sp->rand_seed isn't enough to tell if $RANDOM has been reseeded.
Add sp->rand_state for this purpose.
- sh_subshell(): Only restore the former $RANDOM seed and state if
it is necessary to prevent a subshell leak.
src/cmd/ksh93/tests/variables.sh:
- Add two regression tests for bugs I ran into while making this
patch.
This commit is contained in:
parent
745ffd366d
commit
396b388e1f
5 changed files with 59 additions and 12 deletions
|
|
@ -99,6 +99,19 @@ do : $( : $RANDOM $RANDOM $RANDOM )
|
|||
done
|
||||
[[ $got == "$exp" ]] || err_exit 'Using $RANDOM in subshell influences reproducible sequence in parent environment' \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
# Forking a subshell shouldn't throw away the $RANDOM seed in the main shell
|
||||
exp=$(ulimit -t unlimited; RANDOM=123; echo $RANDOM)
|
||||
RANDOM=123
|
||||
(ulimit -t unlimited; true)
|
||||
got=${ echo $RANDOM ;}
|
||||
[[ $got == "$exp" ]] || err_exit "Forking a subshell resets the parent shell's \$RANDOM seed" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
# Similarly, forking a subshell shouldn't throw away a seed
|
||||
# previously set inside of the subshell
|
||||
exp=$(ulimit -t unlimited; RANDOM=789; echo $RANDOM)
|
||||
got=$(RANDOM=789; ulimit -t unlimited; echo $RANDOM)
|
||||
[[ $got == "$exp" ]] || err_exit "Forking a subshell resets the subshell's \$RANDOM seed" \
|
||||
"(expected $(printf %q "$exp"), got $(printf %q "$got"))"
|
||||
unset N i rand1 rand2
|
||||
|
||||
# SECONDS
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue