Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752700AbdIRS7z (ORCPT ); Mon, 18 Sep 2017 14:59:55 -0400 Received: from mail.efficios.com ([167.114.142.141]:48296 "EHLO mail.efficios.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751916AbdIRS7v (ORCPT ); Mon, 18 Sep 2017 14:59:51 -0400 From: Mathieu Desnoyers To: Michael Kerrisk Cc: linux-kernel@vger.kernel.org, Mathieu Desnoyers , "Paul E . McKenney" Subject: [PATCH] membarrier: Update example to take TSO into account Date: Mon, 18 Sep 2017 14:59:39 -0400 Message-Id: <20170918185939.20970-1-mathieu.desnoyers@efficios.com> X-Mailer: git-send-email 2.11.0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3131 Lines: 142 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. 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); } -- 2.11.0