ISO/IEC JTC1/SC22/WG5 N1753 Atomic LOAD/STORE intrinsics instead of VOLATILE coarrays Aleksandar Donev There is contention over whether to include VOLATILE coarrays in Fortran 2008. This proposal offers an alternative that allows the same functionality (actually, more) and efficiency as do VOLATILE coarrays, and, in my opinion, has much cleaner semantics. The present CD allows a VOLATILE variable to be referenced by an image concurrently (without segment ordering) with it being defined by another image. This requires that atomic instructions be used by the processor for both the definition and the reference, to ensure that junk values are not produced due to concurrency. Most architectures have several such instructions, but the compiler needs to be informed about using those instructions. The two fundamental ones are an atomic load and an atomic store instruction. I propose that these be supported in the form of two new intrinsics: GET_ATOMIC and SET_ATOMIC. References to these intrinsics would be excluded from the segment ordering rules. Note that this would allow concurrent definititions (atomic stores), which the current CD does not allow for volatile coarrays. I prefer subroutines for both of these, but of course, the load might be a function as well. The argument should be restricted to be a scalar of certain types (e.g., an integer of a given kind, logical, single-precision real)---to be decided in discussions with vendors. In the future it could be extended to arrays or arbitrary types (this will require locks to implement on most machines). Alternatively, and maybe better, two new statements could be added (GET ATOMIC and SET ATOMIC). Using these new intriniscs, the spin-lock example in Note. 8.38 of N1723: LOGICAL,VOLATILE :: LOCKED[*] = .TRUE. INTEGER :: IAM, P, Q IAM = THIS_IMAGE() IF (IAM == P) THEN ! Preceding segment SYNC MEMORY ! A LOCKED[Q] = .FALSE. ! segment Pi SYNC MEMORY ! B ELSE IF (IAM == Q) THEN DO WHILE (LOCKED); END DO ! segment Qj SYNC MEMORY ! C ! Subsequent segment END IF may be replaced by: LOGICAL :: LOCK[*] = .TRUE., LOCKED INTEGER :: IAM, P, Q IAM = THIS_IMAGE() IF (IAM == P) THEN ! Preceding segment SYNC MEMORY ! User-defined segment ordering CALL SET_ATOMIC(VARIABLE=LOCK[Q], VALUE=.FALSE.) ELSE IF (IAM == Q) THEN DO ! Spin loop CALL GET_ATOMIC(VARIABLE=LOCK, VALUE=LOCKED) IF(.NOT.LOCKED) EXIT END DO SYNC MEMORY ! User-defined segment ordering ! Subsequent segment END IF