Skip to content

Commit 6d06a2c

Browse files
committed
Make thread-safe non-PCG-C PRNG portable to Windows
1 parent 8471c6c commit 6d06a2c

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

src/cpfloat_definitions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#ifndef _CHOPFAST_DEFINITIONS_
2424
#define _CHOPFAST_DEFINITIONS_
2525

26+
#define _CRT_RAND_S
2627
#include <stdlib.h>
2728
#include <stdint.h>
2829

src/cpfloat_template.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@
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+
3955
/* Functions to initialize bit pseudo-random generators and generate bits. */
4056
#define BITSEED bitseed
4157
#define BITSEEDTYPE cpfloat_bitseed_t
@@ -46,24 +62,24 @@
4662
#define ADVANCEBIT(seed, thread, nloc) \
4763
pcg32_advance_r(seed, thread * nloc - 1);
4864
#define GENBIT(seed) (pcg32_random_r(seed) & (1U << 31))
49-
#else /* #ifdef PCG_VARIANTS_H_INCLUDED */
65+
#else /* #ifdef PCG_VARIANTS_H_INCLUDED */
5066
#ifdef _OPENMP
5167
#define INITBIT(seed) *seed = time(NULL);
5268
#define GEN_SINGLE_BIT(seed) (rand_r(seed) & (1U << 30))
5369
#define PRNG_ADVANCE_BIT prng_advance_bit
5470
static inline BITTYPE PRNG_ADVANCE_BIT(BITSEEDTYPE *seed, size_t delta) {
5571
for (size_t i=0; i<delta; i++)
56-
rand_r(seed);
72+
thread_safe_rand(seed);
5773
return GEN_SINGLE_BIT(seed);
5874
}
5975
#define ADVANCEBIT(seed, thread, nloc) PRNG_ADVANCE_BIT(seed, thread);
6076
#define GENBIT(seed) PRNG_ADVANCE_BIT(seed, nthreads)
61-
#else /* #ifdef _OPENMP */
77+
#else /* #ifdef _OPENMP */
6278
#define INITBIT(seed) srand(time(NULL));
6379
#define GEN_SINGLE_BIT(seed) (rand() & (1U << 30))
6480
#define GENBIT(seed) (GEN_SINGLE_BIT(seed))
6581
#endif /* #ifdef _OPENMP */
66-
#endif /* #ifdef PCG_VARIANTS_H_INCLUDED */
82+
#endif /* #ifdef PCG_VARIANTS_H_INCLUDED */
6783

6884
#define PRNG_BIT_INIT \
6985
if (fpopts->BITSEED == NULL) { \

0 commit comments

Comments
 (0)