From patchwork Tue Aug 8 11:17:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 1818582 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RKrJB0GCZz1yfh for ; Tue, 8 Aug 2023 21:17:29 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id E668C385772F for ; Tue, 8 Aug 2023 11:17:27 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from sonata.ens-lyon.org (domu-toccata.ens-lyon.fr [140.77.166.138]) by sourceware.org (Postfix) with ESMTPS id 431A73857B9B for ; Tue, 8 Aug 2023 11:17:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 431A73857B9B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=bounce.ens-lyon.org Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id D5F222010E; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from sonata.ens-lyon.org ([127.0.0.1]) by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id VivpM_xxQVdl; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from begin.home (lfbn-bor-1-1163-184.w92-158.abo.wanadoo.fr [92.158.138.184]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by sonata.ens-lyon.org (Postfix) with ESMTPSA id 796502010A; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from samy by begin.home with local (Exim 4.96) (envelope-from ) id 1qTKi7-008oSF-1n; Tue, 08 Aug 2023 13:17:11 +0200 From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Samuel Thibault , commit-hurd@gnu.org Subject: [hurd,commited 1/2] htl: Add support for static TSD data Date: Tue, 8 Aug 2023 13:17:10 +0200 Message-Id: <20230808111711.2100557-2-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230808111711.2100557-1-samuel.thibault@ens-lyon.org> References: <20230808111711.2100557-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" When using jemalloc, malloc() needs to use TSD, while libpthread initialization needs malloc(). Supporting a static TSD area allows jemalloc and libpthread to initialize together. --- sysdeps/htl/pt-destroy-specific.c | 35 ++++++++++++++++++++++++++----- sysdeps/htl/pt-getspecific.c | 8 +++++++ sysdeps/htl/pt-init-specific.c | 2 ++ sysdeps/htl/pt-key-create.c | 25 +++++++++++++++------- sysdeps/htl/pt-key-delete.c | 12 +++++++++-- sysdeps/htl/pt-key.h | 7 ++++++- sysdeps/htl/pt-setspecific.c | 26 +++++++++++++++++++++-- 7 files changed, 97 insertions(+), 18 deletions(-) diff --git a/sysdeps/htl/pt-destroy-specific.c b/sysdeps/htl/pt-destroy-specific.c index 7c1acb5068..6d1ad6baed 100644 --- a/sysdeps/htl/pt-destroy-specific.c +++ b/sysdeps/htl/pt-destroy-specific.c @@ -29,7 +29,16 @@ __pthread_destroy_specific (struct __pthread *thread) /* Check if there is any thread specific data. */ if (thread->thread_specifics == NULL) - return; + { + for (i = 0; i < PTHREAD_STATIC_KEYS; i++) + { + if (thread->static_thread_specifics[i] != NULL) + break; + } + + if (i == PTHREAD_STATIC_KEYS) + return; + } __pthread_key_lock_ready (); @@ -40,18 +49,32 @@ __pthread_destroy_specific (struct __pthread *thread) __pthread_mutex_lock (&__pthread_key_lock); - for (i = 0; i < __pthread_key_count && i < thread->thread_specifics_size; - i++) + for (i = 0; i < __pthread_key_count; i++) { void *value; if (__pthread_key_destructors[i] == PTHREAD_KEY_INVALID) continue; - value = thread->thread_specifics[i]; + if (thread->thread_specifics == NULL) + { + if (i >= PTHREAD_STATIC_KEYS) + break; + value = thread->static_thread_specifics[i]; + } + else + { + if (i >= thread->thread_specifics_size) + break; + value = thread->thread_specifics[i]; + } + if (value != NULL) { - thread->thread_specifics[i] = 0; + if (thread->thread_specifics == NULL) + thread->static_thread_specifics[i] = 0; + else + thread->thread_specifics[i] = 0; if (__pthread_key_destructors[i]) { @@ -74,4 +97,6 @@ __pthread_destroy_specific (struct __pthread *thread) free (thread->thread_specifics); thread->thread_specifics = 0; thread->thread_specifics_size = 0; + memset (&thread->static_thread_specifics, 0, + sizeof (thread->static_thread_specifics)); } diff --git a/sysdeps/htl/pt-getspecific.c b/sysdeps/htl/pt-getspecific.c index 68a2503563..4d42cba93d 100644 --- a/sysdeps/htl/pt-getspecific.c +++ b/sysdeps/htl/pt-getspecific.c @@ -29,6 +29,14 @@ __pthread_getspecific (pthread_key_t key) return NULL; self = _pthread_self (); + + if (self->thread_specifics == NULL) + { + if (key >= PTHREAD_STATIC_KEYS) + return NULL; + return self->static_thread_specifics[key]; + } + if (key >= self->thread_specifics_size) return 0; diff --git a/sysdeps/htl/pt-init-specific.c b/sysdeps/htl/pt-init-specific.c index 8c4d23cb13..ed6c6f2d0c 100644 --- a/sysdeps/htl/pt-init-specific.c +++ b/sysdeps/htl/pt-init-specific.c @@ -26,5 +26,7 @@ __pthread_init_specific (struct __pthread *thread) { thread->thread_specifics = 0; thread->thread_specifics_size = 0; + memset (&thread->static_thread_specifics, 0, + sizeof (thread->static_thread_specifics)); return 0; } diff --git a/sysdeps/htl/pt-key-create.c b/sysdeps/htl/pt-key-create.c index 51c0ef72b8..b7057434e3 100644 --- a/sysdeps/htl/pt-key-create.c +++ b/sysdeps/htl/pt-key-create.c @@ -26,10 +26,11 @@ pthread_mutex_t __pthread_key_lock; pthread_once_t __pthread_key_once = PTHREAD_ONCE_INIT; -void (**__pthread_key_destructors) (void *arg); -int __pthread_key_size; +void (*__pthread_static_key_destructors [PTHREAD_STATIC_KEYS]) (void *arg); +void (**__pthread_key_destructors) (void *arg) = __pthread_static_key_destructors; +int __pthread_key_size = PTHREAD_STATIC_KEYS; int __pthread_key_count; -int __pthread_key_invalid_count; +int __pthread_key_invalid_count = PTHREAD_STATIC_KEYS; int __pthread_key_create (pthread_key_t *key, void (*destructor) (void *)) @@ -80,13 +81,21 @@ do_search: void *t; int newsize; - if (__pthread_key_size == 0) - newsize = 8; + newsize = __pthread_key_size * 2; + + if (__pthread_key_destructors == __pthread_static_key_destructors) + { + /* We were still using the static array. Switch to dynamic. */ + t = malloc (newsize * sizeof (*__pthread_key_destructors)); + + if (t != NULL) + memcpy (t, __pthread_key_destructors, + __pthread_key_size * sizeof (*__pthread_key_destructors)); + } else - newsize = __pthread_key_size * 2; + t = realloc (__pthread_key_destructors, + newsize * sizeof (*__pthread_key_destructors)); - t = realloc (__pthread_key_destructors, - newsize * sizeof (*__pthread_key_destructors)); if (t == NULL) { __pthread_mutex_unlock (&__pthread_key_lock); diff --git a/sysdeps/htl/pt-key-delete.c b/sysdeps/htl/pt-key-delete.c index ce77a573c2..6d128d2aaf 100644 --- a/sysdeps/htl/pt-key-delete.c +++ b/sysdeps/htl/pt-key-delete.c @@ -51,8 +51,16 @@ __pthread_key_delete (pthread_key_t key) /* Just remove the key, no need to care whether it was already there. */ - if (key < t->thread_specifics_size) - t->thread_specifics[key] = 0; + if (t->thread_specifics == NULL) + { + if (key < PTHREAD_STATIC_KEYS) + t->static_thread_specifics[key] = 0; + } + else + { + if (key < t->thread_specifics_size) + t->thread_specifics[key] = 0; + } } __libc_rwlock_unlock (GL (dl_pthread_threads_lock)); } diff --git a/sysdeps/htl/pt-key.h b/sysdeps/htl/pt-key.h index 262006de9f..047b7e24ba 100644 --- a/sysdeps/htl/pt-key.h +++ b/sysdeps/htl/pt-key.h @@ -20,9 +20,14 @@ #include #include +/* When using e.g. jemalloc, we need to be able to create and use keys before + being able to allocate. */ +#define PTHREAD_STATIC_KEYS 4 + #define PTHREAD_KEY_MEMBERS \ void **thread_specifics; /* This is only resized by the thread, and always growing */ \ - unsigned thread_specifics_size; /* Number of entries in thread_specifics */ + unsigned thread_specifics_size; /* Number of entries in thread_specifics */ \ + void *static_thread_specifics[PTHREAD_STATIC_KEYS]; /* Static storage for a few entries */ #define PTHREAD_KEY_INVALID (void *) (-1) diff --git a/sysdeps/htl/pt-setspecific.c b/sysdeps/htl/pt-setspecific.c index 2b9a89dc70..30550e09c7 100644 --- a/sysdeps/htl/pt-setspecific.c +++ b/sysdeps/htl/pt-setspecific.c @@ -28,12 +28,34 @@ __pthread_setspecific (pthread_key_t key, const void *value) if (key < 0 || key >= __pthread_key_count) return EINVAL; + if (self->thread_specifics == NULL) + { + if (key < PTHREAD_STATIC_KEYS) + { + self->static_thread_specifics[key] = (void *) value; + return 0; + } + } + if (key >= self->thread_specifics_size) { /* Amortize reallocation cost. */ int newsize = 2 * key + 1; - void **new = realloc (self->thread_specifics, - newsize * sizeof (new[0])); + void **new; + + if (self->thread_specifics == NULL) + { + self->thread_specifics_size = PTHREAD_STATIC_KEYS; + new = malloc (newsize * sizeof (new[0])); + if (new != NULL) + memcpy (new, self->static_thread_specifics, + PTHREAD_STATIC_KEYS * sizeof (new[0])); + } + else + { + new = realloc (self->thread_specifics, + newsize * sizeof (new[0])); + } if (new == NULL) return ENOMEM; From patchwork Tue Aug 8 11:17:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Samuel Thibault X-Patchwork-Id: 1818583 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org; receiver=) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RKrJd58hrz1yVt for ; Tue, 8 Aug 2023 21:17:53 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id BD092385772D for ; Tue, 8 Aug 2023 11:17:51 +0000 (GMT) X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from sonata.ens-lyon.org (sonata.ens-lyon.org [140.77.166.138]) by sourceware.org (Postfix) with ESMTPS id 28092385700C for ; Tue, 8 Aug 2023 11:17:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 28092385700C Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ens-lyon.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=bounce.ens-lyon.org Received: from localhost (localhost [127.0.0.1]) by sonata.ens-lyon.org (Postfix) with ESMTP id D19D22010B; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from sonata.ens-lyon.org ([127.0.0.1]) by localhost (sonata.ens-lyon.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id oArPmGs8dxx2; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from begin.home (lfbn-bor-1-1163-184.w92-158.abo.wanadoo.fr [92.158.138.184]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by sonata.ens-lyon.org (Postfix) with ESMTPSA id 6A08320107; Tue, 8 Aug 2023 13:17:12 +0200 (CEST) Received: from samy by begin.home with local (Exim 4.96) (envelope-from ) id 1qTKi7-008oSI-1q; Tue, 08 Aug 2023 13:17:11 +0200 From: Samuel Thibault To: libc-alpha@sourceware.org Cc: Samuel Thibault , commit-hurd@gnu.org Subject: [hurd,commited 2/2] htl: Initialize ___pthread_self early Date: Tue, 8 Aug 2023 13:17:11 +0200 Message-Id: <20230808111711.2100557-3-samuel.thibault@ens-lyon.org> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230808111711.2100557-1-samuel.thibault@ens-lyon.org> References: <20230808111711.2100557-1-samuel.thibault@ens-lyon.org> MIME-Version: 1.0 X-Spam-Status: No, score=-13.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: libc-alpha-bounces+incoming=patchwork.ozlabs.org@sourceware.org Sender: "Libc-alpha" When using jemalloc, malloc() needs to use TSD, while libpthread initialization needs malloc(). Having ___pthread_self set early to some static storage allows TSD to work early, thus allowing jemalloc and libpthread to initialize together. This incidentaly simplifies __pthread_enable/disable_asynccancel and __pthread_self, now that ___pthread_self is always initialized. --- htl/cancellation.c | 8 -------- htl/pt-self.c | 10 +--------- sysdeps/mach/hurd/htl/pt-sysdep.c | 14 ++++++++++++++ 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/htl/cancellation.c b/htl/cancellation.c index 9cc61b9f23..5a67083188 100644 --- a/htl/cancellation.c +++ b/htl/cancellation.c @@ -25,10 +25,6 @@ int __pthread_enable_asynccancel (void) struct __pthread *p = _pthread_self (); int oldtype; - if (___pthread_self == NULL) - /* We are not initialized yet, we can't be cancelled anyway. */ - return PTHREAD_CANCEL_DEFERRED; - __pthread_mutex_lock (&p->cancel_lock); oldtype = p->cancel_type; p->cancel_type = PTHREAD_CANCEL_ASYNCHRONOUS; @@ -43,10 +39,6 @@ void __pthread_disable_asynccancel (int oldtype) { struct __pthread *p = _pthread_self (); - if (___pthread_self == NULL) - /* We are not initialized yet, we can't be cancelled anyway. */ - return; - __pthread_mutex_lock (&p->cancel_lock); p->cancel_type = oldtype; __pthread_mutex_unlock (&p->cancel_lock); diff --git a/htl/pt-self.c b/htl/pt-self.c index f7e9cb88c4..1278908397 100644 --- a/htl/pt-self.c +++ b/htl/pt-self.c @@ -24,15 +24,7 @@ pthread_t __pthread_self (void) { - struct __pthread *self; - - if (___pthread_self == NULL) - /* We are not initialized yet, we are the first thread. */ - return 1; - - self = _pthread_self (); - assert (self != NULL); - + struct __pthread *self = _pthread_self (); return self->thread; } diff --git a/sysdeps/mach/hurd/htl/pt-sysdep.c b/sysdeps/mach/hurd/htl/pt-sysdep.c index 55b1a86e00..030a7c7a9e 100644 --- a/sysdeps/mach/hurd/htl/pt-sysdep.c +++ b/sysdeps/mach/hurd/htl/pt-sysdep.c @@ -26,6 +26,10 @@ #include #include +/* Initial thread structure used temporarily during initialization, so various + * functions can already work at least basically. */ +static struct __pthread init_thread; + static void reset_pthread_total (void) { @@ -47,6 +51,10 @@ _init_routine (void *stack) /* Already initialized */ return; + /* Initialize early thread structure. */ + init_thread.thread = 1; + ___pthread_self = &init_thread; + /* Initialize the library. */ ___pthread_init (); @@ -74,6 +82,12 @@ _init_routine (void *stack) __pthread_default_attr.__guardsize = __vm_page_size; #endif + /* Copy over the thread-specific state */ + assert (!init_thread.thread_specifics); + memcpy (&thread->static_thread_specifics, + &init_thread.static_thread_specifics, + sizeof (thread->static_thread_specifics)); + ___pthread_self = thread; /* Decrease the number of threads, to take into account that the