summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-01-15 00:23:08 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-01-15 00:23:08 +0300
commit457b0241f1a2bfbee6f5257a5c9646e944d406d2 (patch)
tree914a628c4263da6650022cd59725153f034e97ef /tests
parent2cc754be36bd2560a3e6f468f5039cf00e4230d1 (diff)
downloadbdwgc-457b0241f1a2bfbee6f5257a5c9646e944d406d2.tar.gz
Workaround crash in FreeBSD rand() by avoiding its concurrent usage
Issue #414 (bdwgc). The standard specifies rand() as not a thread-safe API function. Thus, the concurrent usage of libc rand() should be avoided. Redefine the standard rand() in disclaim_[weakmap_]test with a trivial (yet sufficient for the test purpose) implementation to avoid crashes inside rand() on some targets (e.g. FreeBSD 13.0). * tests/disclaim_test.c [LINT2] (GC_API_PRIV): Do not define. * tests/disclaim_weakmap_test.c [LINT2] (GC_API_PRIV): Likewise. * tests/disclaim_test.c [LINT2] (GC_random): Do not declare. * tests/disclaim_weakmap_test.c [LINT2] (GC_random): Likewise. * tests/disclaim_test.c [GC_PTHREADS || LINT2] (NOT_GCBUILD): Define. * tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2] (NOT_GCBUILD): Likewise. * tests/disclaim_test.c [GC_PTHREADS || LINT2]: Include gc_priv.h. * tests/disclaim_test.c [GC_PTHREADS || LINT2] (GC_rand): New static function. * tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2] (GC_rand): Likewise. * tests/disclaim_test.c [GC_PTHREADS || LINT2] (rand): Define to GC_rand() (instead of (int)GC_random()); add comment. * tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2] (rand): Likewise. * tests/disclaim_weakmap_test.c [GC_PTHREADS || LINT2]: Include gc_priv.h before gc/gc_mark.h; add comment.
Diffstat (limited to 'tests')
-rw-r--r--tests/disclaim_test.c33
-rw-r--r--tests/disclaim_weakmap_test.c36
2 files changed, 38 insertions, 31 deletions
diff --git a/tests/disclaim_test.c b/tests/disclaim_test.c
index 7dca517b..f73c16a7 100644
--- a/tests/disclaim_test.c
+++ b/tests/disclaim_test.c
@@ -28,21 +28,26 @@
#undef GC_NO_THREAD_REDIRECTS
#include "gc/gc_disclaim.h"
-#ifdef LINT2
- /* Avoid include gc_priv.h. */
-# ifndef GC_API_PRIV
-# define GC_API_PRIV GC_API
-# endif
-# ifdef __cplusplus
- extern "C" {
-# endif
- GC_API_PRIV long GC_random(void);
-# ifdef __cplusplus
- } /* extern "C" */
-# endif
+#if defined(GC_PTHREADS) || defined(LINT2)
+# define NOT_GCBUILD
+# include "private/gc_priv.h"
+
+ GC_ATTR_NO_SANITIZE_THREAD
+ static int GC_rand(void) /* nearly identical to GC_random */
+ {
+ static unsigned seed; /* concurrent update does not hurt the test */
+
+ seed = (seed * 1103515245U + 12345) & (~0U >> 1);
+ return (int)seed;
+ }
+
+ /* Redefine the standard rand() with a trivial (yet sufficient for */
+ /* the test purpose) implementation to avoid crashes inside rand() */
+ /* on some targets (e.g. FreeBSD 13.0) when used concurrently. */
+ /* The standard specifies rand() as not a thread-safe API function. */
# undef rand
-# define rand() (int)GC_random()
-#endif /* LINT2 */
+# define rand() GC_rand()
+#endif /* GC_PTHREADS || LINT2 */
#define my_assert(e) \
if (!(e)) { \
diff --git a/tests/disclaim_weakmap_test.c b/tests/disclaim_weakmap_test.c
index a42695fd..68f7c6e5 100644
--- a/tests/disclaim_weakmap_test.c
+++ b/tests/disclaim_weakmap_test.c
@@ -24,7 +24,25 @@
#endif
#include "gc/gc_disclaim.h" /* includes gc.h */
-#include "gc/gc_mark.h"
+
+#if defined(GC_PTHREADS) || defined(LINT2)
+# define NOT_GCBUILD
+# include "private/gc_priv.h"
+
+ 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;
+ }
+
+# undef rand
+# define rand() GC_rand()
+#endif /* GC_PTHREADS || LINT2 */
+
+#include "gc/gc_mark.h" /* should not precede include gc_priv.h */
#ifdef GC_PTHREADS
# ifndef NTHREADS
@@ -39,22 +57,6 @@
# define AO_t GC_word
#endif
-#ifdef LINT2
- /* Avoid include gc_priv.h. */
-# ifndef GC_API_PRIV
-# define GC_API_PRIV GC_API
-# endif
-# ifdef __cplusplus
- extern "C" {
-# endif
- GC_API_PRIV long GC_random(void);
-# ifdef __cplusplus
- } /* extern "C" */
-# endif
-# undef rand
-# define rand() (int)GC_random()
-#endif /* LINT2 */
-
#define POP_SIZE 200
#define MUTATE_CNT (5000000 / NTHREADS)
#define GROW_LIMIT (MUTATE_CNT / 10)