From 8cfb8141128e33e2938bbb85c39a7250a6533c79 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Wed, 4 Jul 2018 20:26:17 +0200 Subject: [PATCH] Random: add a global RANDOM_DEVICE generator Creating a RandomDevice object is cheap but it opens a file on unix systems, so one can't call `rand(RandomDevice())` repeatedly too quicly (e.g. in a loop). It can therefore be convenient to have a readily available generator. --- stdlib/Random/src/RNGs.jl | 10 ++++++++++ stdlib/Random/src/Random.jl | 2 +- stdlib/Random/test/runtests.jl | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/stdlib/Random/src/RNGs.jl b/stdlib/Random/src/RNGs.jl index 899147313fb2b..f8d622b3b80d5 100644 --- a/stdlib/Random/src/RNGs.jl +++ b/stdlib/Random/src/RNGs.jl @@ -67,6 +67,7 @@ RandomDevice RandomDevice(::Nothing) = RandomDevice() seed!(rng::RandomDevice) = rng +const RANDOM_DEVICE = RandomDevice() ## MersenneTwister @@ -306,6 +307,15 @@ const THREAD_RNGs = MersenneTwister[] end function __init__() resize!(empty!(THREAD_RNGs), Threads.nthreads()) # ensures that we didn't save a bad object + + if !Sys.iswindows() + # open /dev/urandom "in-place" (in RANDOM_DEVICE.file) + RANDOM_DEVICE.file.handle = pointer(RANDOM_DEVICE.file.ios) + systemerror("opening file /dev/urandom", + ccall(:ios_file, Ptr{Cvoid}, + (Ptr{UInt8}, Cstring, Cint, Cint, Cint, Cint), + RANDOM_DEVICE.file.ios, "/dev/urandom", 1, 0, 0, 0) == C_NULL) + end end diff --git a/stdlib/Random/src/Random.jl b/stdlib/Random/src/Random.jl index a3ac839677535..dbcc77bc4d4c5 100644 --- a/stdlib/Random/src/Random.jl +++ b/stdlib/Random/src/Random.jl @@ -29,7 +29,7 @@ export rand!, randn!, shuffle, shuffle!, randperm, randperm!, randcycle, randcycle!, - AbstractRNG, MersenneTwister, RandomDevice + AbstractRNG, MersenneTwister, RandomDevice, RANDOM_DEVICE ## general definitions diff --git a/stdlib/Random/test/runtests.jl b/stdlib/Random/test/runtests.jl index 49a5f5c0ccb3d..eccc672e8633e 100644 --- a/stdlib/Random/test/runtests.jl +++ b/stdlib/Random/test/runtests.jl @@ -778,3 +778,7 @@ end @testset "RNGs broadcast as scalars: T" for T in (MersenneTwister, RandomDevice) @test length.(rand.(T(), 1:3)) == 1:3 end + +@testset "RANDOM_DEVICE" begin + @test rand(Random.RANDOM_DEVICE) isa Float64 +end