diff --git a/configure.ac b/configure.ac index 016e38fb599..83cd5d1d15e 100644 --- a/configure.ac +++ b/configure.ac @@ -415,6 +415,20 @@ if test "x$GCC_ATOMIC_BUILTINS_SUPPORTED" = x1; then fi AM_CONDITIONAL([GCC_ATOMIC_BUILTINS_SUPPORTED], [test x$GCC_ATOMIC_BUILTINS_SUPPORTED = x1]) +dnl Check if host supports 64-bit atomics +dnl note that lack of support usually results in link (not compile) error +AC_MSG_CHECKING(whether __sync_add_and_fetch_8 is supported) +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include +uint64_t v; +int main() { + return __sync_add_and_fetch(&v, (uint64_t)1); +}]])], GCC_64BIT_ATOMICS_SUPPORTED=yes, GCC_64BIT_ATOMICS_SUPPORTED=no) +if test "x$GCC_64BIT_ATOMICS_SUPPORTED" != xyes; then + DEFINES="$DEFINES -DMISSING_64BIT_ATOMICS" +fi +AC_MSG_RESULT($GCC_64BIT_ATOMICS_SUPPORTED) + dnl Check for Endianness AC_C_BIGENDIAN( little_endian=no, diff --git a/src/util/Makefile.sources b/src/util/Makefile.sources index 8ee45d56170..e9057343dc2 100644 --- a/src/util/Makefile.sources +++ b/src/util/Makefile.sources @@ -43,6 +43,7 @@ MESA_UTIL_FILES := \ strtod.c \ strtod.h \ texcompress_rgtc_tmp.h \ + u_atomic.c \ u_atomic.h \ u_endian.h \ u_queue.c \ diff --git a/src/util/u_atomic.c b/src/util/u_atomic.c new file mode 100644 index 00000000000..44b75fb0c00 --- /dev/null +++ b/src/util/u_atomic.c @@ -0,0 +1,75 @@ +/* + * Copyright © 2017 Gražvydas Ignotas + * + * 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 +#include + +#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) +{ + uint64_t r; + + pthread_mutex_lock(&sync_mutex); + *ptr += val; + r = *ptr; + pthread_mutex_unlock(&sync_mutex); + + return r; +} + +WEAK uint64_t +__sync_sub_and_fetch_8(uint64_t *ptr, uint64_t val) +{ + uint64_t r; + + pthread_mutex_lock(&sync_mutex); + *ptr -= val; + r = *ptr; + pthread_mutex_unlock(&sync_mutex); + + return r; +} + +WEAK uint64_t +__atomic_fetch_add_8(uint64_t *ptr, uint64_t val, int memorder) +{ + return __sync_add_and_fetch(ptr, val); +} + +WEAK uint64_t +__atomic_fetch_sub_8(uint64_t *ptr, uint64_t val, int memorder) +{ + return __sync_sub_and_fetch(ptr, val); +} + +#endif