summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbg_mlc.c26
-rw-r--r--include/private/gc_priv.h12
-rw-r--r--tests/disclaim_bench.c5
-rw-r--r--tests/disclaim_test.c8
-rw-r--r--tests/disclaim_weakmap_test.c6
5 files changed, 28 insertions, 29 deletions
diff --git a/dbg_mlc.c b/dbg_mlc.c
index b333a128..1ffee0f4 100644
--- a/dbg_mlc.c
+++ b/dbg_mlc.c
@@ -54,23 +54,20 @@
}
#endif /* !SHORT_DBG_HDRS */
+#ifdef KEEP_BACK_PTRS
+
#ifdef LINT2
- long GC_random(void)
+ static int GC_rand(void)
{
- static unsigned seed = 1; /* not thread-safe */
+ static GC_RAND_STATE_T seed;
- /* Linear congruential pseudo-random numbers generator. */
- seed = (seed * 1103515245U + 12345) & GC_RAND_MAX; /* overflow is ok */
- return (long)seed;
+ return GC_RAND_NEXT(&seed);
}
-#endif
-#ifdef KEEP_BACK_PTRS
-
-#ifdef LINT2
-# define RANDOM() GC_random()
+# define RANDOM() (long)GC_rand()
#else
# include <stdlib.h>
+# undef GC_RAND_MAX
# define GC_RAND_MAX RAND_MAX
# if defined(__GLIBC__) || defined(SOLARIS) \
@@ -163,16 +160,17 @@
GC_API void * GC_CALL GC_generate_random_heap_address(void)
{
size_t i;
- word heap_offset = RANDOM();
+ word heap_offset = (word)RANDOM();
- if (GC_heapsize > GC_RAND_MAX) {
+ if (GC_heapsize > (word)GC_RAND_MAX) {
heap_offset *= GC_RAND_MAX;
- heap_offset += RANDOM();
+ heap_offset += (word)RANDOM();
}
heap_offset %= GC_heapsize;
/* This doesn't yield a uniform distribution, especially if */
- /* e.g. RAND_MAX = 1.5* GC_heapsize. But for typical cases, */
+ /* e.g. RAND_MAX is 1.5*GC_heapsize. But for typical cases, */
/* it's not too bad. */
+
for (i = 0;; ++i) {
size_t size;
diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h
index 81fb57b0..74e6c8c9 100644
--- a/include/private/gc_priv.h
+++ b/include/private/gc_priv.h
@@ -2358,10 +2358,14 @@ GC_EXTERN GC_bool GC_have_errors; /* We saw a smashed or leaked object. */
GC_INNER void GC_generate_random_backtrace_no_gc(void);
#endif
-#ifdef LINT2
-# define GC_RAND_MAX (~0U >> 1)
- GC_API_PRIV long GC_random(void);
-#endif
+#if defined(THREADS) || defined(LINT2)
+ /* A trivial (linear congruential) pseudo-random numbers generator, */
+ /* safe for the concurrent usage. */
+# define GC_RAND_STATE_T unsigned
+# define GC_RAND_MAX ((int)(~0U >> 1))
+# define GC_RAND_NEXT(pseed) /* overflow is OK */ \
+ (int)(*(pseed) = (*(pseed) * 1103515245U + 12345) & (unsigned)GC_RAND_MAX)
+#endif /* THREADS || LINT2 */
GC_EXTERN GC_bool GC_print_back_height;
diff --git a/tests/disclaim_bench.c b/tests/disclaim_bench.c
index f665d58d..99c76e27 100644
--- a/tests/disclaim_bench.c
+++ b/tests/disclaim_bench.c
@@ -23,11 +23,12 @@
#include "gc/gc_disclaim.h"
#define NOT_GCBUILD
-#include "private/gc_priv.h" /* for CLOCK_TYPE, COVERT_DATAFLOW, GC_random */
+#include "private/gc_priv.h"
#ifdef LINT2
# undef rand
-# define rand() (int)GC_random()
+ static GC_RAND_STATE_T seed;
+# define rand() GC_RAND_NEXT(&seed)
#endif
#define my_assert(e) \
diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c
index f73c16a7..c6956b54 100644
--- a/tests/disclaim_test.c
+++ b/tests/disclaim_test.c
@@ -33,12 +33,10 @@
# include "private/gc_priv.h"
GC_ATTR_NO_SANITIZE_THREAD
- static int GC_rand(void) /* nearly identical to GC_random */
+ static int GC_rand(void)
{
- static unsigned seed; /* concurrent update does not hurt the test */
-
- seed = (seed * 1103515245U + 12345) & (~0U >> 1);
- return (int)seed;
+ static GC_RAND_STATE_T seed; /* concurrent update does not hurt the test */
+ return GC_RAND_NEXT(&seed);
}
/* Redefine the standard rand() with a trivial (yet sufficient for */
diff --git a/tests/disclaim_weakmap_test.c b/tests/disclaim_weakmap_test.c
index 68f7c6e5..c2dd8e1f 100644
--- a/tests/disclaim_weakmap_test.c
+++ b/tests/disclaim_weakmap_test.c
@@ -32,10 +32,8 @@
GC_ATTR_NO_SANITIZE_THREAD
static int GC_rand(void) /* same as in disclaim_test.c */
{
- static unsigned seed; /* concurrent update does not hurt the test */
-
- seed = (seed * 1103515245U + 12345) & (~0U >> 1);
- return (int)seed;
+ static GC_RAND_STATE_T seed; /* concurrent update does not hurt the test */
+ return GC_RAND_NEXT(&seed);
}
# undef rand