[patch, fortran] Asynchronous I/O, take 3

Thomas König tk@tkoenig.net
Mon Jul 2 22:17:00 GMT 2018


Hello world,

the attached patch is the third take on Nicolas' and my patch
for implementing asynchronous I/O.  Some parts have been reworked, and 
several bugs which caused either incorrect I/O or hangs have been
fixed in the process.

I have to say that getting out these bugs has been much harder
than Nicolas and I originally thought, and that this has cost more
working hours than any other patch I have been involved in.

This has been regression-tested on x86_64-pc-linux-gnu. The new test
cases have also been tested in a tight loop with

n=1; while ./a.out; do echo -n $n " " ; n=$((n+1)); done

or (for async_io_3.f90, which is supposed to fail)

while true ; do ./a.out > /dev/null 2>&1 ;  echo -n $n " " ; n=$((n+1)); 
done

and the test cases also come up clean with valgrind --tool=drd
(which is a _very_ strict tool which, after this experience, I
wholeheartedly recommend for doing pthreads debugging).

The interface remains as before - link in pthread to get asynchronous
I/O, which matches what ifort does.

So, OK for trunk?

Regards

	Thomas

2018-07-02  Nicolas Koenig  <koenigni@gcc.gnu.org>
         Thomas Koenig <tkoenig@gcc.gnu.org>

         PR fortran/25829
         * gfortran.texi: Add description of asynchronous I/O.
         * trans-decl.c (gfc_finish_var_decl): Treat asynchronous variables
         as volatile.
         * trans-io.c (gfc_build_io_library_fndecls): Rename st_wait to
         st_wait_async and change argument spec from ".X" to ".w".
         (gfc_trans_wait): Pass ID argument via reference.

2018-07-02  Nicolas Koenig  <koenigni@gcc.gnu.org>
         Thomas Koenig <tkoenig@gcc.gnu.org>

         PR fortran/25829
         * gfortran.dg/f2003_inquire_1.f03: Add write statement.
         * gfortran.dg/f2003_io_1.f03: Add wait statement.

2018-01-02  Nicolas Koenig  <koenigni@gcc.gnu.org>
         Thomas Koenig <tkoenig@gcc.gnu.org>

         PR fortran/25829
         * Makefile.am: Add async.c to gfor_io_src.
         Add async.h to gfor_io_headers.
         * Makefile.in: Regenerated.
         * gfortran.map: Add _gfortran_st_wait_async.
         * io/async.c: New file.
         * io/async.h: New file.
         * io/close.c: Include async.h.
         (st_close): Call async_wait for an asynchronous unit.
         * io/file_pos.c (st_backspace): Likewise.
         (st_endfile): Likewise.
         (st_rewind): Likewise.
         (st_flush): Likewise.
         * io/inquire.c: Add handling for asynchronous PENDING
         and ID arguments.
         * io/io.h (st_parameter_dt): Add async bit.
         (st_parameter_wait): Correct.
         (gfc_unit): Add au pointer.
         (st_wait_async): Add prototype.
         (transfer_array_inner): Likewise.
         (st_write_done_worker): Likewise.
         * io/open.c: Include async.h.
         (new_unit): Initialize asynchronous unit.
         * io/transfer.c (async_opt): New struct.
         (wrap_scalar_transfer): New function.
         (transfer_integer): Call wrap_scalar_transfer to do the work.
         (transfer_real): Likewise.
         (transfer_real_write): Likewise.
         (transfer_character): Likewise.
         (transfer_character_wide): Likewise.
         (transfer_complex): Likewise.
         (transfer_array_inner): New function.
         (transfer_array): Call transfer_array_inner.
         (transfer_derived): Call wrap_scalar_transfer.
         (data_transfer_init): Check for asynchronous I/O.
         Perform a wait operation on any pending asynchronous I/O
         if the data transfer is synchronous. Copy PDT and enqueue
         thread for data transfer.
         (st_read_done_worker): New function.
         (st_read_done): Enqueue transfer or call st_read_done_worker.
         (st_write_done_worker): New function.
         (st_write_done): Enqueue transfer or call st_read_done_worker.
         (st_wait): Document as no-op for compatibility reasons.
         (st_wait_async): New function.
         * io/unit.c (insert_unit): Use macros LOCK, UNLOCK and TRYLOCK;
         add NOTE where necessary.
         (get_gfc_unit): Likewise.
         (init_units): Likewise.
         (close_unit_1): Likewise. Call async_close if asynchronous.
         (close_unit): Use macros LOCK and UNLOCK.
         (finish_last_advance_record): Likewise.
         (newunit_alloc): Likewise.
         * io/unix.c (find_file): Likewise.
         (flush_all_units_1): Likewise.
         (flush_all_units): Likewise.
         * libgfortran.h (generate_error_common): Add prototype.
         * runtime/error.c: Include io.h and async.h.
         (generate_error_common): New function.

2018-07-02  Nicolas Koenig  <koenigni@gcc.gnu.org>
         Thomas Koenig <tkoenig@gcc.gnu.org>

         PR fortran/25829
         * testsuite/libgfomp.fortran/async_io_1.f90: New test.
         * testsuite/libgfomp.fortran/async_io_2.f90: New test.
         * testsuite/libgfomp.fortran/async_io_3.f90: New test.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: p13g.diff
Type: text/x-patch
Size: 69061 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20180702/cc8a51ba/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: async_io_1.f90
Type: text/x-fortran
Size: 1331 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20180702/cc8a51ba/attachment-0001.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: async_io_2.f90
Type: text/x-fortran
Size: 371 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20180702/cc8a51ba/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: async_io_3.f90
Type: text/x-fortran
Size: 360 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20180702/cc8a51ba/attachment-0003.bin>


More information about the Fortran mailing list