mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-23 19:03:59 +08:00
Replace sync builtins with atomic builtins
The old __sync builtins have been deprecated for a long time now in favor of the __atomic builtins following the C++11/C11 memory model. This patch converts libgfortran to use the modern __atomic builtins. At the same time I weakened the consistency to relaxed for incrementing and decrementing the counter, and acquire-release when decrementing to check whether the counter is 0 and the unit can be freed. This is similar to e.g. std::shared_ptr in C++. Regtested on x86_64-pc-linux-gnu. libgfortran/ChangeLog: 2018-11-22 Janne Blomqvist <jb@gcc.gnu.org> * acinclude.m4 (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Rename and test presence of atomic builtins instead of sync builtins. * configure.ac (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Call new test. * io/io.h (inc_waiting_locked): Use __atomic_fetch_add. (predec_waiting_locked): Use __atomic_add_fetch. (dec_waiting_unlocked): Use __atomic_fetch_add. * config.h.in: Regenerated. * configure: Regenerated. * Makefile.in: Regenerated. From-SVN: r266367
This commit is contained in:
parent
d8bcb00f21
commit
0536d5b37d
@ -1,3 +1,15 @@
|
||||
2018-11-22 Janne Blomqvist <jb@gcc.gnu.org>
|
||||
|
||||
* acinclude.m4 (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Rename and test
|
||||
presence of atomic builtins instead of sync builtins.
|
||||
* configure.ac (LIBGFOR_CHECK_ATOMIC_FETCH_ADD): Call new test.
|
||||
* io/io.h (inc_waiting_locked): Use __atomic_fetch_add.
|
||||
(predec_waiting_locked): Use __atomic_add_fetch.
|
||||
(dec_waiting_unlocked): Use __atomic_fetch_add.
|
||||
* config.h.in: Regenerated.
|
||||
* configure: Regenerated.
|
||||
* Makefile.in: Regenerated.
|
||||
|
||||
2018-11-09 Jerry DeLisle <jvdelisle@gcc.gnu.org>
|
||||
|
||||
PR libfortran/78351
|
||||
|
@ -690,6 +690,7 @@ pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
|
@ -59,17 +59,17 @@ extern void bar(void) __attribute__((alias("foo")));]],
|
||||
[Define to 1 if the target supports __attribute__((alias(...))).])
|
||||
fi])
|
||||
|
||||
dnl Check whether the target supports __sync_fetch_and_add.
|
||||
AC_DEFUN([LIBGFOR_CHECK_SYNC_FETCH_AND_ADD], [
|
||||
AC_CACHE_CHECK([whether the target supports __sync_fetch_and_add],
|
||||
libgfor_cv_have_sync_fetch_and_add, [
|
||||
dnl Check whether the target supports __atomic_fetch_add.
|
||||
AC_DEFUN([LIBGFOR_CHECK_ATOMIC_FETCH_ADD], [
|
||||
AC_CACHE_CHECK([whether the target supports __atomic_fetch_add],
|
||||
libgfor_cv_have_atomic_fetch_add, [
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[int foovar = 0;]], [[
|
||||
if (foovar <= 0) return __sync_fetch_and_add (&foovar, 1);
|
||||
if (foovar > 10) return __sync_add_and_fetch (&foovar, -1);]])],
|
||||
libgfor_cv_have_sync_fetch_and_add=yes, libgfor_cv_have_sync_fetch_and_add=no)])
|
||||
if test $libgfor_cv_have_sync_fetch_and_add = yes; then
|
||||
AC_DEFINE(HAVE_SYNC_FETCH_AND_ADD, 1,
|
||||
[Define to 1 if the target supports __sync_fetch_and_add])
|
||||
if (foovar <= 0) return __atomic_fetch_add (&foovar, 1, __ATOMIC_ACQ_REL);
|
||||
if (foovar > 10) return __atomic_add_fetch (&foovar, -1, __ATOMIC_ACQ_REL);]])],
|
||||
libgfor_cv_have_atomic_fetch_add=yes, libgfor_cv_have_atomic_fetch_add=no)])
|
||||
if test $libgfor_cv_have_atomic_fetch_add = yes; then
|
||||
AC_DEFINE(HAVE_ATOMIC_FETCH_ADD, 1,
|
||||
[Define to 1 if the target supports __atomic_fetch_add])
|
||||
fi])
|
||||
|
||||
dnl Check for pragma weak.
|
||||
|
@ -72,6 +72,9 @@
|
||||
/* Define to 1 if you have the `atanl' function. */
|
||||
#undef HAVE_ATANL
|
||||
|
||||
/* Define to 1 if the target supports __atomic_fetch_add */
|
||||
#undef HAVE_ATOMIC_FETCH_ADD
|
||||
|
||||
/* Define to 1 if the target supports __attribute__((alias(...))). */
|
||||
#undef HAVE_ATTRIBUTE_ALIAS
|
||||
|
||||
@ -741,9 +744,6 @@
|
||||
/* Define to 1 if you have the `symlink' function. */
|
||||
#undef HAVE_SYMLINK
|
||||
|
||||
/* Define to 1 if the target supports __sync_fetch_and_add */
|
||||
#undef HAVE_SYNC_FETCH_AND_ADD
|
||||
|
||||
/* Define to 1 if you have the <sys/random.h> header file. */
|
||||
#undef HAVE_SYS_RANDOM_H
|
||||
|
||||
|
52
libgfortran/configure
vendored
52
libgfortran/configure
vendored
@ -780,6 +780,7 @@ infodir
|
||||
docdir
|
||||
oldincludedir
|
||||
includedir
|
||||
runstatedir
|
||||
localstatedir
|
||||
sharedstatedir
|
||||
sysconfdir
|
||||
@ -870,6 +871,7 @@ datadir='${datarootdir}'
|
||||
sysconfdir='${prefix}/etc'
|
||||
sharedstatedir='${prefix}/com'
|
||||
localstatedir='${prefix}/var'
|
||||
runstatedir='${localstatedir}/run'
|
||||
includedir='${prefix}/include'
|
||||
oldincludedir='/usr/include'
|
||||
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
|
||||
@ -1122,6 +1124,15 @@ do
|
||||
| -silent | --silent | --silen | --sile | --sil)
|
||||
silent=yes ;;
|
||||
|
||||
-runstatedir | --runstatedir | --runstatedi | --runstated \
|
||||
| --runstate | --runstat | --runsta | --runst | --runs \
|
||||
| --run | --ru | --r)
|
||||
ac_prev=runstatedir ;;
|
||||
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
|
||||
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
|
||||
| --run=* | --ru=* | --r=*)
|
||||
runstatedir=$ac_optarg ;;
|
||||
|
||||
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
|
||||
ac_prev=sbindir ;;
|
||||
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
|
||||
@ -1259,7 +1270,7 @@ fi
|
||||
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
|
||||
datadir sysconfdir sharedstatedir localstatedir includedir \
|
||||
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
|
||||
libdir localedir mandir
|
||||
libdir localedir mandir runstatedir
|
||||
do
|
||||
eval ac_val=\$$ac_var
|
||||
# Remove trailing slashes.
|
||||
@ -1412,6 +1423,7 @@ Fine tuning of the installation directories:
|
||||
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
|
||||
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
|
||||
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
|
||||
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
|
||||
--libdir=DIR object code libraries [EPREFIX/lib]
|
||||
--includedir=DIR C header files [PREFIX/include]
|
||||
--oldincludedir=DIR C header files for non-gcc [/usr/include]
|
||||
@ -12684,7 +12696,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12687 "configure"
|
||||
#line 12699 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -12790,7 +12802,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<_LT_EOF
|
||||
#line 12793 "configure"
|
||||
#line 12805 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -16039,7 +16051,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@ -16085,7 +16097,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@ -16109,7 +16121,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@ -16154,7 +16166,7 @@ else
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@ -16178,7 +16190,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
We can't simply define LARGE_OFF_T to be 9223372036854775807,
|
||||
since some C++ compilers masquerading as C compilers
|
||||
incorrectly reject 9223372036854775807. */
|
||||
#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62))
|
||||
#define LARGE_OFF_T ((((off_t) 1 << 31) << 31) - 1 + (((off_t) 1 << 31) << 31))
|
||||
int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721
|
||||
&& LARGE_OFF_T % 2147483647 == 1)
|
||||
? 1 : -1];
|
||||
@ -26283,11 +26295,11 @@ $as_echo "#define HAVE_ATTRIBUTE_ALIAS 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
# Check out sync builtins support.
|
||||
# Check out atomic builtins support.
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports __sync_fetch_and_add" >&5
|
||||
$as_echo_n "checking whether the target supports __sync_fetch_and_add... " >&6; }
|
||||
if ${libgfor_cv_have_sync_fetch_and_add+:} false; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the target supports __atomic_fetch_add" >&5
|
||||
$as_echo_n "checking whether the target supports __atomic_fetch_add... " >&6; }
|
||||
if ${libgfor_cv_have_atomic_fetch_add+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
|
||||
@ -26301,25 +26313,25 @@ int
|
||||
main ()
|
||||
{
|
||||
|
||||
if (foovar <= 0) return __sync_fetch_and_add (&foovar, 1);
|
||||
if (foovar > 10) return __sync_add_and_fetch (&foovar, -1);
|
||||
if (foovar <= 0) return __atomic_fetch_add (&foovar, 1, __ATOMIC_ACQ_REL);
|
||||
if (foovar > 10) return __atomic_add_fetch (&foovar, -1, __ATOMIC_ACQ_REL);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
libgfor_cv_have_sync_fetch_and_add=yes
|
||||
libgfor_cv_have_atomic_fetch_add=yes
|
||||
else
|
||||
libgfor_cv_have_sync_fetch_and_add=no
|
||||
libgfor_cv_have_atomic_fetch_add=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_sync_fetch_and_add" >&5
|
||||
$as_echo "$libgfor_cv_have_sync_fetch_and_add" >&6; }
|
||||
if test $libgfor_cv_have_sync_fetch_and_add = yes; then
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libgfor_cv_have_atomic_fetch_add" >&5
|
||||
$as_echo "$libgfor_cv_have_atomic_fetch_add" >&6; }
|
||||
if test $libgfor_cv_have_atomic_fetch_add = yes; then
|
||||
|
||||
$as_echo "#define HAVE_SYNC_FETCH_AND_ADD 1" >>confdefs.h
|
||||
$as_echo "#define HAVE_ATOMIC_FETCH_ADD 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
|
@ -608,8 +608,8 @@ fi
|
||||
LIBGFOR_CHECK_ATTRIBUTE_VISIBILITY
|
||||
LIBGFOR_CHECK_ATTRIBUTE_ALIAS
|
||||
|
||||
# Check out sync builtins support.
|
||||
LIBGFOR_CHECK_SYNC_FETCH_AND_ADD
|
||||
# Check out atomic builtins support.
|
||||
LIBGFOR_CHECK_ATOMIC_FETCH_ADD
|
||||
|
||||
# Check out #pragma weak.
|
||||
LIBGFOR_GTHREAD_WEAK
|
||||
|
@ -961,8 +961,8 @@ internal_proto(free_ionml);
|
||||
static inline void
|
||||
inc_waiting_locked (gfc_unit *u)
|
||||
{
|
||||
#ifdef HAVE_SYNC_FETCH_AND_ADD
|
||||
(void) __sync_fetch_and_add (&u->waiting, 1);
|
||||
#ifdef HAVE_ATOMIC_FETCH_ADD
|
||||
(void) __atomic_fetch_add (&u->waiting, 1, __ATOMIC_RELAXED);
|
||||
#else
|
||||
u->waiting++;
|
||||
#endif
|
||||
@ -971,8 +971,20 @@ inc_waiting_locked (gfc_unit *u)
|
||||
static inline int
|
||||
predec_waiting_locked (gfc_unit *u)
|
||||
{
|
||||
#ifdef HAVE_SYNC_FETCH_AND_ADD
|
||||
return __sync_add_and_fetch (&u->waiting, -1);
|
||||
#ifdef HAVE_ATOMIC_FETCH_ADD
|
||||
/* Note that the pattern
|
||||
|
||||
if (predec_waiting_locked (u) == 0)
|
||||
// destroy u
|
||||
|
||||
could be further optimized by making this be an __ATOMIC_RELEASE,
|
||||
and then inserting a
|
||||
|
||||
__atomic_thread_fence (__ATOMIC_ACQUIRE);
|
||||
|
||||
inside the branch before destroying. But for now, lets keep it
|
||||
simple. */
|
||||
return __atomic_add_fetch (&u->waiting, -1, __ATOMIC_ACQ_REL);
|
||||
#else
|
||||
return --u->waiting;
|
||||
#endif
|
||||
@ -981,8 +993,8 @@ predec_waiting_locked (gfc_unit *u)
|
||||
static inline void
|
||||
dec_waiting_unlocked (gfc_unit *u)
|
||||
{
|
||||
#ifdef HAVE_SYNC_FETCH_AND_ADD
|
||||
(void) __sync_fetch_and_add (&u->waiting, -1);
|
||||
#ifdef HAVE_ATOMIC_FETCH_ADD
|
||||
(void) __atomic_fetch_add (&u->waiting, -1, __ATOMIC_RELAXED);
|
||||
#else
|
||||
__gthread_mutex_lock (&unit_lock);
|
||||
u->waiting--;
|
||||
|
Loading…
Reference in New Issue
Block a user