diff options
| author | Feoramund <161657516+Feoramund@users.noreply.github.com> | 2025-03-03 15:29:33 -0500 |
|---|---|---|
| committer | Feoramund <161657516+Feoramund@users.noreply.github.com> | 2025-03-03 19:17:29 -0500 |
| commit | d6002d68a2f15a286694fc36a8dfc599d4f5be68 (patch) | |
| tree | 05c45e5ff4b26134df32552a22addafdad94bdbe /core/os | |
| parent | 189b4782fb19dae260dcf1893583976463f21e6f (diff) | |
Make `os2.random_string` use `context.random_generator`
This removes the data race caused by multiple threads using the
unprotected global `random_string_seed`, so long as no two threads share
the same random generator; this is the default case.
Additionally, `os2.random_string` now takes into account the full buffer
slice given to it.
Diffstat (limited to 'core/os')
| -rw-r--r-- | core/os/os2/internal_util.odin | 47 |
1 files changed, 9 insertions, 38 deletions
diff --git a/core/os/os2/internal_util.odin b/core/os/os2/internal_util.odin index 164e1e1be..ce253d17b 100644 --- a/core/os/os2/internal_util.odin +++ b/core/os/os2/internal_util.odin @@ -3,6 +3,7 @@ package os2 import "base:intrinsics" import "base:runtime" +import "core:math/rand" // Splits pattern by the last wildcard "*", if it exists, and returns the prefix and suffix @@ -84,45 +85,15 @@ concatenate :: proc(strings: []string, allocator: runtime.Allocator) -> (res: st return string(buf), nil } - - -@(private="file") -random_string_seed: [2]u64 - -@(init, private="file") -init_random_string_seed :: proc() { - seed := u64(intrinsics.read_cycle_counter()) - s := &random_string_seed - s[0] = 0 - s[1] = (seed << 1) | 1 - _ = next_random(s) - s[1] += seed - _ = next_random(s) -} - -@(require_results) -next_random :: proc(r: ^[2]u64) -> u64 { - old_state := r[0] - r[0] = old_state * 6364136223846793005 + (r[1]|1) - xor_shifted := (((old_state >> 59) + 5) ~ old_state) * 12605985483714917081 - rot := (old_state >> 59) - return (xor_shifted >> rot) | (xor_shifted << ((-rot) & 63)) -} - @(require_results) random_string :: proc(buf: []byte) -> string { - @(static, rodata) digits := "0123456789" - - u := next_random(&random_string_seed) - - b :: 10 - i := len(buf) - for u >= b { - i -= 1 - buf[i] = digits[u % b] - u /= b + for i := 0; i < len(buf); i += 16 { + n := rand.uint64() + end := min(i + 16, len(buf)) + for j := i; j < end; j += 1 { + buf[j] = '0' + u8(n) % 10 + n >>= 4 + } } - i -= 1 - buf[i] = digits[u % b] - return string(buf[i:]) + return string(buf) } |