re PR libfortran/88411 (Random crashes for ASYNCHRONOUS writes (bad locking?))
authorThomas Koenig <tkoenig@gcc.gnu.org>
Sun, 9 Dec 2018 18:54:47 +0000 (18:54 +0000)
committerThomas Koenig <tkoenig@gcc.gnu.org>
Sun, 9 Dec 2018 18:54:47 +0000 (18:54 +0000)
2018-12-09  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/88411
* io/transfer.c (dta_transfer_init): Do not treat as an
asynchronous statement unless the statement has
ASYNCHRONOUS="YES".
(st_write_done): Likewise.
(st_read_done): Do not perform async_wait for synchronous I/O
on an async unit.
(st_read_done): Likewise.

2018-12-09  Thomas Koenig  <tkoenig@gcc.gnu.org>

PR fortran/88411
* testsuite/libgomp.fortran/async_io_8.f90: New test.

From-SVN: r266929

libgfortran/ChangeLog
libgfortran/io/transfer.c
libgomp/ChangeLog
libgomp/testsuite/libgomp.fortran/async_io_8.f90 [new file with mode: 0644]

index 42dbc8034430067ee4f63bd8719924845cbf7978..7e56fead3a5cb47d555b024dd73be67b821255b6 100644 (file)
@@ -1,3 +1,14 @@
+2018-12-09  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/88411
+       * io/transfer.c (dta_transfer_init): Do not treat as an
+       asynchronous statement unless the statement has
+       ASYNCHRONOUS="YES".
+       (st_write_done): Likewise.
+       (st_read_done): Do not perform async_wait for synchronous I/O
+       on an async unit.
+       (st_read_done): Likewise.
+
 2018-12-02  Janne Blomqvist  <jb@gcc.gnu.org>
 
        PR libfortran/88137
index 4013b3be60ab01c595f217e8130e31f3878f1e80..6fcec8a479e46a5e4d79687640c83690a0d9800a 100644 (file)
@@ -3189,7 +3189,7 @@ data_transfer_init (st_parameter_dt *dtp, int read_flag)
        }
     }
 
-  if (au)
+  if (au && dtp->u.p.async)
     {
       NOTE ("enqueue_data_transfer");
       enqueue_data_transfer_init (au, dtp, read_flag);
@@ -4313,11 +4313,8 @@ st_read_done (st_parameter_dt *dtp)
            *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au, AIO_READ_DONE);  
          else
            {
-             enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
-             /* An asynchronous unit without ASYNCHRONOUS="YES" - make this
-                synchronous by performing a wait operation.  */
-             if (!dtp->u.p.async)
-               async_wait (&dtp->common, dtp->u.p.current_unit->au);
+             if (dtp->u.p.async)
+               enqueue_done (dtp->u.p.current_unit->au, AIO_READ_DONE);
            }
        }
       else
@@ -4401,18 +4398,17 @@ st_write_done (st_parameter_dt *dtp)
 {
   if (dtp->u.p.current_unit)
     {
-      if (dtp->u.p.current_unit->au)
+      if (dtp->u.p.current_unit->au && dtp->u.p.async)
        {
          if (dtp->common.flags & IOPARM_DT_HAS_ID)
            *dtp->id = enqueue_done_id (dtp->u.p.current_unit->au,
                                        AIO_WRITE_DONE);
          else
            {
-             enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
-             /* An asynchronous unit without ASYNCHRONOUS="YES" - make this
-                synchronous by performing a wait operation.  */
-             if (!dtp->u.p.async)
-               async_wait (&dtp->common, dtp->u.p.current_unit->au);
+             /* We perform synchronous I/O on an asynchronous unit, so no need
+                to enqueue AIO_READ_DONE.  */
+             if (dtp->u.p.async)
+               enqueue_done (dtp->u.p.current_unit->au, AIO_WRITE_DONE);
            }
        }
       else
index 99417ef62cf0899f3f0ea19b9d52a24bbef893a0..13ec674809a4261e34a13ff6918f003139f54769 100644 (file)
@@ -1,3 +1,8 @@
+2018-12-09  Thomas Koenig  <tkoenig@gcc.gnu.org>
+
+       PR fortran/88411
+       * testsuite/libgomp.fortran/async_io_8.f90: New test.
+
 2018-12-09  Thomas Schwinge  <thomas@codesourcery.com>
            Jakub Jelinek  <jakub@redhat.com>
 
diff --git a/libgomp/testsuite/libgomp.fortran/async_io_8.f90 b/libgomp/testsuite/libgomp.fortran/async_io_8.f90
new file mode 100644 (file)
index 0000000..f5ae93d
--- /dev/null
@@ -0,0 +1,30 @@
+! { dg-do run }
+! PR libfortran/88411
+! This used to generate errors due to a mixup of
+! synchronous and asynchronous execution.
+! Test case by Harald Anlauf.
+program gfcbug153
+  implicit none
+  integer :: iu, irecl
+  real    :: a(100,20), b(1,3000)
+  iu = 10
+  a  = 0.
+  b  = 0.
+  inquire (iolength = irecl) a
+  open (iu, file="file1.dat", access='direct', &
+       asynchronous='yes', &
+       recl=irecl)
+  write(iu, rec=1) a(:,:)
+  write(iu, rec=2) a(:,:)
+  write(iu, rec=3) a(:,:)
+  close (iu,status="delete")
+
+  inquire (iolength = irecl) b
+  open (iu, file="file2.dat", access='direct', &
+       asynchronous='yes', &
+       recl=irecl)
+  write(iu, rec=1) b(:,:)
+  write(iu, rec=2) b(:,:)
+  write(iu, rec=3) b(:,:)
+  close (iu,status="delete")
+end program