Messages in this thread | | | Subject | Re: [PATCH] membarrier: Update example to take TSO into account | From | "Michael Kerrisk (man-pages)" <> | Date | Tue, 19 Sep 2017 17:11:40 +0200 |
| |
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 <mathieu.desnoyers@efficios.com> > CC: Michael Kerrisk <mtk.manpages@gmail.com> > CC: Paul E. McKenney <paulmck@linux.vnet.ibm.com> > 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/
| |