From patchwork Wed Jul 7 14:52:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Florian Weimer X-Patchwork-Id: 44202 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 C0B683959C34 for ; Wed, 7 Jul 2021 14:52:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org C0B683959C34 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1625669576; bh=OLljdRPDGFghn8razPLGy5Hgb20UqZpKD3nqDblhYHE=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=dV75Qwbd+sneeiHUY7+32eyj7lGwaPRq/+AnLgCO5fSdC+dM+fEkAZ7sG5LRJxf2f CF9rJPd+9yjNPVHHN7nNti95D1/bBCrRPfBwpjzqOwZdpN/dpwdniKCcN/XeQaiqfK RfJfg3vU7TylQ5CvIQfcjrj9KeQdLW3vg0TgTmwo= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTP id AF192384402B for ; Wed, 7 Jul 2021 14:52:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AF192384402B Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-118-KZ4uBO6IMKqthSTIwdD-8w-1; Wed, 07 Jul 2021 10:52:32 -0400 X-MC-Unique: KZ4uBO6IMKqthSTIwdD-8w-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2C376801A93 for ; Wed, 7 Jul 2021 14:52:32 +0000 (UTC) Received: from oldenburg.str.redhat.com (ovpn-115-5.ams2.redhat.com [10.36.115.5]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 82AD75C1C2 for ; Wed, 7 Jul 2021 14:52:31 +0000 (UTC) To: libc-alpha@sourceware.org Subject: [PATCH] nptl: Use out-of-line wake function in __libc_lock_unlock slow path Date: Wed, 07 Jul 2021 16:52:29 +0200 Message-ID: <87lf6i5g7m.fsf@oldenburg.str.redhat.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-13.3 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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: , X-Patchwork-Original-From: Florian Weimer via Libc-alpha From: Florian Weimer Reply-To: Florian Weimer Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This slightly reduces code size, as can be seen below. __libc_lock_unlock is usually used along with __libc_lock_lock in the same function. __libc_lock_lock already has an out-of-line slow path, so this change should not introduce many additional non-leaf functions. This change also fixes a link failure in 32-bit Arm thumb mode because commit 1f9c804fbd699104adefbce9e56d2c8aa711b6b9 ("nptl: Use internal low-level lock type for !IS_IN (libc)") introduced __libc_do_syscall calls outside of libc. Before x86-64: text data bss dec hex filename 1937748 20456 54896 2013100 1eb7ac libc.so.6 25601 856 12768 39225 9939 nss/libnss_db.so.2 40310 952 25144 66406 10366 nss/libnss_files.so.2 After x86-64: text data bss dec hex filename 1935312 20456 54896 2010664 1eae28 libc.so.6 25559 864 12768 39191 9917 nss/libnss_db.so.2 39764 960 25144 65868 1014c nss/libnss_files.so.2 Before i686: 2110961 11272 39144 2161377 20fae1 libc.so.6 27243 428 12652 40323 9d83 nss/libnss_db.so.2 43062 476 25028 68566 10bd6 nss/libnss_files.so.2 After i686: 2107347 11272 39144 2157763 20ecc3 libc.so.6 26929 432 12652 40013 9c4d nss/libnss_db.so.2 43132 480 25028 68640 10c20 nss/libnss_files.so.2 --- nptl/Versions | 1 + nptl/lowlevellock.c | 14 ++++++++++++++ sysdeps/nptl/lowlevellock.h | 26 ++++++++++++++++++-------- 3 files changed, 33 insertions(+), 8 deletions(-) diff --git a/nptl/Versions b/nptl/Versions index 2a75f013f2..3221de89d1 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -380,6 +380,7 @@ libc { } GLIBC_PRIVATE { __libc_alloca_cutoff; + __lll_lock_wake_private; __lll_lock_wait_private; __nptl_create_event; __nptl_death_event; diff --git a/nptl/lowlevellock.c b/nptl/lowlevellock.c index 2d077d8694..4f88178964 100644 --- a/nptl/lowlevellock.c +++ b/nptl/lowlevellock.c @@ -52,6 +52,20 @@ __lll_lock_wait (int *futex, int private) } libc_hidden_def (__lll_lock_wait) +void +__lll_lock_wake_private (int *futex) +{ + lll_futex_wake (futex, 1, LLL_PRIVATE); +} +libc_hidden_def (__lll_lock_wake_private) + +void +__lll_lock_wake (int *futex, int private) +{ + lll_futex_wake (futex, 1, private); +} +libc_hidden_def (__lll_lock_wake) + #if ENABLE_ELISION_SUPPORT int __pthread_force_elision __attribute__ ((nocommon)); libc_hidden_data_def (__pthread_force_elision) diff --git a/sysdeps/nptl/lowlevellock.h b/sysdeps/nptl/lowlevellock.h index be60c9ac28..4d95114ed3 100644 --- a/sysdeps/nptl/lowlevellock.h +++ b/sysdeps/nptl/lowlevellock.h @@ -125,6 +125,11 @@ libc_hidden_proto (__lll_lock_wait) #define lll_cond_lock(futex, private) __lll_cond_lock (&(futex), private) +extern void __lll_lock_wake_private (int *futex); +libc_hidden_proto (__lll_lock_wake_private) +extern void __lll_lock_wake (int *futex, int private); +libc_hidden_proto (__lll_lock_wake) + /* This is an expression rather than a statement even though its value is void, so that it can be used in a comma expression or as an expression that's cast to void. */ @@ -137,14 +142,19 @@ libc_hidden_proto (__lll_lock_wait) acquires the lock and when there will be no further lock acquisitions; thus, we must not access the lock after releasing it, or those accesses could be concurrent with mutex destruction or reuse of the memory. */ -#define __lll_unlock(futex, private) \ - ((void) \ - ({ \ - int *__futex = (futex); \ - int __private = (private); \ - int __oldval = atomic_exchange_rel (__futex, 0); \ - if (__glibc_unlikely (__oldval > 1)) \ - lll_futex_wake (__futex, 1, __private); \ +#define __lll_unlock(futex, private) \ + ((void) \ + ({ \ + int *__futex = (futex); \ + int __private = (private); \ + int __oldval = atomic_exchange_rel (__futex, 0); \ + if (__glibc_unlikely (__oldval > 1)) \ + { \ + if (__builtin_constant_p (private) && (private) == LLL_PRIVATE) \ + __lll_lock_wake_private (__futex); \ + else \ + __lll_lock_wake (__futex, __private); \ + } \ })) #define lll_unlock(futex, private) \ __lll_unlock (&(futex), private)