Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751548AbdISPLt (ORCPT ); Tue, 19 Sep 2017 11:11:49 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:36062 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750892AbdISPLr (ORCPT ); Tue, 19 Sep 2017 11:11:47 -0400 X-Google-Smtp-Source: AOwi7QAc82/Jv1bHn9bkHe+gaPI7pw+BV/p41KtIEKfgidH7PpiwkJxpHmGhfGPvH3+SZg17xLuFPg== Cc: mtk.manpages@gmail.com, linux-kernel@vger.kernel.org, "Paul E . McKenney" Subject: Re: [PATCH] membarrier: Update example to take TSO into account To: Mathieu Desnoyers References: <20170918185939.20970-1-mathieu.desnoyers@efficios.com> From: "Michael Kerrisk (man-pages)" Message-ID: Date: Tue, 19 Sep 2017 17:11:40 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.3.0 MIME-Version: 1.0 In-Reply-To: <20170918185939.20970-1-mathieu.desnoyers@efficios.com> Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3696 Lines: 154 On 09/18/2017 08:59 PM, Mathieu Desnoyers wrote: > The example given specifically states that it focus on x86 (TSO memory > model), but gives a read-read vs write-write ordering example, even > though this scenario does not require explicit barriers on TSO. > > So either we change the example architecture to a weakly-ordered > architecture, or we change the example to a scenario requiring barriers > on x86. > > Let's stay on x86, but provide a Dekker as example instead. Thanks for the patch, Mathieu. Applied. (And thanks for the links below.) Cheers, Michael > Signed-off-by: Mathieu Desnoyers > CC: Michael Kerrisk > CC: Paul E. McKenney > Link: https://stackoverflow.com/questions/45970525/is-the-example-in-the-membarrier-man-page-pointless-in-x86 > Link: https://lwn.net/Articles/573436/ > --- > man2/membarrier.2 | 66 ++++++++++++++++++++++++++++++------------------------- > 1 file changed, 36 insertions(+), 30 deletions(-) > > diff --git a/man2/membarrier.2 b/man2/membarrier.2 > index 658dfa5d1..bbf611e10 100644 > --- a/man2/membarrier.2 > +++ b/man2/membarrier.2 > @@ -192,39 +192,42 @@ following code (x86) can be transformed using > static volatile int a, b; > > static void > -fast_path(void) > +fast_path(int *read_b) > { > - int read_a, read_b; > - > - read_b = b; > + a = 1; > asm volatile ("mfence" : : : "memory"); > - read_a = a; > - > - /* read_b == 1 implies read_a == 1. */ > - > - if (read_b == 1 && read_a == 0) > - abort(); > + *read_b = b; > } > > static void > -slow_path(void) > +slow_path(int *read_a) > { > - a = 1; > - asm volatile ("mfence" : : : "memory"); > b = 1; > + asm volatile ("mfence" : : : "memory"); > + *read_a = a; > } > > int > main(int argc, char **argv) > { > + int read_a, read_b; > + > /* > * Real applications would call fast_path() and slow_path() > * from different threads. Call those from main() to keep > * this example short. > */ > > - slow_path(); > - fast_path(); > + slow_path(&read_a); > + fast_path(&read_b); > + > + /* > + * read_b == 0 implies read_a == 1 and > + * read_a == 0 implies read_b == 1. > + */ > + > + if (read_b == 0 && read_a == 0) > + abort(); > > exit(EXIT_SUCCESS); > } > @@ -275,31 +278,26 @@ init_membarrier(void) > } > > static void > -fast_path(void) > +fast_path(int *read_b) > { > - int read_a, read_b; > - > - read_b = b; > + a = 1; > asm volatile ("" : : : "memory"); > - read_a = a; > - > - /* read_b == 1 implies read_a == 1. */ > - > - if (read_b == 1 && read_a == 0) > - abort(); > + *read_b = b; > } > > static void > -slow_path(void) > +slow_path(int *read_a) > { > - a = 1; > - membarrier(MEMBARRIER_CMD_SHARED, 0); > b = 1; > + membarrier(MEMBARRIER_CMD_SHARED, 0); > + *read_a = a; > } > > int > main(int argc, char **argv) > { > + int read_a, read_b; > + > if (init_membarrier()) > exit(EXIT_FAILURE); > > @@ -309,8 +307,16 @@ main(int argc, char **argv) > * this example short. > */ > > - slow_path(); > - fast_path(); > + slow_path(&read_a); > + fast_path(&read_b); > + > + /* > + * read_b == 0 implies read_a == 1 and > + * read_a == 0 implies read_b == 1. > + */ > + > + if (read_b == 0 && read_a == 0) > + abort(); > > exit(EXIT_SUCCESS); > } > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/