mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2025-12-16 08:56:40 -05:00
atomic: fix load and store for armv7 and higher
The original atomic implementation in pulseaudio based on libatomic stated that the intent was to use full memory barriers. According to [1], the load and store implementation based on gcc builtins matches sequential consistent (i.e. full memory barrier) load and store ordering only for x86. I observed random crashes in client applications using memfd srbchannel transport on an armv8-aarch64 platform (cortex-a57). In all those crashes the first read on the pstream descriptor (the size field) was wrong and looked like it contained old data. I boiled the relevant parts of the srbchannel implementation down to a simple test case and could observe random test failures. So I figured that the atomic implementation was broken for armv8 with respect to cross-cpu memory access ordering consistency. In order to come up with a minimal fix, I used the newer __atomic_load_n/__atomic_store_n builtins from gcc. With aarch64-linux-gnu-gcc (Linaro GCC 7.3-2018.05) 7.3.1 20180425 they compile to ldar and stlxr on arm64, which is correct according to [1] and [2]. The other atomic operations based on __sync builtins don't need to be touched since they already are of the full memory barrier variety. [1] https://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html [2] <https://community.arm.com/developer/ip-products/processors /b/processors-ip-blog/posts/armv8-a-architecture-2016-additions>
This commit is contained in:
parent
12bb46a768
commit
d4ff4adce2
5 changed files with 198 additions and 1 deletions
12
configure.ac
12
configure.ac
|
|
@ -246,6 +246,15 @@ fi
|
|||
# If everything else fails use libatomic_ops
|
||||
need_libatomic_ops=yes
|
||||
|
||||
AC_CACHE_CHECK([whether $CC knows __atomic_store_n()],
|
||||
pulseaudio_cv_atomic_store_n, [
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([], [[int c = 0; __atomic_store_n(&c, 4, __ATOMIC_SEQ_CST);]])],
|
||||
[pulseaudio_cv_atomic_store_n=yes],
|
||||
[pulseaudio_cv_atomic_store_n=no])
|
||||
])
|
||||
|
||||
|
||||
AC_CACHE_CHECK([whether $CC knows __sync_bool_compare_and_swap()],
|
||||
pulseaudio_cv_sync_bool_compare_and_swap, [
|
||||
AC_LINK_IFELSE(
|
||||
|
|
@ -256,6 +265,9 @@ AC_CACHE_CHECK([whether $CC knows __sync_bool_compare_and_swap()],
|
|||
|
||||
if test "$pulseaudio_cv_sync_bool_compare_and_swap" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ATOMIC_BUILTINS], 1, [Have __sync_bool_compare_and_swap() and friends.])
|
||||
if test "$pulseaudio_cv_atomic_store_n" = "yes" ; then
|
||||
AC_DEFINE([HAVE_ATOMIC_BUILTINS_MEMORY_MODEL], 1, [Have __atomic_store_n() and friends.])
|
||||
fi
|
||||
need_libatomic_ops=no
|
||||
else
|
||||
# HW specific atomic ops stuff
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue