Skip to content

Commit 5e6f4cf

Browse files
committed
Merge pull request #1939 from tinysun212/pr-portable-random
2 parents 37f5a03 + 5c1854b commit 5e6f4cf

File tree

4 files changed

+22
-13
lines changed

4 files changed

+22
-13
lines changed

stdlib/private/SwiftPrivate/PRNG.swift

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,18 @@
1212

1313
import SwiftShims
1414

15-
@inline(never) @_semantics("stdlib_binary_only") // Hide the libbsd dependency
1615
public func rand32() -> UInt32 {
17-
return _swift_stdlib_arc4random()
16+
return _swift_stdlib_cxx11_mt19937()
1817
}
1918

20-
@inline(never) @_semantics("stdlib_binary_only") // Hide the libbsd dependency
2119
public func rand32(exclusiveUpperBound limit: UInt32) -> UInt32 {
22-
return _swift_stdlib_arc4random_uniform(limit)
20+
return _swift_stdlib_cxx11_mt19937_uniform(limit)
2321
}
2422

25-
@inline(never) @_semantics("stdlib_binary_only") // Hide the libbsd dependency
2623
public func rand64() -> UInt64 {
2724
return
28-
(UInt64(_swift_stdlib_arc4random()) << 32) |
29-
UInt64(_swift_stdlib_arc4random())
25+
(UInt64(_swift_stdlib_cxx11_mt19937()) << 32) |
26+
UInt64(_swift_stdlib_cxx11_mt19937())
3027
}
3128

3229
public func randInt() -> Int {

stdlib/public/SwiftShims/LibcShims.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,13 @@ int _swift_stdlib_close(int fd);
6969
__attribute__((const))
7070
SWIFT_RUNTIME_STDLIB_INTERFACE
7171
__swift_size_t _swift_stdlib_malloc_size(const void *ptr);
72+
73+
// Random number <random>
7274
SWIFT_RUNTIME_STDLIB_INTERFACE
73-
__swift_uint32_t _swift_stdlib_arc4random(void);
75+
__swift_uint32_t _swift_stdlib_cxx11_mt19937(void);
7476
SWIFT_RUNTIME_STDLIB_INTERFACE
75-
__swift_uint32_t _swift_stdlib_arc4random_uniform(__swift_uint32_t upper_bound);
77+
__swift_uint32_t
78+
_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound);
7679

7780
#ifdef __cplusplus
7881
}} // extern "C", namespace swift

stdlib/public/stubs/LibcShims.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13+
#include <random>
1314
#include <type_traits>
1415
#include <unistd.h>
1516
#include <stdlib.h>
@@ -69,11 +70,19 @@ size_t _swift_stdlib_malloc_size(const void *ptr) {
6970
#error No malloc_size analog known for this platform/libc.
7071
#endif
7172

72-
__swift_uint32_t _swift_stdlib_arc4random(void) { return arc4random(); }
73+
static std::random_device RandomeDevice;
74+
static std::mt19937 MersenneRandom(RandomeDevice());
75+
76+
__swift_uint32_t _swift_stdlib_cxx11_mt19937(void) {
77+
return MersenneRandom();
78+
}
7379

7480
__swift_uint32_t
75-
_swift_stdlib_arc4random_uniform(__swift_uint32_t upper_bound) {
76-
return arc4random_uniform(upper_bound);
81+
_swift_stdlib_cxx11_mt19937_uniform(__swift_uint32_t upper_bound) {
82+
if (upper_bound > 0)
83+
upper_bound--;
84+
std::uniform_int_distribution<__swift_uint32_t> RandomUniform(0, upper_bound);
85+
return RandomUniform(MersenneRandom);
7786
}
7887

7988
} // namespace swift

validation-test/stdlib/Set.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ func helperDeleteThree(k1: TestKeyTy, _ k2: TestKeyTy, _ k3: TestKeyTy) {
105105
}
106106

107107
func uniformRandom(max: Int) -> Int {
108-
return Int(arc4random_uniform(UInt32(max)))
108+
return Int(rand32(exclusiveUpperBound: UInt32(max)))
109109
}
110110

111111
func pickRandom<T>(a: [T]) -> T {

0 commit comments

Comments
 (0)