Timeouts in Co-array Fortran

Timeouts are important for programs that connect to external resources or that otherwise need to bound execution time. Implementing timeouts in Co-array Fortran requires careful use of synchronization primitives and image control statements.

program timeouts
    use iso_fortran_env
    implicit none

    integer :: image
    real :: start_time, current_time
    character(len=20) :: result

    ! For our example, suppose we're executing an external
    ! call that returns its result after 2s. We'll simulate
    ! this using a co-array and a delay.
    character(len=20), codimension[*] :: shared_result

    if (this_image() == 1) then
        call cpu_time(start_time)

        ! Simulate the delay of the external call
        do while (.true.)
            call cpu_time(current_time)
            if (current_time - start_time >= 2.0) then
                shared_result = "result 1"
                exit
            end if
        end do

        sync images(*)
    end if

    ! Here we implement a timeout using a busy-wait loop.
    ! We check for the result and also check if we've exceeded
    ! the timeout duration.
    if (this_image() == 2) then
        call cpu_time(start_time)
        do while (.true.)
            if (shared_result /= "") then
                result = shared_result
                print *, result
                exit
            end if

            call cpu_time(current_time)
            if (current_time - start_time >= 1.0) then
                print *, "timeout 1"
                exit
            end if
        end do
    end if

    ! If we allow a longer timeout of 3s, then we'll be able
    ! to receive the result.
    if (this_image() == 3) then
        call cpu_time(start_time)
        do while (.true.)
            if (shared_result /= "") then
                result = shared_result
                print *, result
                exit
            end if

            call cpu_time(current_time)
            if (current_time - start_time >= 3.0) then
                print *, "timeout 2"
                exit
            end if
        end do
    end if

end program timeouts

This Co-array Fortran program demonstrates the concept of timeouts. Unlike the original example, Co-array Fortran doesn’t have built-in channel or select constructs, so we use co-arrays and image control statements to simulate similar behavior.

In this program:

  1. We use a co-array shared_result to simulate the channel from the original example.

  2. Image 1 simulates the delayed operation by waiting for 2 seconds before setting the shared_result.

  3. Image 2 implements a 1-second timeout. It continually checks for the result and also checks if 1 second has elapsed.

  4. Image 3 implements a 3-second timeout, similar to Image 2 but with a longer duration.

To run this program, you would compile it with a Co-array Fortran compiler and run it with at least 3 images. The exact command would depend on your specific compiler and system.

Running this program should show the first operation timing out and the second succeeding, similar to the original example:

timeout 1
result 1

Note that the exact output may vary depending on system performance and the precision of the cpu_time function. Also, this implementation uses busy-waiting, which is not ideal for performance but serves to illustrate the concept of timeouts in Co-array Fortran.