diff options
author | Eric Wong <e@80x24.org> | 2022-11-15 19:33:38 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2022-11-16 09:25:11 +0000 |
commit | f2521869d0a411a8d3a79c3961895a40eafa2b06 (patch) | |
tree | 641f14d492ca4f87aa30292b21f6d4adf878608b | |
parent | dfd859ad96e8d6da4943c770f307d56558588fe7 (diff) | |
download | mwrap-f2521869d0a411a8d3a79c3961895a40eafa2b06.tar.gz |
rculfhash, call_rcu, and urcu-bp will spawn background threads. Ensure we spawn all of these threads while signals are blocked since the underlying codebase may block signals and rely on signalfd.
-rw-r--r-- | Mwrap.xs | 127 |
1 files changed, 74 insertions, 53 deletions
@@ -21,6 +21,7 @@ #include <sys/stat.h> #include <fcntl.h> #include <pthread.h> +#include <signal.h> #include <urcu-bp.h> #include <urcu/rculfhash.h> #include <urcu/rculist.h> @@ -101,60 +102,9 @@ static pthread_mutex_t *mutex_assign(void) return &mutexes[uatomic_add_return(&mutex_i, 1) & MUTEX_MASK].mtx; } -static struct cds_lfht * -lfht_new(void) +static struct cds_lfht *lfht_new(void) { - return cds_lfht_new(16384, 1, 0, CDS_LFHT_AUTO_RESIZE, 0); -} - -__attribute__((constructor)) static void resolve_malloc(void) -{ - int err; - - ++locating; - - /* - * 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++) { - err = pthread_mutex_init(&mutexes[i].mtx, 0); - if (err) { - fprintf(stderr, "error: %s\n", strerror(err)); - _exit(1); - } - } - /* 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__ */ - } - CMM_STORE_SHARED(totals, lfht_new()); - if (!CMM_LOAD_SHARED(totals)) - fprintf(stderr, "failed to allocate totals table\n"); - - err = pthread_atfork(call_rcu_before_fork, - call_rcu_after_fork_parent, - call_rcu_after_fork_child); - if (err) - fprintf(stderr, "pthread_atfork failed: %s\n", strerror(err)); - page_size = sysconf(_SC_PAGESIZE); - --locating; + return cds_lfht_new(8192, 1, 0, CDS_LFHT_AUTO_RESIZE, 0); } #ifdef NDEBUG @@ -807,6 +757,77 @@ out: --locating; } +__attribute__((constructor)) static void mwrap_ctor(void) +{ + sigset_t set, old; + struct alloc_hdr *h; + int err; + + ++locating; + + /* block signals */ + err = sigfillset(&set); + assert(err == 0); + err = pthread_sigmask(SIG_SETMASK, &set, &old); + assert(err == 0); + + page_size = sysconf(_SC_PAGESIZE); + /* + * 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++) { + err = pthread_mutex_init(&mutexes[i].mtx, 0); + if (err) { + fprintf(stderr, "error: %s\n", strerror(err)); + _exit(1); + } + } + /* 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__ */ + } + CMM_STORE_SHARED(totals, lfht_new()); + if (!CMM_LOAD_SHARED(totals)) { + fprintf(stderr, "failed to allocate `totals' table\n"); + abort(); + } + h = real_malloc(sizeof(struct alloc_hdr)); + if (h) { /* force call_rcu to start background thread */ + h->real = h; + call_rcu(&h->as.dead, free_hdr_rcu); + } else + fprintf(stderr, "malloc failed: %s\n", strerror(errno)); + + /* start more background threads before unblocking signals */ + cds_lfht_resize(CMM_LOAD_SHARED(totals), 16384); + err = pthread_sigmask(SIG_SETMASK, &old, NULL); + assert(err == 0); + err = pthread_atfork(call_rcu_before_fork, + call_rcu_after_fork_parent, + call_rcu_after_fork_child); + if (err) + fprintf(stderr, "pthread_atfork failed: %s\n", strerror(err)); + + --locating; +} + MODULE = Devel::Mwrap PACKAGE = Devel::Mwrap PREFIX = mwrap_ BOOT: |