#include <ucw/lib.h>
#include <ucw/random.h>
#include <ucw/threads.h>
+#include <ucw/unaligned.h>
#include <limits.h>
#include <stdlib.h>
void fastrand_mem(struct fastrand *c, void *ptr, size_t size)
{
+ // XXX: Could be optimized to aligned assignments instead of put_u32/64, but it
+ // would be quite complex to make it deterministic (for same seed and any @ptr)
+ // and large sizes are not used often anyway.
FASTRAND_CHECK_SEED(c);
byte *p = ptr;
- if (size > 3)
+#if FASTRAND_ONE_BITS < 64
+ for (size_t n = size >> 2; n--; p += 4)
+ put_u32(p, fastrand_u32_helper(c));
+ if (size &= 3)
{
- if ((intptr_t)p & 3)
- {
- u32 x = fastrand_u32_helper(c);
- while ((intptr_t)p & 3)
- {
- *p++ = x;
- x >>= 8;
- size--;
- }
- }
-#if FASTRAND_ONE_BITS == 64
- for (size_t n = size >> 3; n--; )
- {
- u64 x = fastrand_one(c);
- ((u32 *)p)[0] = x;
- ((u32 *)p)[1] = x >> 32;
- p += 8;
- }
- if (size & 4)
+ u32 x = fastrand_u32_helper(c);
#else
- for (size_t n = size >> 2; n--; )
-#endif
- {
- *(u32 *)p = fastrand_u32_helper(c);
- p += 4;
- }
- size &= 3;
- }
- if (size)
+ for (size_t n = size >> 3; n--; p += 8)
+ put_u64(p, fastrand_one(c));
+ if (size &= 7)
{
- u32 x = fastrand_u32_helper(c);
+ u64 x = fastrand_one(c);
+#endif
while (size--)
{
*p++ = x;
/** Uniformly generate 64 random bits. **/
u64 fastrand_u64(struct fastrand *c);
-/** Uniformly generate [0..64] random bits. **/
+/** Uniformly generate [0, 64] random bits. **/
u64 fastrand_bits_u64(struct fastrand *c, uint bits);
/** Uniformly generate [0, 8*sizeof(uint)] random bits. **/