[Mesa-dev] [PATCH] util/u_atomic: provide 64bit atomics where they're missing

Jonathan Gray jsg at jsg.id.au
Thu Mar 30 04:54:46 UTC 2017


On Wed, Mar 29, 2017 at 04:55:54PM -0700, Matt Turner wrote:
> On Wed, Mar 29, 2017 at 4:13 PM, Grazvydas Ignotas <notasas at gmail.com> wrote:
> > There are still some distributions trying to support unfortunate people
> > with old or exotic CPUs that don't have 64bit atomic operations. When
> > compiling for such a machine, gcc conveniently inserts a library call to
> > a helper, but it's implementation is missing and we get a linker error.
> > This allows us to provide our implementation, which is marked weak to
> > prefer a better implementation, should one exist.
> >
> > Cc: Matt Turner <mattst88 at gmail.com>
> > Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=93089
> > Signed-off-by: Grazvydas Ignotas <notasas at gmail.com>
> > ---
> 
> Thanks, this is a really good idea.
> 
> >  configure.ac              | 12 ++++++++
> >  src/util/Makefile.sources |  1 +
> >  src/util/u_atomic.c       | 71 +++++++++++++++++++++++++++++++++++++++++++++++
> >  3 files changed, 84 insertions(+)
> >  create mode 100644 src/util/u_atomic.c
> >
> > diff --git a/configure.ac b/configure.ac
> > index ab9a91e..89b615b 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -413,10 +413,22 @@ int main() {
> >  if test "x$GCC_ATOMIC_BUILTINS_SUPPORTED" = x1; then
> >      DEFINES="$DEFINES -DUSE_GCC_ATOMIC_BUILTINS"
> >  fi
> >  AM_CONDITIONAL([GCC_ATOMIC_BUILTINS_SUPPORTED], [test x$GCC_ATOMIC_BUILTINS_SUPPORTED = x1])
> >
> > +dnl Check if host supports 64bit atomics
> > +dnl note that lack of support usually results in link (not compile) error
> > +AC_LINK_IFELSE([AC_LANG_SOURCE([[
> > +#include <stdint.h>
> > +uint64_t v;
> > +int main() {
> > +    return __sync_add_and_fetch(&v, (uint64_t)1);
> > +}]])], GCC_64BIT_ATOMICS_SUPPORTED=1)
> > +if test "x$GCC_64BIT_ATOMICS_SUPPORTED" != x1; then
> > +    DEFINES="$DEFINES -DMISSING_64BIT_ATOMICS"
> > +fi
> > +
> >  dnl Check for Endianness
> >  AC_C_BIGENDIAN(
> >     little_endian=no,
> >     little_endian=yes,
> >     little_endian=no,
> > diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources
> > index 8ee45d5..e905734 100644
> > --- a/src/util/Makefile.sources
> > +++ b/src/util/Makefile.sources
> > @@ -41,10 +41,11 @@ MESA_UTIL_FILES := \
> >         string_to_uint_map.h \
> >         strndup.h \
> >         strtod.c \
> >         strtod.h \
> >         texcompress_rgtc_tmp.h \
> > +       u_atomic.c \
> >         u_atomic.h \
> >         u_endian.h \
> >         u_queue.c \
> >         u_queue.h \
> >         u_string.h \
> > diff --git a/src/util/u_atomic.c b/src/util/u_atomic.c
> > new file mode 100644
> > index 0000000..77ef119
> > --- /dev/null
> > +++ b/src/util/u_atomic.c
> > @@ -0,0 +1,71 @@
> > +/*
> > + * Copyright ?? 2017 The Mesa Project
> 
> The Mesa Project isn't something that can hold copyright. Your name
> should be here.
> 
> > + *
> > + * Permission is hereby granted, free of charge, to any person obtaining a
> > + * copy of this software and associated documentation files (the "Software"),
> > + * to deal in the Software without restriction, including without limitation
> > + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> > + * and/or sell copies of the Software, and to permit persons to whom the
> > + * Software is furnished to do so, subject to the following conditions:
> > + *
> > + * The above copyright notice and this permission notice (including the next
> > + * paragraph) shall be included in all copies or substantial portions of the
> > + * Software.
> > + *
> > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
> > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
> > + * IN THE SOFTWARE.
> > + */
> > +
> > +#if defined(MISSING_64BIT_ATOMICS) && defined(HAVE_PTHREAD)
> > +
> > +#include <stdint.h>
> > +#include <pthread.h>
> > +
> > +#if defined(HAVE_FUNC_ATTRIBUTE_WEAK) && !defined(__CYGWIN__)
> > +#define WEAK __attribute__((weak))
> > +#else
> > +#define WEAK
> > +#endif
> > +
> > +static pthread_mutex_t sync_mutex = PTHREAD_MUTEX_INITIALIZER;
> > +
> > +WEAK uint64_t __sync_add_and_fetch_8(uint64_t *ptr, uint64_t val)
> 
> Let's do BSD-style function declarations, with the qualifiers and
> return type on their own line.
> 
> With those two trivial things changed, this is
> 
> Reviewed-by: Matt Turner <mattst88 at gmail.com>
> 
> Grazvydas, if you have not already, please file a request for a
> Freedesktop account [1] [2] and let's get you commit access.
> 
> Jonathan, can you check whether this resolves the bug entirely? Or are
> there some other __sync functions we need to implement? I see
> __sync_add_and_fetch_4, etc, in the bug report.

I don't have a full list of which platforms implement which atomics.
Instruction sets which predate C11 and weren't designed with
multiprocessor support in mind are unlikely to have them.

32 bit atomics, no 64 bit atomics:
32 bit powerpc
32 bit mips?
i386/i486
arm < v6k
sparc < v9

no 32 bit atomics, no 64 bit atomics:
arm < v6 (just swp)
32bit hppa (just ldcws)
superh

On linux the situation is less clear.  On linux each architecture has a
different list of syscalls.  In some cases (arm and perhaps others?)
there are syscalls to disable interrupts and perform an equivalent
operation in the kernel.  gcc will insert calls to helper functions
that call the syscalls in some cases when compiled for a linux target
on one of those architectures.

The point at which gcc added __sync instructions and/or the linux kernel
stubs also depends on the architecture, in some cases they were added
comparatively late.

Going by https://gcc.gnu.org/wiki/Atomic arm, hppa and superh
do syscalls on linux for 32 bit atomics, with the equivalent for faking
64 bit arm atomics only in gcc >= 4.8, linux >= 3.1.

Though "Kernel-provided User Helpers" are only documented for arm so it
is unclear what the reality is.


More information about the mesa-dev mailing list