summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAndrew Opalach <andrew@akon.city> 2025-10-30 11:56:05 -0400
committerAndrew Opalach <andrew@akon.city> 2025-10-30 11:56:05 -0400
commit1b15b6ba0a78e0fe87716cc1df07f092c64dfefb (patch)
treec784e9a4a39521f00a62723bfa2aa85850bd081d /include
parent00c292b5bd4f6cf24287c7581d54a60f4b6fdcb7 (diff)
downloadlibalabaster-1b15b6ba0a78e0fe87716cc1df07f092c64dfefb.tar.gz
libalabaster-1b15b6ba0a78e0fe87716cc1df07f092c64dfefb.tar.bz2
libalabaster-1b15b6ba0a78e0fe87716cc1df07f092c64dfefb.zip
random: Try to ensure rand() state is thread-local
Signed-off-by: Andrew Opalach <andrew@akon.city>
Diffstat (limited to 'include')
-rw-r--r--include/al/random.h34
1 files changed, 32 insertions, 2 deletions
diff --git a/include/al/random.h b/include/al/random.h
index f92a77b..3df3140 100644
--- a/include/al/random.h
+++ b/include/al/random.h
@@ -5,23 +5,53 @@
#include "macros.h"
#define AL_RAND_MAX RAND_MAX
+#define AL_RAND_INIT_SEED 1738
extern u32 al_rand_seed;
+
extern __thread bool al_rand_set;
+#ifndef AL_SRAND_THREAD_LOCAL
+extern __thread u32 al_rand_state;
+#endif
static inline void al_rand_init(u32 seed)
{
al_rand_seed = seed;
}
+// @TODO: Replace this with an implementation of any PRNG algorithm where
+// we can control the state and make it thread-local. Trying to predict the
+// state in libc is pretty dumb.
+// al_rand() is equivalent to libc rand(), as such there is no expectation
+// of it being an actually good random number generator.
+#ifdef AL_SRAND_THREAD_LOCAL
+#define rrand() rand()
+#else
+#define rrand() rand_r(&al_rand_state)
+#endif
static inline s32 al_rand(void)
{
if (UNLIKELY(!al_rand_set)) {
- // srand() is thread-local in Windows CRT.
+#ifdef AL_SRAND_THREAD_LOCAL
srand(al_rand_seed);
+#else
+ al_rand_state = al_rand_seed;
+#endif
+ // Call rand() once after setting the seed incase it returns the seed
+ // on the first call, like on Windows. Having the first result potentially
+ // be so similar run-to-run would no longer even be pseudo-random.
+ // https://stackoverflow.com/a/76676396
+ rrand();
al_rand_set = true;
}
- return rand();
+ return rrand();
+}
+#undef rrand
+
+// https://c-faq.com/lib/randrange.html
+static inline s32 al_random_int(s32 min, s32 max) // [MIN, MAX]
+{
+ return min + al_rand() / (AL_RAND_MAX / (max - min + 1) + 1);
}
#endif // _AL_RANDOM_H