-
Notifications
You must be signed in to change notification settings - Fork 919
Regression testing / Reproducability: Fix MacOS and Linux differences for rand() and qsort() #9574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
b0c0732
2659c14
a21179c
b409ee1
4582997
5997511
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| load("@rules_cc//cc:cc_library.bzl", "cc_library") | ||
|
|
||
| package( | ||
| default_visibility = ["//visibility:public"], | ||
| ) | ||
|
|
||
| # Match glibc functions for platform stable results. The functions are | ||
| # only used on MacOS as linux systems provide these functions by glibc | ||
| # Portable rand()/srand() and qsort() implementation matching glibc's algorithm. | ||
| # Apple's libc rand() produces different sequences for the same seed, | ||
| # causing non-determinism in code using rand() across platforms (e.g., ABC). | ||
| # qsort() from glibc and Apple differ for equal elements causing also | ||
| # non-determinism. | ||
| cc_library( | ||
| name = "portable_rand_qsort", | ||
| srcs = select({ | ||
| # On macOS, override rand()/srand() and qsort() to match glibc's | ||
| # algorithms. Apple's libc uses different algorithms for both, | ||
| # causing non-determinism in code like ABC across platforms. | ||
| # On Linux (glibc), these are already the native implementations. | ||
| "@platforms//os:macos": [ | ||
| "portable_qsort.c", | ||
| "portable_rand.c", | ||
| ], | ||
| "//conditions:default": [], | ||
| }), | ||
| copts = [ | ||
| "-std=c99", | ||
| "-fno-builtin", | ||
| "-w", | ||
| ], | ||
| alwayslink = True, | ||
| ) |
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,187 @@ | ||||||||||
| /* | ||||||||||
| * Portable qsort() implementation matching glibc's msort algorithm. | ||||||||||
| * | ||||||||||
| * glibc's qsort uses a merge sort (which is stable) with a temporary | ||||||||||
| * buffer, falling back to insertion sort for small subarrays. Apple's | ||||||||||
| * libc uses a different algorithm that produces different orderings for | ||||||||||
| * equal elements. This causes non-determinism in ABC's logic synthesis. | ||||||||||
| * | ||||||||||
| * This implements the same algorithm as glibc's stdlib/msort.c to ensure | ||||||||||
| * identical behavior across platforms. | ||||||||||
| * | ||||||||||
| * Source reference: glibc/stdlib/msort.c (LGPL 2.1) | ||||||||||
| * Simplified implementation of the merge sort algorithm used by glibc. | ||||||||||
| */ | ||||||||||
|
|
||||||||||
| #include <stdlib.h> | ||||||||||
| #include <string.h> | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead [modernize-deprecated-headers]
Suggested change
|
||||||||||
|
|
||||||||||
| /* Threshold below which we use insertion sort */ | ||||||||||
| #define INSERTION_THRESHOLD 4 | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: macro 'INSERTION_THRESHOLD' defines an integral constant; prefer an enum instead [modernize-macro-to-enum] #define INSERTION_THRESHOLD 4
^ |
||||||||||
|
|
||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: replace macro with enum [modernize-macro-to-enum]
Suggested change
|
||||||||||
| static void insertion_sort(void *base, size_t nmemb, size_t size, | ||||||||||
| int (*compar)(const void *, const void *)) { | ||||||||||
| char *b = (char *)base; | ||||||||||
| char *tmp = (char *)malloc(size); | ||||||||||
| if (!tmp) | ||||||||||
| return; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||
|
|
||||||||||
| for (size_t i = 1; i < nmemb; i++) { | ||||||||||
| char *key = b + i * size; | ||||||||||
| size_t j = i; | ||||||||||
| while (j > 0 && compar(b + (j - 1) * size, key) > 0) { | ||||||||||
| j--; | ||||||||||
| } | ||||||||||
| if (j != i) { | ||||||||||
| memcpy(tmp, key, size); | ||||||||||
| memmove(b + (j + 1) * size, b + j * size, (i - j) * size); | ||||||||||
| memcpy(b + j * size, tmp, size); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| free(tmp); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| static void merge(char *dst, const char *src1, size_t n1, const char *src2, | ||||||||||
| size_t n2, size_t size, | ||||||||||
| int (*compar)(const void *, const void *)) { | ||||||||||
| while (n1 > 0 && n2 > 0) { | ||||||||||
| if (compar(src1, src2) <= 0) { | ||||||||||
| memcpy(dst, src1, size); | ||||||||||
| src1 += size; | ||||||||||
| n1--; | ||||||||||
| } else { | ||||||||||
| memcpy(dst, src2, size); | ||||||||||
| src2 += size; | ||||||||||
| n2--; | ||||||||||
| } | ||||||||||
| dst += size; | ||||||||||
| } | ||||||||||
| if (n1 > 0) | ||||||||||
| memcpy(dst, src1, n1 * size); | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||
| if (n2 > 0) | ||||||||||
| memcpy(dst, src2, n2 * size); | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||
| } | ||||||||||
|
|
||||||||||
| static void msort_with_tmp(void *base, size_t nmemb, size_t size, | ||||||||||
| int (*compar)(const void *, const void *), | ||||||||||
| char *tmp) { | ||||||||||
| char *b = (char *)base; | ||||||||||
|
|
||||||||||
| if (nmemb <= INSERTION_THRESHOLD) { | ||||||||||
| insertion_sort(base, nmemb, size, compar); | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| size_t n1 = nmemb / 2; | ||||||||||
| size_t n2 = nmemb - n1; | ||||||||||
|
|
||||||||||
| msort_with_tmp(b, n1, size, compar, tmp); | ||||||||||
| msort_with_tmp(b + n1 * size, n2, size, compar, tmp); | ||||||||||
|
|
||||||||||
| /* Merge into tmp, then copy back */ | ||||||||||
| merge(tmp, b, n1, b + n1 * size, n2, size, compar); | ||||||||||
| memcpy(b, tmp, nmemb * size); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void qsort(void *base, size_t nmemb, size_t size, | ||||||||||
| int (*compar)(const void *, const void *)) { | ||||||||||
| if (nmemb < 2) | ||||||||||
| return; | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||
|
|
||||||||||
| char *tmp = (char *)malloc(nmemb * size); | ||||||||||
| if (!tmp) { | ||||||||||
| /* Fallback to insertion sort if malloc fails */ | ||||||||||
| insertion_sort(base, nmemb, size, compar); | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| msort_with_tmp(base, nmemb, size, compar, tmp); | ||||||||||
| free(tmp); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| /* Also provide qsort_r for completeness */ | ||||||||||
| #ifdef __APPLE__ | ||||||||||
| /* macOS qsort_r has a different signature from glibc: | ||||||||||
| * macOS: qsort_r(base, nmemb, size, thunk, compar(thunk, a, b)) | ||||||||||
| * glibc: qsort_r(base, nmemb, size, compar(a, b, thunk), thunk) | ||||||||||
| * We implement the macOS signature since we're overriding on macOS. | ||||||||||
| */ | ||||||||||
| static void insertion_sort_r(void *base, size_t nmemb, size_t size, void *thunk, | ||||||||||
| int (*compar)(void *, const void *, | ||||||||||
| const void *)) { | ||||||||||
| char *b = (char *)base; | ||||||||||
| char *tmp = (char *)malloc(size); | ||||||||||
| if (!tmp) | ||||||||||
| return; | ||||||||||
|
|
||||||||||
| for (size_t i = 1; i < nmemb; i++) { | ||||||||||
| char *key = b + i * size; | ||||||||||
| size_t j = i; | ||||||||||
| while (j > 0 && compar(thunk, b + (j - 1) * size, key) > 0) { | ||||||||||
| j--; | ||||||||||
| } | ||||||||||
| if (j != i) { | ||||||||||
| memcpy(tmp, key, size); | ||||||||||
| memmove(b + (j + 1) * size, b + j * size, (i - j) * size); | ||||||||||
| memcpy(b + j * size, tmp, size); | ||||||||||
| } | ||||||||||
| } | ||||||||||
| free(tmp); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| static void merge_r(char *dst, const char *src1, size_t n1, const char *src2, | ||||||||||
| size_t n2, size_t size, void *thunk, | ||||||||||
| int (*compar)(void *, const void *, const void *)) { | ||||||||||
| while (n1 > 0 && n2 > 0) { | ||||||||||
| if (compar(thunk, src1, src2) <= 0) { | ||||||||||
| memcpy(dst, src1, size); | ||||||||||
| src1 += size; | ||||||||||
| n1--; | ||||||||||
| } else { | ||||||||||
| memcpy(dst, src2, size); | ||||||||||
| src2 += size; | ||||||||||
| n2--; | ||||||||||
| } | ||||||||||
| dst += size; | ||||||||||
| } | ||||||||||
| if (n1 > 0) | ||||||||||
| memcpy(dst, src1, n1 * size); | ||||||||||
| if (n2 > 0) | ||||||||||
| memcpy(dst, src2, n2 * size); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| static void msort_with_tmp_r(void *base, size_t nmemb, size_t size, void *thunk, | ||||||||||
| int (*compar)(void *, const void *, const void *), | ||||||||||
| char *tmp) { | ||||||||||
| char *b = (char *)base; | ||||||||||
|
|
||||||||||
| if (nmemb <= INSERTION_THRESHOLD) { | ||||||||||
| insertion_sort_r(base, nmemb, size, thunk, compar); | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| size_t n1 = nmemb / 2; | ||||||||||
| size_t n2 = nmemb - n1; | ||||||||||
|
|
||||||||||
| msort_with_tmp_r(b, n1, size, thunk, compar, tmp); | ||||||||||
| msort_with_tmp_r(b + n1 * size, n2, size, thunk, compar, tmp); | ||||||||||
|
|
||||||||||
| merge_r(tmp, b, n1, b + n1 * size, n2, size, thunk, compar); | ||||||||||
| memcpy(b, tmp, nmemb * size); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| void qsort_r(void *base, size_t nmemb, size_t size, void *thunk, | ||||||||||
| int (*compar)(void *, const void *, const void *)) { | ||||||||||
| if (nmemb < 2) | ||||||||||
| return; | ||||||||||
|
|
||||||||||
| char *tmp = (char *)malloc(nmemb * size); | ||||||||||
| if (!tmp) { | ||||||||||
| insertion_sort_r(base, nmemb, size, thunk, compar); | ||||||||||
| return; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| msort_with_tmp_r(base, nmemb, size, thunk, compar, tmp); | ||||||||||
| free(tmp); | ||||||||||
| } | ||||||||||
| #endif | ||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,92 @@ | ||||||||||||||||||||||
| /* | ||||||||||||||||||||||
| * Portable rand()/srand() implementation matching glibc's TYPE_3 algorithm. | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * glibc's rand() uses a trinomial feedback shift register (TYPE_3) with | ||||||||||||||||||||||
| * 31 words of state (not the simple LCG often described in textbooks). | ||||||||||||||||||||||
| * Apple's libc uses a completely different algorithm. | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * This implements glibc's exact algorithm from stdlib/random_r.c to ensure | ||||||||||||||||||||||
| * identical rand() sequences across platforms. | ||||||||||||||||||||||
| * | ||||||||||||||||||||||
| * Reference: glibc/stdlib/random_r.c (LGPL 2.1) | ||||||||||||||||||||||
| * TYPE_3: degree 31, separation 3 | ||||||||||||||||||||||
| */ | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| #define DEG_3 31 | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: macro 'DEG_3' defines an integral constant; prefer an enum instead [modernize-macro-to-enum] #define DEG_3 31
^ |
||||||||||||||||||||||
| #define SEP_3 3 | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: macro 'SEP_3' defines an integral constant; prefer an enum instead [modernize-macro-to-enum] #define SEP_3 3
^ |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: replace macro with enum [modernize-macro-to-enum]
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: replace macro with enum [modernize-macro-to-enum]
Suggested change
|
||||||||||||||||||||||
| static unsigned int _state[DEG_3]; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_state', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:24: - _state[0] = seed;
+ state[0] = seed;bazel/glibc_for_apple/portable_rand.c:29: - long long val = (16807LL * (long long)_state[i - 1]) % 2147483647LL;
+ long long val = (16807LL * (long long)state[i - 1]) % 2147483647LL;bazel/glibc_for_apple/portable_rand.c:32: - _state[i] = (unsigned int)val;
+ state[i] = (unsigned int)val;bazel/glibc_for_apple/portable_rand.c:39: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
+ state[_fptr] = (state[_fptr] + state[_rptr]);bazel/glibc_for_apple/portable_rand.c:60: - unsigned int result = _state[_fptr] + _state[_rptr];
- _state[_fptr] = result;
+ unsigned int result = state[_fptr] + state[_rptr];
+ state[_fptr] = result;
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_state', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:23: - _state[0] = seed;
+ state[0] = seed;bazel/glibc_for_apple/portable_rand.c:28: - long long val = (16807LL * (long long)_state[i - 1]) % 2147483647LL;
+ long long val = (16807LL * (long long)state[i - 1]) % 2147483647LL;bazel/glibc_for_apple/portable_rand.c:31: - _state[i] = (unsigned int)val;
+ state[i] = (unsigned int)val;bazel/glibc_for_apple/portable_rand.c:38: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
+ state[_fptr] = (state[_fptr] + state[_rptr]);bazel/glibc_for_apple/portable_rand.c:55: - unsigned int result = _state[_fptr] + _state[_rptr];
- _state[_fptr] = result;
+ unsigned int result = state[_fptr] + state[_rptr];
+ state[_fptr] = result; |
||||||||||||||||||||||
| static int _fptr = SEP_3; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_fptr', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:34: - _fptr = SEP_3;
+ fptr = SEP_3;bazel/glibc_for_apple/portable_rand.c:39: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
- _fptr++;
- if (_fptr >= DEG_3)
- _fptr = 0;
+ _state[fptr] = (_state[fptr] + _state[_rptr]);
+ fptr++;
+ if (fptr >= DEG_3)
+ fptr = 0;bazel/glibc_for_apple/portable_rand.c:60: - unsigned int result = _state[_fptr] + _state[_rptr];
- _state[_fptr] = result;
+ unsigned int result = _state[fptr] + _state[_rptr];
+ _state[fptr] = result;bazel/glibc_for_apple/portable_rand.c:65: - _fptr++;
- if (_fptr >= DEG_3)
- _fptr = 0;
+ fptr++;
+ if (fptr >= DEG_3)
+ fptr = 0;
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_fptr', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:33: - _fptr = SEP_3;
+ fptr = SEP_3;bazel/glibc_for_apple/portable_rand.c:38: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
- _fptr++;
- if (_fptr >= DEG_3)
- _fptr = 0;
+ _state[fptr] = (_state[fptr] + _state[_rptr]);
+ fptr++;
+ if (fptr >= DEG_3)
+ fptr = 0;bazel/glibc_for_apple/portable_rand.c:55: - unsigned int result = _state[_fptr] + _state[_rptr];
- _state[_fptr] = result;
+ unsigned int result = _state[fptr] + _state[_rptr];
+ _state[fptr] = result;bazel/glibc_for_apple/portable_rand.c:60: - _fptr++;
- if (_fptr >= DEG_3)
- _fptr = 0;
+ fptr++;
+ if (fptr >= DEG_3)
+ fptr = 0; |
||||||||||||||||||||||
| static int _rptr = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_rptr', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:35: - _rptr = 0;
+ rptr = 0;bazel/glibc_for_apple/portable_rand.c:39: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
+ _state[_fptr] = (_state[_fptr] + _state[rptr]);bazel/glibc_for_apple/portable_rand.c:43: - _rptr++;
- if (_rptr >= DEG_3)
- _rptr = 0;
+ rptr++;
+ if (rptr >= DEG_3)
+ rptr = 0;bazel/glibc_for_apple/portable_rand.c:60: - unsigned int result = _state[_fptr] + _state[_rptr];
+ unsigned int result = _state[_fptr] + _state[rptr];bazel/glibc_for_apple/portable_rand.c:68: - _rptr++;
- if (_rptr >= DEG_3)
- _rptr = 0;
+ rptr++;
+ if (rptr >= DEG_3)
+ rptr = 0;
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_rptr', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:34: - _rptr = 0;
+ rptr = 0;bazel/glibc_for_apple/portable_rand.c:38: - _state[_fptr] = (_state[_fptr] + _state[_rptr]);
+ _state[_fptr] = (_state[_fptr] + _state[rptr]);bazel/glibc_for_apple/portable_rand.c:42: - _rptr++;
- if (_rptr >= DEG_3)
- _rptr = 0;
+ rptr++;
+ if (rptr >= DEG_3)
+ rptr = 0;bazel/glibc_for_apple/portable_rand.c:55: - unsigned int result = _state[_fptr] + _state[_rptr];
+ unsigned int result = _state[_fptr] + _state[rptr];bazel/glibc_for_apple/portable_rand.c:63: - _rptr++;
- if (_rptr >= DEG_3)
- _rptr = 0;
+ rptr++;
+ if (rptr >= DEG_3)
+ rptr = 0; |
||||||||||||||||||||||
| static int _initialized = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_initialized', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:47: - _initialized = 1;
+ initialized = 1;bazel/glibc_for_apple/portable_rand.c:57: - if (!_initialized)
+ if (!initialized)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_initialized', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:46: - _initialized = 1;
+ initialized = 1;bazel/glibc_for_apple/portable_rand.c:52: - if (!_initialized)
+ if (!initialized) |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| static void _init_state(unsigned int seed) { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: declaration uses identifier '_init_state', which is reserved in the global namespace [bugprone-reserved-identifier]
Suggested change
bazel/glibc_for_apple/portable_rand.c:49: - void srand(unsigned int seed) { _init_state(seed); }
+ void srand(unsigned int seed) { init_state(seed); }bazel/glibc_for_apple/portable_rand.c:53: - _init_state(1);
+ init_state(1); |
||||||||||||||||||||||
| _state[0] = seed; | ||||||||||||||||||||||
| for (int i = 1; i < DEG_3; i++) { | ||||||||||||||||||||||
| /* This is the same initialization as glibc's __srandom_r: | ||||||||||||||||||||||
| * state[i] = (16807 * state[i-1]) % 2147483647 | ||||||||||||||||||||||
| * Using 64-bit arithmetic to avoid overflow */ | ||||||||||||||||||||||
| long long val = (16807LL * (long long)_state[i - 1]) % 2147483647LL; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: consider replacing 'long long' with 'int64_t' [google-runtime-int] long long val = (16807LL * (long long)_state[i - 1]) % 2147483647LL;
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: consider replacing 'long long' with 'int64_t' [google-runtime-int] long long val = (16807LL * (long long)_state[i - 1]) % 2147483647LL;
^ |
||||||||||||||||||||||
| if (val < 0) | ||||||||||||||||||||||
| val += 2147483647LL; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
| _state[i] = (unsigned int)val; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| _fptr = SEP_3; | ||||||||||||||||||||||
| _rptr = 0; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| /* Warmup: 10 * DEG_3 = 310 iterations (matches glibc) */ | ||||||||||||||||||||||
| for (int i = 0; i < 10 * DEG_3; i++) { | ||||||||||||||||||||||
| _state[_fptr] = (_state[_fptr] + _state[_rptr]); | ||||||||||||||||||||||
| _fptr++; | ||||||||||||||||||||||
| if (_fptr >= DEG_3) | ||||||||||||||||||||||
| _fptr = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
| _rptr++; | ||||||||||||||||||||||
| if (_rptr >= DEG_3) | ||||||||||||||||||||||
| _rptr = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| _initialized = 1; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| void srand(unsigned int seed) { _init_state(seed); } | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'srand' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "seed" is directly included [misc-include-cleaner] void srand(unsigned int seed) { _init_state(seed); }
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "srand" is directly included [misc-include-cleaner] bazel/glibc_for_apple/portable_rand.c:14: - #define DEG_3 31
+ #include <cstdlib>
+ #define DEG_3 31 |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| int rand(void) { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'rand' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "rand" is directly included [misc-include-cleaner] int rand(void) {
^
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: redundant void argument list in function definition [modernize-redundant-void-arg]
Suggested change
|
||||||||||||||||||||||
| if (!_initialized) | ||||||||||||||||||||||
| _init_state(1); | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| unsigned int result = _state[_fptr] + _state[_rptr]; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "result" is directly included [misc-include-cleaner] unsigned int result = _state[_fptr] + _state[_rptr];
^ |
||||||||||||||||||||||
| _state[_fptr] = result; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| int ret = (int)((result >> 1) & 0x7fffffffU); | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: no header providing "ret" is directly included [misc-include-cleaner] int ret = (int)((result >> 1) & 0x7fffffffU);
^ |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| _fptr++; | ||||||||||||||||||||||
| if (_fptr >= DEG_3) | ||||||||||||||||||||||
| _fptr = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
| _rptr++; | ||||||||||||||||||||||
| if (_rptr >= DEG_3) | ||||||||||||||||||||||
| _rptr = 0; | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: statement should be inside braces [google-readability-braces-around-statements]
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| return ret; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| int rand_r(unsigned int *seedp) { | ||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warning: function 'rand_r' can be made static or moved into an anonymous namespace to enforce internal linkage [misc-use-internal-linkage]
Suggested change
|
||||||||||||||||||||||
| /* glibc's rand_r uses a different (simpler) algorithm */ | ||||||||||||||||||||||
| unsigned int next = *seedp; | ||||||||||||||||||||||
| int result; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| next *= 1103515245; | ||||||||||||||||||||||
| next += 12345; | ||||||||||||||||||||||
| result = (unsigned int)(next / 65536) % 2048; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| next *= 1103515245; | ||||||||||||||||||||||
| next += 12345; | ||||||||||||||||||||||
| result <<= 10; | ||||||||||||||||||||||
| result ^= (unsigned int)(next / 65536) % 1024; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| next *= 1103515245; | ||||||||||||||||||||||
| next += 12345; | ||||||||||||||||||||||
| result <<= 10; | ||||||||||||||||||||||
| result ^= (unsigned int)(next / 65536) % 1024; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| *seedp = next; | ||||||||||||||||||||||
| return result; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead [modernize-deprecated-headers]