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: 73806 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6CD1538555B2 for ; Tue, 8 Aug 2023 11:17:32 +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+patchwork=sourceware.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;