diff options
author | Tobias Burnus <burnus@net-b.de> | 2014-07-12 21:02:57 +0200 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2014-07-12 21:02:57 +0200 |
commit | 42a8246dbdb963921fe5426ba34646f6399a412d (patch) | |
tree | 9c63676c636ff51b2efc0a019d14caccdf82245e /libgfortran | |
parent | 7f4aaf912bdab4fe3ccad012add9a1d00a26dab1 (diff) | |
download | gcc-42a8246dbdb963921fe5426ba34646f6399a412d.tar.gz |
libgfortran.h (libcaf_atomic_codes): Add.
2014-07-12 Tobias Burnus <burnus@net-b.de>
gcc/fortran/
* libgfortran.h (libcaf_atomic_codes): Add.
* trans-decl.c (gfor_fndecl_caf_atomic_def,
gfor_fndecl_caf_atomic_ref, gfor_fndecl_caf_atomic_cas,
gfor_fndecl_caf_atomic_op): New variables.
(gfc_build_builtin_function_decls): Initialize them.
* trans.h (gfor_fndecl_caf_atomic_def,
gfor_fndecl_caf_atomic_ref, gfor_fndecl_caf_atomic_cas,
gfor_fndecl_caf_atomic_op): New variables.
* trans-intrinsic.c (conv_intrinsic_atomic_op,
conv_intrinsic_atomic_ref, conv_intrinsic_atomic_cas):
Add library calls with -fcoarray=lib.
libgfortran/
* caf/libcaf.h (_gfortran_caf_atomic_define,
_gfortran_caf_atomic_ref, _gfortran_caf_atomic_op,
_gfortran_caf_atomic_cas): New prototypes.
* caf/single.c (_gfortran_caf_atomic_define,
_gfortran_caf_atomic_ref, _gfortran_caf_atomic_op,
_gfortran_caf_atomic_cas): New functions.
From-SVN: r212484
Diffstat (limited to 'libgfortran')
-rw-r--r-- | libgfortran/ChangeLog | 9 | ||||
-rw-r--r-- | libgfortran/caf/libcaf.h | 9 | ||||
-rw-r--r-- | libgfortran/caf/single.c | 90 |
3 files changed, 108 insertions, 0 deletions
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog index db9e42bd48a..8a71b8046fc 100644 --- a/libgfortran/ChangeLog +++ b/libgfortran/ChangeLog @@ -1,3 +1,12 @@ +2014-07-12 Tobias Burnus <burnus@net-b.de> + + * caf/libcaf.h (_gfortran_caf_atomic_define, + _gfortran_caf_atomic_ref, _gfortran_caf_atomic_op, + _gfortran_caf_atomic_cas): New prototypes. + * caf/single.c (_gfortran_caf_atomic_define, + _gfortran_caf_atomic_ref, _gfortran_caf_atomic_op, + _gfortran_caf_atomic_cas): New functions. + 2014-07-10 Francois-Xavier Coudert <fxcoudert@gcc.gnu.org> * config/fpu-*.h (get_fpu_rounding_mode, set_fpu_rounding_mode, diff --git a/libgfortran/caf/libcaf.h b/libgfortran/caf/libcaf.h index 2c97880f122..0ae7135885f 100644 --- a/libgfortran/caf/libcaf.h +++ b/libgfortran/caf/libcaf.h @@ -128,4 +128,13 @@ void _gfortran_caf_send (caf_token_t, size_t, int, gfc_descriptor_t *, void _gfortran_caf_sendget (caf_token_t, size_t, int, gfc_descriptor_t *, caf_vector_t *, caf_token_t, size_t, int, gfc_descriptor_t *, caf_vector_t *, int, int); + +void _gfortran_caf_atomic_define (caf_token_t, size_t, int, void *, int *, + int, int); +void _gfortran_caf_atomic_ref (caf_token_t, size_t, int, void *, int *, + int, int); +void _gfortran_caf_atomic_cas (caf_token_t, size_t, int, void *, void *, + void *, int *, int, int); +void _gfortran_caf_atomic_op (int, caf_token_t, size_t, int, void *, void *, + int *, int, int); #endif /* LIBCAF_H */ diff --git a/libgfortran/caf/single.c b/libgfortran/caf/single.c index d053c503129..1f5da7293e5 100644 --- a/libgfortran/caf/single.c +++ b/libgfortran/caf/single.c @@ -28,6 +28,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include <stdlib.h> /* For exit and malloc. */ #include <string.h> /* For memcpy and memset. */ #include <stdarg.h> /* For variadic arguments. */ +#include <assert.h> /* Define GFC_CAF_CHECK to enable run-time checking. */ /* #define GFC_CAF_CHECK 1 */ @@ -774,3 +775,92 @@ _gfortran_caf_sendget (caf_token_t dst_token, size_t dst_offset, src, dst_len, src_len); GFC_DESCRIPTOR_DATA (src) = src_base; } + + +void +_gfortran_caf_atomic_define (caf_token_t token, size_t offset, + int image_index __attribute__ ((unused)), + void *value, int *stat, + int type __attribute__ ((unused)), int kind) +{ + assert(kind == 4); + + uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset); + + __atomic_store (atom, (uint32_t *) value, __ATOMIC_RELAXED); + + if (stat) + *stat = 0; +} + +void +_gfortran_caf_atomic_ref (caf_token_t token, size_t offset, + int image_index __attribute__ ((unused)), + void *value, int *stat, + int type __attribute__ ((unused)), int kind) +{ + assert(kind == 4); + + uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset); + + __atomic_load (atom, (uint32_t *) value, __ATOMIC_RELAXED); + + if (stat) + *stat = 0; +} + + +void +_gfortran_caf_atomic_cas (caf_token_t token, size_t offset, + int image_index __attribute__ ((unused)), + void *old, void *compare, void *new_val, int *stat, + int type __attribute__ ((unused)), int kind) +{ + assert(kind == 4); + + uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset); + + *(uint32_t *) old = *(uint32_t *) compare; + (void) __atomic_compare_exchange_n (atom, (uint32_t *) old, + *(uint32_t *) new_val, false, + __ATOMIC_RELAXED, __ATOMIC_RELAXED); + if (stat) + *stat = 0; +} + + +void +_gfortran_caf_atomic_op (int op, caf_token_t token, size_t offset, + int image_index __attribute__ ((unused)), + void *value, void *old, int *stat, + int type __attribute__ ((unused)), int kind) +{ + assert(kind == 4); + + uint32_t res; + uint32_t *atom = (uint32_t *) ((char *) TOKEN (token) + offset); + + switch (op) + { + case GFC_CAF_ATOMIC_ADD: + res = __atomic_fetch_add (atom, *(uint32_t *) value, __ATOMIC_RELAXED); + break; + case GFC_CAF_ATOMIC_AND: + res = __atomic_fetch_and (atom, *(uint32_t *) value, __ATOMIC_RELAXED); + break; + case GFC_CAF_ATOMIC_OR: + res = __atomic_fetch_or (atom, *(uint32_t *) value, __ATOMIC_RELAXED); + break; + case GFC_CAF_ATOMIC_XOR: + res = __atomic_fetch_xor (atom, *(uint32_t *) value, __ATOMIC_RELAXED); + break; + default: + __builtin_unreachable(); + } + + if (old) + *(uint32_t *) old = res; + + if (stat) + *stat = 0; +} |