From patchwork Mon Aug 30 15:26:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergey Bugaev X-Patchwork-Id: 44807 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 B1F8A3857810 for ; Mon, 30 Aug 2021 15:28:39 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B1F8A3857810 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1630337319; bh=nwKz0OCZWBlbo154ak9L70N61GR+Y6VJg0cIgfxAdwU=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=ry37Cx/6vRAyGm19wEAMEd/YujAZWLWkxBXlMJxBoGFTwx91kkMX6Gv0G2Yy9Gh8F jxQPZokzRAz5iwUwkl7lUuGLD13cnHX6PrsRT22zVWxmeRZiasibyz/89XMSFawXXT G1dd42j3dpOXjSdc3VY2dkbIqXF+tWTqQxpSDVmw= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-lf1-x12c.google.com (mail-lf1-x12c.google.com [IPv6:2a00:1450:4864:20::12c]) by sourceware.org (Postfix) with ESMTPS id 16313385800E for ; Mon, 30 Aug 2021 15:26:52 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 16313385800E Received: by mail-lf1-x12c.google.com with SMTP id y34so31987988lfa.8 for ; Mon, 30 Aug 2021 08:26:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nwKz0OCZWBlbo154ak9L70N61GR+Y6VJg0cIgfxAdwU=; b=iZa6nO9uAWpEiL+gvy7EG698EGD5M2vBFawMAKOQO7gwYfR67CufXCgTM5WTuaH662 kGD0jUVzoExND0z+cK6mOIRsz/LTGS2sIdAE/PrnBxOB4eYPtBCNfTpNZjnKxQvSFaTx d8QB3amC+RLUoduxCdRJEUYxbSWKBtR78dIvFQu85Vn4LDk/75Yeu9yhpnHl1d2bdvxk kfKqpplTvmPXnQSvqfeaTS7mYBzXR1RXR4crJ21JmYOvn3KidNUKXbkhozWcMGfU+r/b s7GrCYHMRWwNV9XhIGHBdNoRglcKVBk5AYXcyvxK7928d6K7I1bimqjVK1K8UT/ZB3I/ Frrw== X-Gm-Message-State: AOAM531X2mXdUGI+sgJRIArmPZCfFYeia4Fht4t+qnQfWrqs6if/JLfo i7QNjqUBEcYGbbpO1y5mhJUltihdaTTIJgw3 X-Google-Smtp-Source: ABdhPJwin3v0K/Qtgm5WGKPqqUtDlwIuHajs4s7Kv8ggeCAjsSdFhIOOoim79bOAda89vYWxS8NdZA== X-Received: by 2002:a05:6512:36d9:: with SMTP id e25mr17720208lfs.553.1630337210496; Mon, 30 Aug 2021 08:26:50 -0700 (PDT) Received: from badwolf.office.smartdec.ru ([81.23.5.115]) by smtp.googlemail.com with ESMTPSA id b18sm1882314ljk.24.2021.08.30.08.26.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 30 Aug 2021 08:26:50 -0700 (PDT) To: libc-alpha@sourceware.org, bug-hurd@gnu.org Subject: [RFC PATCH htl v2 2/4] htl: Reimplement GSCOPE Date: Mon, 30 Aug 2021 18:26:34 +0300 Message-Id: <20210830152636.1334678-3-bugaevc@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210830152636.1334678-1-bugaevc@gmail.com> References: <20210830152636.1334678-1-bugaevc@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-9.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_BARRACUDACENTRAL, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, 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: Sergey Bugaev via Libc-alpha From: Sergey Bugaev Reply-To: Sergey Bugaev Cc: samuel.thibault@gnu.org, Sergey Bugaev Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" This is a new implementation of GSCOPE which largely mirrors its NPTL counterpart. Same as in NPTL, instead of a global flag shared between threads, there is now a per-thread GSCOPE flag stored in each thread's TCB. This makes entering and exiting a GSCOPE faster at the expense of making THREAD_GSCOPE_WAIT () slower. The largest win is the elimination of many redundant gsync_wake () RPC calls; previously, even simplest programs would make dozens of fully redundant gsync_wake () calls. Despite all ports now putting GSCOPE flag into TCP, this patch keeps the THREAD_GSCOPE_IN_TCB preprocessor definition, with value 0 for HTL and 1 for NPTL. It turns out that although originally this definition was indeed used to distinguish between the cases where the GSCOPE flag was stored in TCB or not, it has since become used as a general way to distinguish between HTL and NPTL. It may be worthwhile to get rid of this flag, or at least rename it to better reflect what it's used for. This patch does neither, though. Signed-off-by: Sergey Bugaev --- elf/dl-support.c | 1 - sysdeps/generic/ldsodefs.h | 4 --- sysdeps/htl/dl-thread_gscope_wait.c | 55 +++++++++++++++++++++++++++++ sysdeps/mach/hurd/i386/tls.h | 19 ++++++++++ sysdeps/mach/hurd/tls.h | 20 +---------- 5 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 sysdeps/htl/dl-thread_gscope_wait.c diff --git a/elf/dl-support.c b/elf/dl-support.c index 0155718175..68abf606ca 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -195,7 +195,6 @@ int _dl_stack_cache_lock; when it was not, we do it by calling this function. It returns an errno code or zero on success. */ int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable; -int _dl_thread_gscope_count; void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls; #endif struct dl_scope_free_list *_dl_scope_free_list; diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 31c7d3945b..5a779ae1a3 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -487,8 +487,6 @@ struct rtld_global /* Mutex protecting the stack lists. */ EXTERN int _dl_stack_cache_lock; #else - EXTERN int _dl_thread_gscope_count; - /* The total number of thread IDs currently in use, or on the list of available thread IDs. */ EXTERN int _dl_pthread_num_threads; @@ -1379,10 +1377,8 @@ __rtld_mutex_init (void) } #endif /* !PTHREAD_IN_LIBC */ -#if THREAD_GSCOPE_IN_TCB void __thread_gscope_wait (void) attribute_hidden; # define THREAD_GSCOPE_WAIT() __thread_gscope_wait () -#endif __END_DECLS diff --git a/sysdeps/htl/dl-thread_gscope_wait.c b/sysdeps/htl/dl-thread_gscope_wait.c new file mode 100644 index 0000000000..b277217b8e --- /dev/null +++ b/sysdeps/htl/dl-thread_gscope_wait.c @@ -0,0 +1,55 @@ +/* Out-of-line notification function for the GSCOPE locking mechanism. + Copyright (C) 2007-2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +void +__thread_gscope_wait (void) +{ + size_t i; + struct __pthread *t; + int *gscope_flagp; + + lll_lock (GL (dl_pthread_threads_lock), LLL_PRIVATE); + + /* Iterate over the list of threads. */ + for (i = 0; i < GL (dl_pthread_num_threads); ++i) + { + t = GL (dl_pthread_threads[i]); + if (t == NULL || t->tcb->gscope_flag == THREAD_GSCOPE_FLAG_UNUSED) + continue; + + gscope_flagp = &t->tcb->gscope_flag; + + /* We have to wait until this thread is done with the global + scope. First tell the thread that we are waiting and + possibly have to be woken. */ + if (atomic_compare_and_exchange_bool_acq (gscope_flagp, + THREAD_GSCOPE_FLAG_WAIT, + THREAD_GSCOPE_FLAG_USED)) + continue; + + do + lll_wait (gscope_flagp, THREAD_GSCOPE_FLAG_WAIT, LLL_PRIVATE); + while (*gscope_flagp == THREAD_GSCOPE_FLAG_WAIT); + } + + lll_unlock (GL (dl_pthread_threads_lock), LLL_PRIVATE); +} diff --git a/sysdeps/mach/hurd/i386/tls.h b/sysdeps/mach/hurd/i386/tls.h index 057b2613f3..c70ea73a81 100644 --- a/sysdeps/mach/hurd/i386/tls.h +++ b/sysdeps/mach/hurd/i386/tls.h @@ -369,6 +369,25 @@ _hurd_tls_new (thread_t child, struct i386_thread_state *state, tcbhead_t *tcb) return err; } +/* Global scope switch support. */ +# define THREAD_GSCOPE_FLAG_UNUSED 0 +# define THREAD_GSCOPE_FLAG_USED 1 +# define THREAD_GSCOPE_FLAG_WAIT 2 + +# define THREAD_GSCOPE_SET_FLAG() \ + THREAD_SETMEM (THREAD_SELF, gscope_flag, THREAD_GSCOPE_FLAG_USED) + +# define THREAD_GSCOPE_RESET_FLAG() \ + ({ \ + int __flag; \ + asm volatile ("xchgl %0, %%gs:%P1" \ + : "=r" (__flag) \ + : "i" (offsetof (tcbhead_t, gscope_flag)), \ + "0" (THREAD_GSCOPE_FLAG_UNUSED)); \ + if (__flag == THREAD_GSCOPE_FLAG_WAIT) \ + lll_wake (THREAD_SELF->gscope_flag, LLL_PRIVATE); \ + }) + #endif /* !__ASSEMBLER__ */ #endif /* i386/tls.h */ diff --git a/sysdeps/mach/hurd/tls.h b/sysdeps/mach/hurd/tls.h index f83956d3d7..98dc319745 100644 --- a/sysdeps/mach/hurd/tls.h +++ b/sysdeps/mach/hurd/tls.h @@ -52,25 +52,7 @@ # define GET_DTV(descr) \ (((tcbhead_t *) (descr))->dtv) -/* Global scope switch support. */ -#define THREAD_GSCOPE_IN_TCB 0 -#define THREAD_GSCOPE_GLOBAL -#define THREAD_GSCOPE_SET_FLAG() \ - atomic_exchange_and_add_acq (&GL(dl_thread_gscope_count), 1) -#define THREAD_GSCOPE_RESET_FLAG() \ - do \ - if (atomic_exchange_and_add_rel (&GL(dl_thread_gscope_count), -1) == 1) \ - lll_wake (GL(dl_thread_gscope_count), 0); \ - while (0) -#define THREAD_GSCOPE_WAIT() \ - do \ - { \ - int count; \ - atomic_write_barrier (); \ - while ((count = GL(dl_thread_gscope_count))) \ - lll_wait (GL(dl_thread_gscope_count), count, 0); \ - } \ - while (0) +# define THREAD_GSCOPE_IN_TCB 0 #endif /* !ASSEMBLER */