From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-4.2 required=3.0 tests=ALL_TRUSTED,BAYES_00, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id 01C951FAF1 for ; Tue, 15 Nov 2022 19:33:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=80x24.org; s=selector1; t=1668540822; bh=KmvaNiZhxCgpszPeiwgb6I+xJIT3mMTh16Xx1ZZG8Rg=; h=From:To:Subject:Date:In-Reply-To:References:From; b=RDV7e86zQAr8QbOZJrvamsjdooEpU01etpTHQ8bm8csZydNzChZgV/q9FyoR2/Y8v LFS/RJRpmKYnCfhbbRFh20ut2yjfeqeSn4rmDKYfHH5QNFcdywfXxuEadj1j6fLydD BKA2zlgv1lv4pqsCaC8dvUg70xO75Abq7Gc0Z7ks= From: Eric Wong To: mwrap-perl@80x24.org Subject: [PATCH 3/6] block signals when spawning URCU-related threads Date: Tue, 15 Nov 2022 19:33:38 +0000 Message-Id: <20221115193341.3948245-4-e@80x24.org> In-Reply-To: <20221115193341.3948245-1-e@80x24.org> References: <20221115193341.3948245-1-e@80x24.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit List-Id: 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. --- Mwrap.xs | 127 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 74 insertions(+), 53 deletions(-) diff --git a/Mwrap.xs b/Mwrap.xs index e87fe30..f441ca8 100644 --- a/Mwrap.xs +++ b/Mwrap.xs @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -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: