diff options
Diffstat (limited to 'man2/membarrier.2')
-rw-r--r-- | man2/membarrier.2 | 75 |
1 files changed, 35 insertions, 40 deletions
diff --git a/man2/membarrier.2 b/man2/membarrier.2 index a530c662a..f118fd014 100644 --- a/man2/membarrier.2 +++ b/man2/membarrier.2 @@ -3,7 +3,7 @@ .\" .\" SPDX-License-Identifier: Linux-man-pages-copyleft .\" -.TH membarrier 2 2022-12-15 "Linux man-pages 6.03" +.TH membarrier 2 2023-05-03 "Linux man-pages 6.05.01" .SH NAME membarrier \- issue memory barriers on a set of threads .SH LIBRARY @@ -280,27 +280,18 @@ system call is not implemented by this kernel. .B EPERM The current process was not registered prior to using private expedited commands. -.SH VERSIONS -The -.BR membarrier () -system call was added in Linux 4.3. +.SH STANDARDS +Linux. +.SH HISTORY +Linux 4.3. .PP -Before Linux 5.10, the prototype for -.BR membarrier () -was: +Before Linux 5.10, the prototype was: .PP .in +4n .EX .BI "int membarrier(int " cmd ", int " flags ); .EE .in -.SH STANDARDS -.BR membarrier () -is Linux-specific. -.\" .SH SEE ALSO -.\" FIXME See if the following syscalls make it into Linux 4.15 or later -.\" .BR cpu_opv (2), -.\" .BR rseq (2) .SH NOTES A memory barrier instruction is part of the instruction set of architectures with weakly ordered memory models. @@ -328,9 +319,9 @@ following code (x86) can be transformed using .\" SRC BEGIN (membarrier.c) .EX #include <stdlib.h> - +\& static volatile int a, b; - +\& static void fast_path(int *read_b) { @@ -338,7 +329,7 @@ fast_path(int *read_b) asm volatile ("mfence" : : : "memory"); *read_b = b; } - +\& static void slow_path(int *read_a) { @@ -346,29 +337,29 @@ slow_path(int *read_a) asm volatile ("mfence" : : : "memory"); *read_a = a; } - +\& int main(void) { 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(&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); } .EE @@ -387,37 +378,37 @@ becomes: #include <unistd.h> #include <sys/syscall.h> #include <linux/membarrier.h> - +\& static volatile int a, b; - +\& static int membarrier(int cmd, unsigned int flags, int cpu_id) { return syscall(__NR_membarrier, cmd, flags, cpu_id); } - +\& static int init_membarrier(void) { int ret; - +\& /* Check that membarrier() is supported. */ - +\& ret = membarrier(MEMBARRIER_CMD_QUERY, 0, 0); if (ret < 0) { perror("membarrier"); return \-1; } - +\& if (!(ret & MEMBARRIER_CMD_GLOBAL)) { fprintf(stderr, "membarrier does not support MEMBARRIER_CMD_GLOBAL\en"); return \-1; } - +\& return 0; } - +\& static void fast_path(int *read_b) { @@ -425,7 +416,7 @@ fast_path(int *read_b) asm volatile ("" : : : "memory"); *read_b = b; } - +\& static void slow_path(int *read_a) { @@ -433,33 +424,37 @@ slow_path(int *read_a) membarrier(MEMBARRIER_CMD_GLOBAL, 0, 0); *read_a = a; } - +\& int main(int argc, char *argv[]) { int read_a, read_b; - +\& if (init_membarrier()) exit(EXIT_FAILURE); - +\& /* * Real applications would call fast_path() and slow_path() * from different threads. Call those from main() to keep * this example short. */ - +\& 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); } .EE .in +.\" .SH SEE ALSO +.\" FIXME See if the following syscalls make it into Linux 4.15 or later +.\" .BR cpu_opv (2), +.\" .BR rseq (2) |