Skip to content

Commit 0ca9279

Browse files
committed
Add portable thread-safe RNG based on PCG-C
1 parent 6d06a2c commit 0ca9279

File tree

2 files changed

+32
-17
lines changed

2 files changed

+32
-17
lines changed

src/cpfloat_definitions.h

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
#ifndef _CHOPFAST_DEFINITIONS_
2424
#define _CHOPFAST_DEFINITIONS_
2525

26-
#define _CRT_RAND_S
26+
// #define _CRT_RAND_S
2727
#include <stdlib.h>
2828
#include <stdint.h>
2929

@@ -38,6 +38,37 @@
3838

3939
#if defined(_OPENMP)
4040
#include <omp.h>
41+
42+
/* Portable thread-safe pseudo-random number generator. */
43+
/*
44+
* FIXME: The version below would be a bit more robust,
45+
* but I don't have access to a Windows machine to test it.
46+
* This needs to be revisited later.
47+
*
48+
#ifdef _WIN32
49+
// Use rand_s.
50+
#include <errno.h>
51+
unsigned int thread_safe_rand(unsigned int *seed_state) {
52+
unsigned int result;
53+
errno_t err = rand_s(&result);
54+
return result;
55+
}
56+
#else /* #ifdef _WIN32
57+
// Use rand_r.
58+
unsigned int thread_safe_rand(unsigned int *seed_state) {
59+
return rand_r(seed_state);
60+
}
61+
#endif /* #ifdef _WIN32 */
62+
unsigned int thread_safe_rand(unsigned int* seedp)
63+
{
64+
unsigned int oldstate = *seedp;
65+
// Advance internal state
66+
*seedp = oldstate * 6364136223846793005ULL + 1;
67+
// Calculate output function (XSH RR), uses old state for max ILP
68+
unsigned int xorshifted = ((oldstate >> 18u) ^ oldstate) >> 27u;
69+
unsigned int rot = oldstate >> 59u;
70+
return (xorshifted >> rot) | (xorshifted << ((-rot) & 31));
71+
}
4172
#endif /* #if defined(_OPENMP) */
4273

4374
/**

src/cpfloat_template.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -36,22 +36,6 @@
3636
#define CONCATENATE_INNER(arg1, arg2) arg1 ## arg2
3737
#define CONCATENATE(arg1, arg2) CONCATENATE_INNER(arg1, arg2)
3838

39-
/* Portable thread-safe pseudo-random number generator. */
40-
#ifdef _WIN32
41-
// Use rand_s.
42-
#include <errno.h>
43-
unsigned int thread_safe_rand(unsigned int *seed_state) {
44-
unsigned int result;
45-
errno_t err = rand_s(&result);
46-
return result;
47-
}
48-
#else /* #ifdef _WIN32 */
49-
// Use rand_r.
50-
unsigned int thread_safe_rand(unsigned int *seed_state) {
51-
return rand_r(seed_state);
52-
}
53-
#endif /* #ifdef _WIN32 */
54-
5539
/* Functions to initialize bit pseudo-random generators and generate bits. */
5640
#define BITSEED bitseed
5741
#define BITSEEDTYPE cpfloat_bitseed_t

0 commit comments

Comments
 (0)