1 /* Single-image implementation of GNU Fortran Coarray Library
2 Copyright (C) 2011-2014 Free Software Foundation, Inc.
3 Contributed by Tobias Burnus <burnus@net-b.de>
5 This file is part of the GNU Fortran Coarray Runtime Library (libcaf).
7 Libcaf is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 Libcaf is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
27 #include <stdio.h> /* For fputs and fprintf. */
28 #include <stdlib.h> /* For exit and malloc. */
29 #include <string.h> /* For memcpy and memset. */
30 #include <stdarg.h> /* For variadic arguments. */
33 /* Define GFC_CAF_CHECK to enable run-time checking. */
34 /* #define GFC_CAF_CHECK 1 */
36 typedef void* single_token_t
;
37 #define TOKEN(X) ((single_token_t) (X))
39 /* Single-image implementation of the CAF library.
40 Note: For performance reasons -fcoarry=single should be used
41 rather than this library. */
43 /* Global variables. */
44 caf_static_t
*caf_static_list
= NULL
;
47 /* Keep in sync with mpi.c. */
49 caf_runtime_error (const char *message
, ...)
52 fprintf (stderr
, "Fortran runtime error: ");
53 va_start (ap
, message
);
54 vfprintf (stderr
, message
, ap
);
56 fprintf (stderr
, "\n");
58 /* FIXME: Shutdown the Fortran RTL to flush the buffer. PR 43849. */
63 _gfortran_caf_init (int *argc
__attribute__ ((unused
)),
64 char ***argv
__attribute__ ((unused
)))
70 _gfortran_caf_finalize (void)
72 while (caf_static_list
!= NULL
)
74 caf_static_t
*tmp
= caf_static_list
->prev
;
75 free (caf_static_list
->token
);
76 free (caf_static_list
);
77 caf_static_list
= tmp
;
83 _gfortran_caf_this_image (int distance
__attribute__ ((unused
)))
90 _gfortran_caf_num_images (int distance
__attribute__ ((unused
)),
91 int failed
__attribute__ ((unused
)))
98 _gfortran_caf_register (size_t size
, caf_register_t type
, caf_token_t
*token
,
99 int *stat
, char *errmsg
, int errmsg_len
)
103 if (type
== CAF_REGTYPE_LOCK_STATIC
|| type
== CAF_REGTYPE_LOCK_ALLOC
104 || type
== CAF_REGTYPE_CRITICAL
)
105 local
= calloc (size
, sizeof (bool));
107 local
= malloc (size
);
108 *token
= malloc (sizeof (single_token_t
));
110 if (unlikely (local
== NULL
|| token
== NULL
))
112 const char msg
[] = "Failed to allocate coarray";
118 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
119 : (int) sizeof (msg
);
120 memcpy (errmsg
, msg
, len
);
121 if (errmsg_len
> len
)
122 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
127 caf_runtime_error (msg
);
135 if (type
== CAF_REGTYPE_COARRAY_STATIC
|| type
== CAF_REGTYPE_LOCK_STATIC
136 || type
== CAF_REGTYPE_CRITICAL
)
138 caf_static_t
*tmp
= malloc (sizeof (caf_static_t
));
139 tmp
->prev
= caf_static_list
;
141 caf_static_list
= tmp
;
148 _gfortran_caf_deregister (caf_token_t
*token
, int *stat
,
149 char *errmsg
__attribute__ ((unused
)),
150 int errmsg_len
__attribute__ ((unused
)))
152 free (TOKEN(*token
));
160 _gfortran_caf_sync_all (int *stat
,
161 char *errmsg
__attribute__ ((unused
)),
162 int errmsg_len
__attribute__ ((unused
)))
170 _gfortran_caf_sync_images (int count
__attribute__ ((unused
)),
171 int images
[] __attribute__ ((unused
)),
173 char *errmsg
__attribute__ ((unused
)),
174 int errmsg_len
__attribute__ ((unused
)))
179 for (i
= 0; i
< count
; i
++)
182 fprintf (stderr
, "COARRAY ERROR: Invalid image index %d to SYNC "
183 "IMAGES", images
[i
]);
194 _gfortran_caf_error_stop_str (const char *string
, int32_t len
)
196 fputs ("ERROR STOP ", stderr
);
198 fputc (*(string
++), stderr
);
199 fputs ("\n", stderr
);
206 _gfortran_caf_error_stop (int32_t error
)
208 fprintf (stderr
, "ERROR STOP %d\n", error
);
214 _gfortran_caf_co_sum (gfc_descriptor_t
*a
__attribute__ ((unused
)),
215 int result_image
__attribute__ ((unused
)),
216 int *stat
, char *errmsg
__attribute__ ((unused
)),
217 int errmsg_len
__attribute__ ((unused
)))
224 _gfortran_caf_co_min (gfc_descriptor_t
*a
__attribute__ ((unused
)),
225 int result_image
__attribute__ ((unused
)),
226 int *stat
, char *errmsg
__attribute__ ((unused
)),
227 int src_len
__attribute__ ((unused
)),
228 int errmsg_len
__attribute__ ((unused
)))
235 _gfortran_caf_co_max (gfc_descriptor_t
*a
__attribute__ ((unused
)),
236 int result_image
__attribute__ ((unused
)),
237 int *stat
, char *errmsg
__attribute__ ((unused
)),
238 int src_len
__attribute__ ((unused
)),
239 int errmsg_len
__attribute__ ((unused
)))
247 assign_char4_from_char1 (size_t dst_size
, size_t src_size
, uint32_t *dst
,
251 n
= dst_size
/4 > src_size
? src_size
: dst_size
/4;
252 for (i
= 0; i
< n
; ++i
)
253 dst
[i
] = (int32_t) src
[i
];
254 for (; i
< dst_size
/4; ++i
)
255 dst
[i
] = (int32_t) ' ';
260 assign_char1_from_char4 (size_t dst_size
, size_t src_size
, unsigned char *dst
,
264 n
= dst_size
> src_size
/4 ? src_size
/4 : dst_size
;
265 for (i
= 0; i
< n
; ++i
)
266 dst
[i
] = src
[i
] > UINT8_MAX
? (unsigned char) '?' : (unsigned char) src
[i
];
268 memset(&dst
[n
], ' ', dst_size
- n
);
273 convert_type (void *dst
, int dst_type
, int dst_kind
, void *src
, int src_type
,
276 #ifdef HAVE_GFC_INTEGER_16
277 typedef __int128 int128t
;
279 typedef int64_t int128t
;
282 #if defined(GFC_REAL_16_IS_LONG_DOUBLE)
283 typedef long double real128t
;
284 typedef _Complex
long double complex128t
;
285 #elif defined(HAVE_GFC_REAL_16)
286 typedef _Complex
float __attribute__((mode(TC
))) __complex128
;
287 typedef __float128 real128t
;
288 typedef __complex128 complex128t
;
289 #elif defined(HAVE_GFC_REAL_10)
290 typedef long double real128t
;
291 typedef long double complex128t
;
293 typedef double real128t
;
294 typedef _Complex
double complex128t
;
298 real128t real_val
= 0;
299 complex128t cmpx_val
= 0;
305 int_val
= *(int8_t*) src
;
306 else if (src_kind
== 2)
307 int_val
= *(int16_t*) src
;
308 else if (src_kind
== 4)
309 int_val
= *(int32_t*) src
;
310 else if (src_kind
== 8)
311 int_val
= *(int64_t*) src
;
312 #ifdef HAVE_GFC_INTEGER_16
313 else if (src_kind
== 16)
314 int_val
= *(int128t
*) src
;
321 real_val
= *(float*) src
;
322 else if (src_kind
== 8)
323 real_val
= *(double*) src
;
324 #ifdef HAVE_GFC_REAL_10
325 else if (src_kind
== 10)
326 real_val
= *(long double*) src
;
328 #ifdef HAVE_GFC_REAL_16
329 else if (src_kind
== 16)
330 real_val
= *(real128t
*) src
;
337 cmpx_val
= *(_Complex
float*) src
;
338 else if (src_kind
== 8)
339 cmpx_val
= *(_Complex
double*) src
;
340 #ifdef HAVE_GFC_REAL_10
341 else if (src_kind
== 10)
342 cmpx_val
= *(_Complex
long double*) src
;
344 #ifdef HAVE_GFC_REAL_16
345 else if (src_kind
== 16)
346 cmpx_val
= *(complex128t
*) src
;
358 if (src_type
== BT_INTEGER
)
361 *(int8_t*) dst
= (int8_t) int_val
;
362 else if (dst_kind
== 2)
363 *(int16_t*) dst
= (int16_t) int_val
;
364 else if (dst_kind
== 4)
365 *(int32_t*) dst
= (int32_t) int_val
;
366 else if (dst_kind
== 8)
367 *(int64_t*) dst
= (int64_t) int_val
;
368 #ifdef HAVE_GFC_INTEGER_16
369 else if (dst_kind
== 16)
370 *(int128t
*) dst
= (int128t
) int_val
;
375 else if (src_type
== BT_REAL
)
378 *(int8_t*) dst
= (int8_t) real_val
;
379 else if (dst_kind
== 2)
380 *(int16_t*) dst
= (int16_t) real_val
;
381 else if (dst_kind
== 4)
382 *(int32_t*) dst
= (int32_t) real_val
;
383 else if (dst_kind
== 8)
384 *(int64_t*) dst
= (int64_t) real_val
;
385 #ifdef HAVE_GFC_INTEGER_16
386 else if (dst_kind
== 16)
387 *(int128t
*) dst
= (int128t
) real_val
;
392 else if (src_type
== BT_COMPLEX
)
395 *(int8_t*) dst
= (int8_t) cmpx_val
;
396 else if (dst_kind
== 2)
397 *(int16_t*) dst
= (int16_t) cmpx_val
;
398 else if (dst_kind
== 4)
399 *(int32_t*) dst
= (int32_t) cmpx_val
;
400 else if (dst_kind
== 8)
401 *(int64_t*) dst
= (int64_t) cmpx_val
;
402 #ifdef HAVE_GFC_INTEGER_16
403 else if (dst_kind
== 16)
404 *(int128t
*) dst
= (int128t
) cmpx_val
;
413 if (src_type
== BT_INTEGER
)
416 *(float*) dst
= (float) int_val
;
417 else if (dst_kind
== 8)
418 *(double*) dst
= (double) int_val
;
419 #ifdef HAVE_GFC_REAL_10
420 else if (dst_kind
== 10)
421 *(long double*) dst
= (long double) int_val
;
423 #ifdef HAVE_GFC_REAL_16
424 else if (dst_kind
== 16)
425 *(real128t
*) dst
= (real128t
) int_val
;
430 else if (src_type
== BT_REAL
)
433 *(float*) dst
= (float) real_val
;
434 else if (dst_kind
== 8)
435 *(double*) dst
= (double) real_val
;
436 #ifdef HAVE_GFC_REAL_10
437 else if (dst_kind
== 10)
438 *(long double*) dst
= (long double) real_val
;
440 #ifdef HAVE_GFC_REAL_16
441 else if (dst_kind
== 16)
442 *(real128t
*) dst
= (real128t
) real_val
;
447 else if (src_type
== BT_COMPLEX
)
450 *(float*) dst
= (float) cmpx_val
;
451 else if (dst_kind
== 8)
452 *(double*) dst
= (double) cmpx_val
;
453 #ifdef HAVE_GFC_REAL_10
454 else if (dst_kind
== 10)
455 *(long double*) dst
= (long double) cmpx_val
;
457 #ifdef HAVE_GFC_REAL_16
458 else if (dst_kind
== 16)
459 *(real128t
*) dst
= (real128t
) cmpx_val
;
466 if (src_type
== BT_INTEGER
)
469 *(_Complex
float*) dst
= (_Complex
float) int_val
;
470 else if (dst_kind
== 8)
471 *(_Complex
double*) dst
= (_Complex
double) int_val
;
472 #ifdef HAVE_GFC_REAL_10
473 else if (dst_kind
== 10)
474 *(_Complex
long double*) dst
= (_Complex
long double) int_val
;
476 #ifdef HAVE_GFC_REAL_16
477 else if (dst_kind
== 16)
478 *(complex128t
*) dst
= (complex128t
) int_val
;
483 else if (src_type
== BT_REAL
)
486 *(_Complex
float*) dst
= (_Complex
float) real_val
;
487 else if (dst_kind
== 8)
488 *(_Complex
double*) dst
= (_Complex
double) real_val
;
489 #ifdef HAVE_GFC_REAL_10
490 else if (dst_kind
== 10)
491 *(_Complex
long double*) dst
= (_Complex
long double) real_val
;
493 #ifdef HAVE_GFC_REAL_16
494 else if (dst_kind
== 16)
495 *(complex128t
*) dst
= (complex128t
) real_val
;
500 else if (src_type
== BT_COMPLEX
)
503 *(_Complex
float*) dst
= (_Complex
float) cmpx_val
;
504 else if (dst_kind
== 8)
505 *(_Complex
double*) dst
= (_Complex
double) cmpx_val
;
506 #ifdef HAVE_GFC_REAL_10
507 else if (dst_kind
== 10)
508 *(_Complex
long double*) dst
= (_Complex
long double) cmpx_val
;
510 #ifdef HAVE_GFC_REAL_16
511 else if (dst_kind
== 16)
512 *(complex128t
*) dst
= (complex128t
) cmpx_val
;
525 fprintf (stderr
, "libcaf_single RUNTIME ERROR: Cannot convert type %d kind "
526 "%d to type %d kind %d\n", src_type
, src_kind
, dst_type
, dst_kind
);
532 _gfortran_caf_get (caf_token_t token
, size_t offset
,
533 int image_index
__attribute__ ((unused
)),
534 gfc_descriptor_t
*src
,
535 caf_vector_t
*src_vector
__attribute__ ((unused
)),
536 gfc_descriptor_t
*dest
, int src_kind
, int dst_kind
)
538 /* FIXME: Handle vector subscripts. */
541 int rank
= GFC_DESCRIPTOR_RANK (dest
);
542 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
543 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
547 void *sr
= (void *) ((char *) TOKEN (token
) + offset
);
548 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
549 && dst_kind
== src_kind
)
551 memmove (GFC_DESCRIPTOR_DATA (dest
), sr
,
552 dst_size
> src_size
? src_size
: dst_size
);
553 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
556 memset ((void*)(char*) GFC_DESCRIPTOR_DATA (dest
) + src_size
,
557 ' ', dst_size
- src_size
);
558 else /* dst_kind == 4. */
559 for (i
= src_size
/4; i
< dst_size
/4; i
++)
560 ((int32_t*) GFC_DESCRIPTOR_DATA (dest
))[i
] = (int32_t) ' ';
563 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
564 assign_char1_from_char4 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
566 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
567 assign_char4_from_char1 (dst_size
, src_size
, GFC_DESCRIPTOR_DATA (dest
),
570 convert_type (GFC_DESCRIPTOR_DATA (dest
), GFC_DESCRIPTOR_TYPE (dest
),
571 dst_kind
, sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
576 for (j
= 0; j
< rank
; j
++)
578 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
587 for (i
= 0; i
< size
; i
++)
589 ptrdiff_t array_offset_dst
= 0;
590 ptrdiff_t stride
= 1;
591 ptrdiff_t extent
= 1;
592 for (j
= 0; j
< rank
-1; j
++)
594 array_offset_dst
+= ((i
/ (extent
*stride
))
595 % (dest
->dim
[j
]._ubound
596 - dest
->dim
[j
].lower_bound
+ 1))
597 * dest
->dim
[j
]._stride
;
598 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
599 stride
= dest
->dim
[j
]._stride
;
601 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
602 void *dst
= dest
->base_addr
+ array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
);
604 ptrdiff_t array_offset_sr
= 0;
607 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
609 array_offset_sr
+= ((i
/ (extent
*stride
))
610 % (src
->dim
[j
]._ubound
611 - src
->dim
[j
].lower_bound
+ 1))
612 * src
->dim
[j
]._stride
;
613 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
614 stride
= src
->dim
[j
]._stride
;
616 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
617 void *sr
= (void *)((char *) TOKEN (token
) + offset
618 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
620 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
621 && dst_kind
== src_kind
)
623 memmove (dst
, sr
, dst_size
> src_size
? src_size
: dst_size
);
624 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
627 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
628 else /* dst_kind == 4. */
629 for (k
= src_size
/4; k
< dst_size
/4; k
++)
630 ((int32_t*) dst
)[k
] = (int32_t) ' ';
633 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
634 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
635 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
636 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
638 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
639 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
645 _gfortran_caf_send (caf_token_t token
, size_t offset
,
646 int image_index
__attribute__ ((unused
)),
647 gfc_descriptor_t
*dest
,
648 caf_vector_t
*dst_vector
__attribute__ ((unused
)),
649 gfc_descriptor_t
*src
, int dst_kind
, int src_kind
)
651 /* FIXME: Handle vector subscripts. */
654 int rank
= GFC_DESCRIPTOR_RANK (dest
);
655 size_t src_size
= GFC_DESCRIPTOR_SIZE (src
);
656 size_t dst_size
= GFC_DESCRIPTOR_SIZE (dest
);
660 void *dst
= (void *) ((char *) TOKEN (token
) + offset
);
661 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
662 && dst_kind
== src_kind
)
664 memmove (dst
, GFC_DESCRIPTOR_DATA (src
),
665 dst_size
> src_size
? src_size
: dst_size
);
666 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
669 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
670 else /* dst_kind == 4. */
671 for (i
= src_size
/4; i
< dst_size
/4; i
++)
672 ((int32_t*) dst
)[i
] = (int32_t) ' ';
675 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
676 assign_char1_from_char4 (dst_size
, src_size
, dst
,
677 GFC_DESCRIPTOR_DATA (src
));
678 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
679 assign_char4_from_char1 (dst_size
, src_size
, dst
,
680 GFC_DESCRIPTOR_DATA (src
));
682 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
683 GFC_DESCRIPTOR_DATA (src
), GFC_DESCRIPTOR_TYPE (src
),
689 for (j
= 0; j
< rank
; j
++)
691 ptrdiff_t dimextent
= dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1;
700 for (i
= 0; i
< size
; i
++)
702 ptrdiff_t array_offset_dst
= 0;
703 ptrdiff_t stride
= 1;
704 ptrdiff_t extent
= 1;
705 for (j
= 0; j
< rank
-1; j
++)
707 array_offset_dst
+= ((i
/ (extent
*stride
))
708 % (dest
->dim
[j
]._ubound
709 - dest
->dim
[j
].lower_bound
+ 1))
710 * dest
->dim
[j
]._stride
;
711 extent
= (dest
->dim
[j
]._ubound
- dest
->dim
[j
].lower_bound
+ 1);
712 stride
= dest
->dim
[j
]._stride
;
714 array_offset_dst
+= (i
/ extent
) * dest
->dim
[rank
-1]._stride
;
715 void *dst
= (void *)((char *) TOKEN (token
) + offset
716 + array_offset_dst
*GFC_DESCRIPTOR_SIZE (dest
));
718 if (GFC_DESCRIPTOR_RANK (src
) != 0)
720 ptrdiff_t array_offset_sr
= 0;
723 for (j
= 0; j
< GFC_DESCRIPTOR_RANK (src
)-1; j
++)
725 array_offset_sr
+= ((i
/ (extent
*stride
))
726 % (src
->dim
[j
]._ubound
727 - src
->dim
[j
].lower_bound
+ 1))
728 * src
->dim
[j
]._stride
;
729 extent
= (src
->dim
[j
]._ubound
- src
->dim
[j
].lower_bound
+ 1);
730 stride
= src
->dim
[j
]._stride
;
732 array_offset_sr
+= (i
/ extent
) * src
->dim
[rank
-1]._stride
;
733 sr
= (void *)((char *) src
->base_addr
734 + array_offset_sr
*GFC_DESCRIPTOR_SIZE (src
));
739 if (GFC_DESCRIPTOR_TYPE (dest
) == GFC_DESCRIPTOR_TYPE (src
)
740 && dst_kind
== src_kind
)
743 dst_size
> src_size
? src_size
: dst_size
);
744 if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_size
> src_size
)
747 memset ((void*)(char*) dst
+ src_size
, ' ', dst_size
-src_size
);
748 else /* dst_kind == 4. */
749 for (k
= src_size
/4; k
< dst_size
/4; k
++)
750 ((int32_t*) dst
)[k
] = (int32_t) ' ';
753 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
&& dst_kind
== 1)
754 assign_char1_from_char4 (dst_size
, src_size
, dst
, sr
);
755 else if (GFC_DESCRIPTOR_TYPE (dest
) == BT_CHARACTER
)
756 assign_char4_from_char1 (dst_size
, src_size
, dst
, sr
);
758 convert_type (dst
, GFC_DESCRIPTOR_TYPE (dest
), dst_kind
,
759 sr
, GFC_DESCRIPTOR_TYPE (src
), src_kind
);
765 _gfortran_caf_sendget (caf_token_t dst_token
, size_t dst_offset
,
766 int dst_image_index
, gfc_descriptor_t
*dest
,
767 caf_vector_t
*dst_vector
, caf_token_t src_token
,
769 int src_image_index
__attribute__ ((unused
)),
770 gfc_descriptor_t
*src
,
771 caf_vector_t
*src_vector
__attribute__ ((unused
)),
772 int dst_kind
, int src_kind
)
774 /* FIXME: Handle vector subscript of 'src_vector'. */
775 /* For a single image, src->base_addr should be the same as src_token + offset
776 but to play save, we do it properly. */
777 void *src_base
= GFC_DESCRIPTOR_DATA (src
);
778 GFC_DESCRIPTOR_DATA (src
) = (void *) ((char *) TOKEN (src_token
) + src_offset
);
779 _gfortran_caf_send (dst_token
, dst_offset
, dst_image_index
, dest
, dst_vector
,
780 src
, dst_kind
, src_kind
);
781 GFC_DESCRIPTOR_DATA (src
) = src_base
;
786 _gfortran_caf_atomic_define (caf_token_t token
, size_t offset
,
787 int image_index
__attribute__ ((unused
)),
788 void *value
, int *stat
,
789 int type
__attribute__ ((unused
)), int kind
)
793 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
795 __atomic_store (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
802 _gfortran_caf_atomic_ref (caf_token_t token
, size_t offset
,
803 int image_index
__attribute__ ((unused
)),
804 void *value
, int *stat
,
805 int type
__attribute__ ((unused
)), int kind
)
809 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
811 __atomic_load (atom
, (uint32_t *) value
, __ATOMIC_RELAXED
);
819 _gfortran_caf_atomic_cas (caf_token_t token
, size_t offset
,
820 int image_index
__attribute__ ((unused
)),
821 void *old
, void *compare
, void *new_val
, int *stat
,
822 int type
__attribute__ ((unused
)), int kind
)
826 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
828 *(uint32_t *) old
= *(uint32_t *) compare
;
829 (void) __atomic_compare_exchange_n (atom
, (uint32_t *) old
,
830 *(uint32_t *) new_val
, false,
831 __ATOMIC_RELAXED
, __ATOMIC_RELAXED
);
838 _gfortran_caf_atomic_op (int op
, caf_token_t token
, size_t offset
,
839 int image_index
__attribute__ ((unused
)),
840 void *value
, void *old
, int *stat
,
841 int type
__attribute__ ((unused
)), int kind
)
846 uint32_t *atom
= (uint32_t *) ((char *) TOKEN (token
) + offset
);
850 case GFC_CAF_ATOMIC_ADD
:
851 res
= __atomic_fetch_add (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
853 case GFC_CAF_ATOMIC_AND
:
854 res
= __atomic_fetch_and (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
856 case GFC_CAF_ATOMIC_OR
:
857 res
= __atomic_fetch_or (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
859 case GFC_CAF_ATOMIC_XOR
:
860 res
= __atomic_fetch_xor (atom
, *(uint32_t *) value
, __ATOMIC_RELAXED
);
863 __builtin_unreachable();
867 *(uint32_t *) old
= res
;
875 _gfortran_caf_lock (caf_token_t token
, size_t index
,
876 int image_index
__attribute__ ((unused
)),
877 int *aquired_lock
, int *stat
, char *errmsg
, int errmsg_len
)
879 const char *msg
= "Already locked";
880 bool *lock
= &((bool *) TOKEN (token
))[index
];
886 *aquired_lock
= (int) true;
894 *aquired_lock
= (int) false;
906 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
907 : (int) sizeof (msg
);
908 memcpy (errmsg
, msg
, len
);
909 if (errmsg_len
> len
)
910 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
914 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));
919 _gfortran_caf_unlock (caf_token_t token
, size_t index
,
920 int image_index
__attribute__ ((unused
)),
921 int *stat
, char *errmsg
, int errmsg_len
)
923 const char *msg
= "Variable is not locked";
924 bool *lock
= &((bool *) TOKEN (token
))[index
];
939 int len
= ((int) sizeof (msg
) > errmsg_len
) ? errmsg_len
940 : (int) sizeof (msg
);
941 memcpy (errmsg
, msg
, len
);
942 if (errmsg_len
> len
)
943 memset (&errmsg
[len
], ' ', errmsg_len
-len
);
947 _gfortran_caf_error_stop_str (msg
, (int32_t) strlen (msg
));