PR 48587 Newunit allocator
commit5ba96fdd1a43f0b66fac16cc0dae6ba71d379fc7
authorjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Oct 2016 13:14:15 +0000 (15 13:14 +0000)
committerjb <jb@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 15 Oct 2016 13:14:15 +0000 (15 13:14 +0000)
tree05afbe2773ef57d4fffd38d55a4f9a577ac6e90f
parentc58d34ea2083844f465ff3f3e595c9c896253feb
PR 48587 Newunit allocator

Currently GFortran newer reuses unit numbers allocated with NEWUNIT=,
instead having a simple counter that is decremented each time such a
unit is opened.  For a long running program which repeatedly opens
files with NEWUNIT= and closes them, the counter can wrap around and
cause an abort.  This patch replaces the counter with an allocator
that keeps track of which units numbers are allocated, and can reuse
them once they have been deallocated.  Since operating systems tend to
limit the number of simultaneous open files for a process to a
relatively modest number, a relatively simple approach with a linear
scan through an array suffices.  Though as a small optimization there
is a low water indicator keeping track of the index for which all unit
numbers below are already allocated.  This linear scan also ensures
that we always allocate the smallest available unit number.

2016-10-15  Janne Blomqvist  <jb@gcc.gnu.org>

        PR libfortran/48587
        * io/io.h (get_unique_unit_number): Remove prototype.
        (newunit_alloc): New prototype.
        * io/open.c (st_open): Call newunit_alloc.
        * io/unit.c (newunits,newunit_size,newunit_lwi): New static
        variables.
        (GFC_FIRST_NEWUNIT): Rename to NEWUNIT_START.
        (next_available_newunit): Remove variable.
        (get_unit): Call newunit_alloc, don't try to create negative
        external unit.
        (close_unit_1): Call newunit_free.
        (close_units): Free newunits array.
        (get_unique_number): Remove function.
        (newunit_alloc): New function.
        (newunit_free): New function.
        * io/transfer.c (data_transfer_init): Check for invalid unit
        number.

testsuite ChangeLog:

2016-10-15  Janne Blomqvist  <jb@gcc.gnu.org>

        PR libfortran/48587
        * gfortran.dg/negative_unit2.f90: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@241199 138bc75d-0d04-0410-961f-82ee72b054a4
gcc/testsuite/ChangeLog
libgfortran/ChangeLog
libgfortran/io/io.h
libgfortran/io/open.c
libgfortran/io/transfer.c
libgfortran/io/unit.c