rand: fix leaks with -autofree

pull/11955/head
Delyan Angelov 2021-09-23 11:14:20 +03:00
parent 79e33d92f1
commit 8837712f2b
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
9 changed files with 63 additions and 6 deletions

View File

@ -323,3 +323,9 @@ pub fn (mut rng MT19937RNG) f64_in_range(min f64, max f64) f64 {
} }
return min + rng.f64n(max - min) return min + rng.f64n(max - min)
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng MT19937RNG) free() {
unsafe { free(rng) }
}

View File

@ -239,3 +239,9 @@ pub fn (mut rng MuslRNG) f64_in_range(min f64, max f64) f64 {
} }
return min + rng.f64n(max - min) return min + rng.f64n(max - min)
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng MuslRNG) free() {
unsafe { free(rng) }
}

View File

@ -224,3 +224,9 @@ pub fn (mut rng PCG32RNG) f64_in_range(min f64, max f64) f64 {
} }
return min + rng.f64n(max - min) return min + rng.f64n(max - min)
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng PCG32RNG) free() {
unsafe { free(rng) }
}

View File

@ -31,6 +31,7 @@ pub interface PRNG {
f64n(max f64) f64 f64n(max f64) f64
f32_in_range(min f32, max f32) f32 f32_in_range(min f32, max f32) f32
f64_in_range(min f64, max f64) f64 f64_in_range(min f64, max f64) f64
free()
} }
__global ( __global (
@ -40,13 +41,23 @@ __global (
// init initializes the default RNG. // init initializes the default RNG.
fn init() { fn init() {
default_rng = new_default() default_rng = new_default()
C.atexit(deinit)
}
fn deinit() {
unsafe {
default_rng.free() // free the implementation
free(default_rng) // free the interface wrapper itself
}
} }
// new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance. // new_default returns a new instance of the default RNG. If the seed is not provided, the current time will be used to seed the instance.
[manualfree]
pub fn new_default(config config.PRNGConfigStruct) &PRNG { pub fn new_default(config config.PRNGConfigStruct) &PRNG {
mut rng := &wyrand.WyRandRNG{} mut rng := &wyrand.WyRandRNG{}
rng.seed(config.seed_) rng.seed(config.seed_)
return rng unsafe { config.seed_.free() }
return &PRNG(rng)
} }
// get_current_rng returns the PRNG instance currently in use. If it is not changed, it will be an instance of wyrand.WyRandRNG. // get_current_rng returns the PRNG instance currently in use. If it is not changed, it will be an instance of wyrand.WyRandRNG.

View File

@ -12,7 +12,6 @@ fn nr_next(prev u32) u32 {
} }
// time_seed_array returns the required number of u32s generated from system time. // time_seed_array returns the required number of u32s generated from system time.
[inline]
pub fn time_seed_array(count int) []u32 { pub fn time_seed_array(count int) []u32 {
ctime := time.sys_mono_now() ctime := time.sys_mono_now()
mut seed := u32(ctime >> 32 ^ (ctime & 0x0000_0000_FFFF_FFFF)) mut seed := u32(ctime >> 32 ^ (ctime & 0x0000_0000_FFFF_FFFF))
@ -25,16 +24,21 @@ pub fn time_seed_array(count int) []u32 {
} }
// time_seed_32 returns a 32-bit seed generated from system time. // time_seed_32 returns a 32-bit seed generated from system time.
[inline] [manualfree]
pub fn time_seed_32() u32 { pub fn time_seed_32() u32 {
return time_seed_array(1)[0] sa := time_seed_array(1)
res := sa[0]
unsafe { sa.free() }
return res
} }
// time_seed_64 returns a 64-bit seed generated from system time. // time_seed_64 returns a 64-bit seed generated from system time.
[inline] [manualfree]
pub fn time_seed_64() u64 { pub fn time_seed_64() u64 {
seed_data := time_seed_array(2) seed_data := time_seed_array(2)
lower := u64(seed_data[0]) lower := u64(seed_data[0])
upper := u64(seed_data[1]) upper := u64(seed_data[1])
return lower | (upper << 32) unsafe { seed_data.free() }
res := lower | (upper << 32)
return res
} }

View File

@ -223,3 +223,9 @@ pub fn (mut rng SplitMix64RNG) f64_in_range(min f64, max f64) f64 {
} }
return min + rng.f64n(max - min) return min + rng.f64n(max - min)
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng SplitMix64RNG) free() {
unsafe { free(rng) }
}

View File

@ -273,3 +273,9 @@ pub fn (r SysRNG) f64_in_range(min f64, max f64) f64 {
} }
return min + r.f64n(max - min) return min + r.f64n(max - min)
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng SysRNG) free() {
unsafe { free(rng) }
}

View File

@ -22,6 +22,12 @@ mut:
extra u32 extra u32
} }
// free should be called when the generator is no longer needed
[unsafe]
pub fn (mut rng WyRandRNG) free() {
unsafe { free(rng) }
}
// seed sets the seed, needs only two `u32`s in little-endian format as [lower, higher]. // seed sets the seed, needs only two `u32`s in little-endian format as [lower, higher].
pub fn (mut rng WyRandRNG) seed(seed_data []u32) { pub fn (mut rng WyRandRNG) seed(seed_data []u32) {
if seed_data.len != 2 { if seed_data.len != 2 {

View File

@ -0,0 +1,6 @@
import rand
fn main() {
n := rand.intn(1000)
println(n)
}