about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <mwrap-perl@80x24.org>2022-09-03 11:18:26 +0000
committerEric Wong <e@80x24.org>2022-09-04 07:02:06 +0000
commit9bcc1941eda378225f3a1b16ffd699365cbd8742 (patch)
tree8dff501339568f3a13543caedbf2bceeff9fe01e
parent38c97ffc04d3254cdc64bc46bf6b28c016599037 (diff)
downloadmwrap-9bcc1941eda378225f3a1b16ffd699365cbd8742.tar.gz
This is to keep up with the Ruby version.
-rw-r--r--Mwrap.xs35
1 files changed, 21 insertions, 14 deletions
diff --git a/Mwrap.xs b/Mwrap.xs
index e888a1c..bec4664 100644
--- a/Mwrap.xs
+++ b/Mwrap.xs
@@ -84,9 +84,16 @@ union padded_mutex {
 /* a round-robin pool of mutexes */
 #define MUTEX_NR   (1 << 6)
 #define MUTEX_MASK (MUTEX_NR - 1)
+#ifdef __FreeBSD__
+#  define STATIC_MTX_INIT_OK (0)
+#else /* only tested on Linux + glibc */
+#  define STATIC_MTX_INIT_OK (1)
+#endif
 static size_t mutex_i;
 static union padded_mutex mutexes[MUTEX_NR] = {
+#if STATIC_MTX_INIT_OK
         [0 ... (MUTEX_NR-1)].mtx = PTHREAD_MUTEX_INITIALIZER
+#endif
 };
 
 static pthread_mutex_t *mutex_assign(void)
@@ -106,12 +113,11 @@ __attribute__((constructor)) static void resolve_malloc(void)
 
         ++locating;
 
-#ifdef __FreeBSD__
         /*
          * PTHREAD_MUTEX_INITIALIZER on FreeBSD means lazy initialization,
          * which happens at pthread_mutex_lock, and that calls calloc
          */
-        {
+        if (!STATIC_MTX_INIT_OK) {
                 size_t i;
 
                 for (i = 0; i < MUTEX_NR; i++) {
@@ -124,19 +130,20 @@ __attribute__((constructor)) static void resolve_malloc(void)
                 /* initialize mutexes used by urcu-bp */
                 rcu_read_lock();
                 rcu_read_unlock();
+#ifndef __FreeBSD__
+        } else {
+                if (!real_malloc) {
+                        resolving_malloc = 1;
+                        real_malloc = dlsym(RTLD_NEXT, "malloc");
+                }
+                real_free = dlsym(RTLD_NEXT, "free");
+                if (!real_malloc || !real_free) {
+                        fprintf(stderr, "missing malloc/aligned_alloc/free\n"
+                                "\t%p %p\n", real_malloc, real_free);
+                        _exit(1);
+                }
+#endif /* !__FreeBSD__ */
         }
-#else /* !FreeBSD (tested on GNU/Linux) */
-        if (!real_malloc) {
-                resolving_malloc = 1;
-                real_malloc = dlsym(RTLD_NEXT, "malloc");
-        }
-        real_free = dlsym(RTLD_NEXT, "free");
-        if (!real_malloc || !real_free) {
-                fprintf(stderr, "missing malloc/aligned_alloc/free\n"
-                        "\t%p %p\n", real_malloc, real_free);
-                _exit(1);
-        }
-#endif /* !FreeBSD */
         err = pthread_atfork(call_rcu_before_fork,
                                 call_rcu_after_fork_parent,
                                 call_rcu_after_fork_child);