Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp995888imm; Wed, 6 Jun 2018 08:56:55 -0700 (PDT) X-Google-Smtp-Source: ADUXVKI/UILY2V4gXJPA/a1zDhXFoKHiirwTsdGqa/IF7CWRxxqewBhaO9NyywXFCQVGWHEsJxZf X-Received: by 2002:a62:b2c4:: with SMTP id z65-v6mr2992654pfl.21.1528300615747; Wed, 06 Jun 2018 08:56:55 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1528300615; cv=none; d=google.com; s=arc-20160816; b=dOMlcltoQy/XZxWm+Zo5rTSw8/hptJfCX/rjEBHcPG7tt+m2VTiJoCNClihP8Dgsog HbIDsFOOTDsexKtYukKGowsrr6T0IAEYwbwnLwknYHPn+FZPIqH1aqbO4bUDoN6neGKE R/E8MwOq9bFuV9G19xKxKeVJ9MbECPHT76fjuH/1ADD1SFnEZhCkP+C+xZQdn8IqePjV qm+62FljloCgUeYR8yQzcNvsNZrlBGcju7o4s2kfgUXcP3re3xzbDRDa8b5OuNUheudc 0vox+pcPsY0ZFVVQ+whd8VzFiEMEvNCcKZgoETjjpnb1NL/hYbvdPl6AmxRm9FLQlHoY URFg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:message-id:in-reply-to :subject:cc:to:from:date:arc-authentication-results; bh=gDJp1FrMuI27rq9eLPNk7LMnPdDzGklR6oUKLAL24sA=; b=gQqfFYbaTUG3ffajVDao6F69W8Mk3NBftFjAt+P+Bj+QuugZaG5xGtJFgjrrBF6syp aKOOaysRzCmKDeaDMImPBA430mREGLdDwrPL7RbsijsPNoqgT/q+3vdSWYnT8SWwsFte iZ+4PnPs0A7h3nyiM2TdWlUVzIB3wBL9/7nd5TpLmInwsYpRDnOJG4NfOLw2JgPdCWqz mbkiiZaLKov4IoIwoF/SL99lm1SN49k33gYEqW80V2CssMvnK/it0yHRYtAGmwlaMTuc jUvh0LCmIc0TZI4hbyjavTL+vqLMWfDqMC6XPfqK2CP6c/Gezz6GWo02ElRjE5KyVsLB DjHQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d8-v6si20399488pgq.162.2018.06.06.08.56.41; Wed, 06 Jun 2018 08:56:55 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932372AbeFFPzu (ORCPT + 99 others); Wed, 6 Jun 2018 11:55:50 -0400 Received: from iolanthe.rowland.org ([192.131.102.54]:36040 "HELO iolanthe.rowland.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with SMTP id S932198AbeFFPzs (ORCPT ); Wed, 6 Jun 2018 11:55:48 -0400 Received: (qmail 3580 invoked by uid 2102); 6 Jun 2018 11:55:47 -0400 Received: from localhost (sendmail-bs@127.0.0.1) by localhost with SMTP; 6 Jun 2018 11:55:47 -0400 Date: Wed, 6 Jun 2018 11:55:47 -0400 (EDT) From: Alan Stern X-X-Sender: stern@iolanthe.rowland.org To: Roman Penyaev cc: "Paul E. McKenney" , Linus Torvalds , Linux Kernel Mailing List , linux-arch , , Will Deacon , Peter Zijlstra , Boqun Feng , Nick Piggin , David Howells , Jade Alglave , Luc Maranget , Akira Yokosawa , Ingo Molnar Subject: Re: LKMM litmus test for Roman Penyaev's rcu-rr In-Reply-To: Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, 6 Jun 2018, Roman Penyaev wrote: > On Wed, Jun 6, 2018 at 3:54 PM, Alan Stern wrote: > > On Wed, 6 Jun 2018, Roman Penyaev wrote: > > > >> > Preserving the order of volatile accesses isn't sufficient. The > >> > compiler is still allowed to translate > >> > > >> > r1 = READ_ONCE(x); > >> > if (r1) { > >> > ... > >> > } > >> > WRITE_ONCE(y, r2); > >> > > >> > into something resembling > >> > > >> > r1 = READ_ONCE(x); > >> > WRITE_ONCE(y, r2); > >> > if (r1) { > >> > ... > >> > } > >> > >> Hi Alan, > >> > >> According to the standard C99 Annex C "the controlling expression of > >> a selection statement (if or switch)" are the sequence points, just > >> like a volatile access (READ_ONCE or WRITE_ONCE). > >> > >> "5.1.2.3 Program execution" states: > >> "At certain specified points in the execution sequence called sequence > >> points, all side effects of previous evaluations shall be complete > >> and no side effects of subsequent evaluations shall have taken place." > >> > >> So in the example we have 3 sequence points: "READ_ONCE", "if" and > >> "WRITE_ONCE", which it seems can't be reordered. Am I mistaken > >> interpreting standard? Could you please clarify. > > > > Well, for one thing, we're talking about C11, not C99. > > C11 is a n1570, ISO/IEC 9899:2011 ? (according to wiki). Found pdf on > the web contains similar lines, so should not be any differences for > that particular case. > > > For another, as far as I understand it, the standard means the program > > should behave _as if_ the side effects are completed in the order > > stated. It doesn't mean that the generated code has to behave that way > > literally. > > Then I do not understand what are the differences between "side effects > are completed" and "code generated". Abstract machine state should > provide some guarantees between sequence points, e.g.: > > foo(); /* function call */ > ------------| > *a = 1; | > *b = 12; | Compiler in his right to reorder. > *c = 123; | > ------------| > boo(); /* function call */ > > compiler in his right to reorder memory accesses between foo() and > boo() calls (foo and boo are sequence points, but memory accesses > are not), but: > > foo(); /* function call */ > *(volatile int *)a = 1; > *(volatile int *)b = 12; > *(volatile int *)c = 123; > boo(); /* function call */ > > are all sequence points, so compiler can't reorder them. > > Where am I mistaken? You are right so far. Now suppose one of the sequence points is an "if" statement: foo(); // sequence point *a = 1; if (*b) // sequence point *c = 2; *d = 3; boo(); // sequence point The object code has to behave _as though_ the write to *a was completed before the write to *d begins, because of the sequence point in between. But nevertheless, the object code is allowed to be like this: foo(); *d = 3; *a = 1; if (*b) *c = 2; boo(); because the overall effect is the same, if all you are concerned with is this single thread. (And assuming that none of the pointers alias each other.) The compiler must not move the "*d = 3" write up before the call to foo(), because foo() might read the value of *d and then it would get an incorrect answer. Moving the write before the "if" statement and the assignment to *a is okay, however, because those statements would do the same thing no matter what value was stored in *d. Alan > > And in particular, the standard is referring to the > > behavior of a single thread, not the interaction between multiple > > concurrent threads. > > Yes, that is clear: we are talking about code reordering in one > particular function in a single threaded environment. > > -- > Roman