Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ cc_binary(
"@boost.stacktrace",
"@rules_cc//cc/runfiles",
"@tcl_lang//:tcl",
],
] + select({
"@platforms//os:macos": ["//bazel/glibc_for_apple:portable_rand_qsort"],
"//conditions:default": [],
}),
)

GUI_BUILD_FLAGS = select(
Expand Down
33 changes: 33 additions & 0 deletions bazel/glibc_for_apple/BUILD
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,
)
187 changes: 187 additions & 0 deletions bazel/glibc_for_apple/portable_qsort.c
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>

Copy link
Copy Markdown
Contributor

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]

Suggested change
#include <stdlib.h>
#include <cstdlib>

#include <string.h>

Copy link
Copy Markdown
Contributor

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 'string.h'; consider using 'cstring' instead [modernize-deprecated-headers]

Suggested change
#include <string.h>
#include <cstring>


/* Threshold below which we use insertion sort */
#define INSERTION_THRESHOLD 4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
        ^


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: replace macro with enum [modernize-macro-to-enum]

Suggested change
enum {
INSERTION_THRESHOLD = 4};

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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;
if (!tmp) {
return;
}


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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
memcpy(dst, src1, n1 * size);
if (n1 > 0) {
memcpy(dst, src1, n1 * size);
}

if (n2 > 0)
memcpy(dst, src2, n2 * size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
memcpy(dst, src2, n2 * size);
if (n2 > 0) {
memcpy(dst, src2, n2 * size);
}

}

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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;
if (nmemb < 2) {
return;
}


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
92 changes: 92 additions & 0 deletions bazel/glibc_for_apple/portable_rand.c
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
        ^


Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: replace macro with enum [modernize-macro-to-enum]

Suggested change
enum {
DEG_3 = 31,
SEP_3 = 3};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

warning: replace macro with enum [modernize-macro-to-enum]

Suggested change
enum {
DEG_3 = 31,
SEP_3 = 3};

static unsigned int _state[DEG_3];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static unsigned int _state[DEG_3];
static unsigned int state[DEG_3];

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static unsigned int _state[DEG_3];
static unsigned int state[DEG_3];

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _fptr = SEP_3;
static int fptr = SEP_3;

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _fptr = SEP_3;
static int fptr = SEP_3;

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _rptr = 0;
static int rptr = 0;

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _rptr = 0;
static int rptr = 0;

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _initialized = 0;
static int initialized = 0;

bazel/glibc_for_apple/portable_rand.c:47:

-     _initialized = 1;
+     initialized = 1;

bazel/glibc_for_apple/portable_rand.c:57:

-     if (!_initialized)
+     if (!initialized)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static int _initialized = 0;
static int initialized = 0;

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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
static void _init_state(unsigned int seed) {
static void init_state(unsigned int seed) {

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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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;
                                ^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
val += 2147483647LL;
if (val < 0) {
val += 2147483647LL;
}

_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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
_fptr = 0;
if (_fptr >= DEG_3) {
_fptr = 0;
}

_rptr++;
if (_rptr >= DEG_3)
_rptr = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 = 0;
if (_rptr >= DEG_3) {
_rptr = 0;
}

}
_initialized = 1;
}

void srand(unsigned int seed) { _init_state(seed); }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
void srand(unsigned int seed) { _init_state(seed); }
static void srand(unsigned int seed) { _init_state(seed); }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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); }
                                            ^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
int rand(void) {
static int rand(void) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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) {
    ^

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
int rand(void) {
int rand() {

if (!_initialized)
_init_state(1);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
_init_state(1);
if (!_initialized) {
_init_state(1);
}


unsigned int result = _state[_fptr] + _state[_rptr];

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
_fptr = 0;
if (_fptr >= DEG_3) {
_fptr = 0;
}

_rptr++;
if (_rptr >= DEG_3)
_rptr = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 = 0;
if (_rptr >= DEG_3) {
_rptr = 0;
}


return ret;
}

int rand_r(unsigned int *seedp) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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
int rand_r(unsigned int *seedp) {
static int rand_r(unsigned int *seedp) {

/* 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;
}
10 changes: 6 additions & 4 deletions src/gpl/src/nesterovBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1896,8 +1896,6 @@ NesterovBase::NesterovBase(
"---- Initialize Nesterov Region: {}",
pb_->getGroup() ? pb_->getGroup()->getName() : "Top-level");

// Set a fixed seed
srand(42);
// area update from pb
stdInstsArea_ = pb_->stdInstsArea();
macroInstsArea_ = pb_->macroInstsArea();
Expand All @@ -1909,10 +1907,14 @@ NesterovBase::NesterovBase(

nb_gcells_.reserve(pb_->getInsts().size() + fillerStor_.size());

// Use mt19937 instead of rand() for cross-platform determinism
// (rand() produces different sequences on glibc vs Apple libc)
std::mt19937 offsetRng(42);

// add place instances
for (auto& pb_inst : pb_->placeInsts()) {
int x_offset = rand() % (2 * dbu_per_micron) - dbu_per_micron;
int y_offset = rand() % (2 * dbu_per_micron) - dbu_per_micron;
int x_offset = offsetRng() % (2 * dbu_per_micron) - dbu_per_micron;
int y_offset = offsetRng() % (2 * dbu_per_micron) - dbu_per_micron;

GCell* gCell = nbc_->pbToNb(pb_inst);
if (pb_inst != gCell->insts()[0]) {
Expand Down
Loading
Loading