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-Status: No, score=-3.9 required=3.0 tests=AWL,BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_PASS, SPF_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from 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 RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 0FA021F55B for ; Fri, 22 May 2020 19:53:33 +0000 (UTC) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 202CD383F847; Fri, 22 May 2020 19:53:31 +0000 (GMT) Received: from brightrain.aerifal.cx (brightrain.aerifal.cx [216.12.86.13]) by sourceware.org (Postfix) with ESMTPS id 991F4383F847 for ; Fri, 22 May 2020 19:53:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 991F4383F847 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=libc.org Authentication-Results: sourceware.org; spf=none smtp.mailfrom=dalias@libc.org Date: Fri, 22 May 2020 15:53:26 -0400 From: Rich Felker To: Szabolcs Nagy Subject: Re: [PATCH 2/2] manual: Document __libc_single_threaded Message-ID: <20200522195326.GB1079@brightrain.aerifal.cx> References: <20200522100146.GA29518@arm.com> <877dx45low.fsf@oldenburg2.str.redhat.com> <20200522105458.GB29518@arm.com> <20200522150720.GR1079@brightrain.aerifal.cx> <20200522161413.GU1079@brightrain.aerifal.cx> <871rnb3nue.fsf@oldenburg2.str.redhat.com> <20200522172826.GW1079@brightrain.aerifal.cx> <87h7w727i4.fsf@oldenburg2.str.redhat.com> <20200522174932.GY1079@brightrain.aerifal.cx> <20200522192249.GC24880@arm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200522192249.GC24880@arm.com> User-Agent: Mutt/1.5.21 (2010-09-15) 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: , Cc: Florian Weimer , libc-alpha@sourceware.org Errors-To: libc-alpha-bounces@sourceware.org Sender: "Libc-alpha" On Fri, May 22, 2020 at 08:22:50PM +0100, Szabolcs Nagy wrote: > The 05/22/2020 13:49, Rich Felker wrote: > > On Fri, May 22, 2020 at 07:40:19PM +0200, Florian Weimer via Libc-alpha wrote: > > > * Rich Felker: > > > > > > >> Our discussion focused on the problem that observing a thread count of 1 > > > >> in pthread_join does not necessarily mean that it is safe to assume at > > > >> this point that the process is single-threaded, in glibc's > > > >> implementation that uses a simple __nptl_nthreads counter decremented on > > > >> the thread itself. This does not cause a low-level data race directly, > > > >> but is potentially still incorrect (I'm not quite sure yet). > > > > > > > > pthread_join necessarily has an acquire barrier (this is a fundamental > > > > requirement of the interface contract; join is acquiring the results > > > > of the thread) so under some weak assumptions on unsynchronized memory > > > > access (e.g. non-tearing, not seeing a value that wasn't stored > > > > sometime between the last and next acquire barriers on the observer's > > > > side) I think observing it from pthread_join is safe. > > > > > > Because of the meaning of the variable, it is *completely* safe if there > > > are no detached threads, without any further assumptions. > > > > > > With detached threads an pthread_join observing a thread count of 1 (as > > > decreased during thread exit), the validity of setting > > > __libc_single_threaded depends on whether the kernel offers something > > > that causes a memory write on thread exit. I know of at least two such > > > > I don't follow. Why do you care about the kernel entity exiting here? > > You should only care about having a release barrier before the update > > to the count, so that seeing the updated count guarantees seeing any > > changes to memory made by the exiting detached thread. > > kernel entity matters if it writes user memory after > the release barrier such that user code may observe it. > (although that would likely break conformance or other > properties too, not just single thread checks). > > another example is observing the detached thread via > kernel apis like /proc/task: user code may expect to > see a single os task when __libc_single_threaded is set. Indeed, this is why I said the precise meaning/contract for what the consumer of __libc_single_threaded is allowed to do needs to be clear -- see also the new thread "How would we make linux man pages authoritative?" and Michael Kerrisk's comments on how hidden behaviors become de facto contracts if you don't clearly specify otherwise. > so i think the safest implementation never sets > __libc_single_threaded back to true and second safest > is one that only sets it back to true in pthread_join > when there were no detached threads (or if using some > os api it can verify that there really is only one > kernel thread). > > if we want to allow kernel entities to be around > but still tell the user when "as far as the libc > is concerned there is only one thread", then i > think __libc_single_threaded needs to be an extern > call (that acts as a compiler barrier). Do relaxed order atomics provide a compiler barrier? If so, I think SYS_membarrier combined with one could be sufficient However using atomic type for a public interface like this is a bit of a compatibility thorn (requires compiler and std level supporting it). Of course the same could be achieved with requirement to use a manual compiler barrier (dummy asm) but I think it's error-prone to assume the application would do it correctly. Rich