* Adhemerval Zanella:
>> Well, that already happens with the duplicated header approach if users
>> want to use UAPI headers, too. It requires complicated synchronization
>> to make it work.
>
> But at least glibc is not imposing it, if user want to use kernel uapi
> header he will explicit include it and it is up to kernel provide a sane
> implementation.
This only works if the header does not include system call wrapper.
>> We can tweak the conditional for the header inclusion further, like
>> this:
>>
>> +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 16, 0) \
>> + || __glibc_has_include (<linux/membarrier.h>) \
>> +# include <linux/membarrier.h>
>> +#else
>>
>> With GCC 5 and later, this would always prefer the kernel header if
>> available. There would never be a conflict between the definitions,
>> irrespective of header file inclusion order.
>>
>> What do you think?
>
> In any case I don't think my suggestion should be a blocker, we
> already rely on linux header for some cases and it seems I am alone in
> trying to decouple glibc from kernel headers.
Okay. I've reconsidered the header baseline approach and I'm now
proposing to go with the 4.3 header version, the first which had the
system call. With a later baseline, you'd get an error if you include
<linux/membarrier.h> before <sys/membarrier.h> and the kernel is older
than the chosen baseline. This cannot happen if we pick the first
supported kernel version as the baseline. (This will not matter if we
eventually choose the use the __has_include trick and the compiler
supports __has_include.)
I had to adjust the test to define a private copy of the subsequently
added constants.
Thanks,
Florian
2018-12-17 Florian Weimer <fweimer@redhat.com>
Linux: Implement membarrier function.
* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
sys/membarrier.h.
(tests): Add tst-membarrier.
* sysdeps/unix/sysv/linux/Versions (GLIBC_2.27): Add membarrier.
* sysdeps/unix/sysv/linux/sys/membarrier.h: New file.
* sysdeps/unix/sysv/linux/tst-membarrier.c: Likewise.
* sysdeps/unix/sysv/linux/aarch64/libc.abilist (GLIBC_2.29): Add
membarrier.
* sysdeps/unix/sysv/linux/alpha/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/arm/libc.abilist (GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/hppa/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/i386/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/ia64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/microblaze/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/nios2/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist
(GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/sh/libc.abilist (GLIBC_2.29): Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist (GLIBC_2.29):
Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist (GLIBC_2.29):
Likewise.
@@ -46,6 +46,9 @@ Major new features:
incosistent mutex state after fork call in multithread environment.
In both popen and system there is no direct access to user-defined mutexes.
+* On Linux, The membarrier function and the <sys/membarrier.h> header file
+ have been added.
+
Deprecated and removed features, and other changes affecting compatibility:
* The glibc.tune tunable namespace has been renamed to glibc.cpu and the
@@ -43,12 +43,13 @@ sysdep_headers += sys/mount.h sys/acct.h sys/sysctl.h \
bits/siginfo-arch.h bits/siginfo-consts-arch.h \
bits/procfs.h bits/procfs-id.h bits/procfs-extra.h \
bits/procfs-prregset.h bits/mman-map-flags-generic.h \
- bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h
+ bits/msq-pad.h bits/sem-pad.h bits/shmlba.h bits/shm-pad.h \
+ sys/membarrier.h
tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-quota tst-sync_file_range tst-sysconf-iov_max tst-ttyname \
test-errno-linux tst-memfd_create tst-mlock2 tst-pkey \
- tst-rlimit-infinity tst-ofdlocks
+ tst-rlimit-infinity tst-ofdlocks tst-membarrier
tests-internal += tst-ofdlocks-compat
@@ -173,6 +173,7 @@ libc {
}
GLIBC_2.29 {
getcpu;
+ membarrier;
}
GLIBC_PRIVATE {
# functions used in other libraries
@@ -2139,5 +2139,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2034,6 +2034,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.4 _Exit F
@@ -1881,6 +1881,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2046,6 +2046,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1915,6 +1915,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -125,6 +125,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.4 _Exit F
@@ -1990,6 +1990,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2131,5 +2131,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -1968,6 +1968,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1966,6 +1966,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1974,6 +1974,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1969,6 +1969,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2172,5 +2172,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -1994,6 +1994,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1998,6 +1998,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -124,6 +124,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 _Exit F
@@ -2229,5 +2229,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2101,5 +2101,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
@@ -2003,6 +2003,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1909,6 +1909,7 @@ GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 __fentry__ F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1885,6 +1885,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1997,6 +1997,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -1938,6 +1938,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
new file mode 100644
@@ -0,0 +1,48 @@
+/* Memory barriers.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_MEMBARRIER_H
+#define _SYS_MEMBARRIER_H 1
+
+#include <features.h>
+
+__BEGIN_DECLS
+
+/* Perform a memory barrier on multiple threads. */
+int membarrier (int __op, int __flags) __THROW;
+
+__END_DECLS
+
+/* Obtain the definitions of the MEMBARRIER_CMD_* constants. */
+
+#include <linux/version.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION (4, 3, 0)
+# include <linux/membarrier.h>
+#else
+
+/* Definitions from Linux 4.3 follow. */
+
+enum membarrier_cmd
+{
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = 1
+};
+
+#endif
+
+#endif /* _SYS_MEMBARRIER_H */
@@ -112,3 +112,4 @@ process_vm_writev EXTRA process_vm_writev i:ipipii process_vm_writev
memfd_create EXTRA memfd_create i:si memfd_create
pkey_alloc EXTRA pkey_alloc i:ii pkey_alloc
pkey_free EXTRA pkey_free i:i pkey_free
+membarrier EXTRA membarrier i:ii membarrier
new file mode 100644
@@ -0,0 +1,66 @@
+/* Tests for the membarrier function.
+ Copyright (C) 2018 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdio.h>
+#include <support/check.h>
+#include <sys/membarrier.h>
+
+static int
+do_test (void)
+{
+ int supported = membarrier (MEMBARRIER_CMD_QUERY, 0);
+ if (supported == -1)
+ {
+ if (errno == ENOSYS)
+ FAIL_UNSUPPORTED ("membarrier system call not implemented");
+ else
+ FAIL_EXIT1 ("membarrier: %m");
+ }
+
+ if ((supported & MEMBARRIER_CMD_SHARED) == 0)
+ FAIL_UNSUPPORTED ("shared memory barriers not supported");
+
+ puts ("info: membarrier is supported on this system");
+
+ /* This was not included in the original implementation in Linux
+ 4.3. */
+ const enum membarrier_cmd cmd_private_expedited = 8;
+ const enum membarrier_cmd cmd_register_private_expedited = 16;
+
+ /* The shared barrier is always implemented. */
+ TEST_COMPARE (supported & MEMBARRIER_CMD_SHARED, MEMBARRIER_CMD_SHARED);
+ TEST_COMPARE (membarrier (MEMBARRIER_CMD_SHARED, 0), 0);
+
+ /* If the private-expedited barrier is advertised, execute it after
+ registering the intent. */
+ if (supported & cmd_private_expedited)
+ {
+ puts ("info: MEMBARRIER_CMD_PRIVATE_EXPEDITED is supported");
+ TEST_COMPARE (supported & cmd_register_private_expedited,
+ cmd_register_private_expedited);
+ TEST_COMPARE (membarrier (cmd_register_private_expedited, 0), 0);
+ TEST_COMPARE (membarrier (cmd_private_expedited, 0), 0);
+ }
+ else
+ puts ("info: MEMBARRIER_CMD_PRIVATE_EXPEDITED not supported");
+
+ return 0;
+}
+
+#include <support/test-driver.c>
@@ -1896,6 +1896,7 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F
GLIBC_2.3 __ctype_b_loc F
@@ -2147,5 +2147,6 @@ GLIBC_2.28 thrd_equal F
GLIBC_2.28 thrd_sleep F
GLIBC_2.28 thrd_yield F
GLIBC_2.29 getcpu F
+GLIBC_2.29 membarrier F
GLIBC_2.29 posix_spawn_file_actions_addchdir_np F
GLIBC_2.29 posix_spawn_file_actions_addfchdir_np F