Part 1.1 of PR25561.
2008-05-15 Janne Blomqvist <jb@gcc.gnu.org> PR libfortran/25561 * io/io.h (struct fbuf): Change pointer to position offset. * io/fbuf.c (fbuf_init): Reduce default size of buffer, ptr=>pos changes. (fbuf_reset): ptr=>pos changes. (fbuf_alloc): If the request doesn't fit, don't waste memory by keeping flushed bytes. ptr=>pos changes. (fbuf_flush): ptr=>pos changes. (fbuf_seek): Don't seek past the left tab limit, don't update active byte count. * io/open.c (new_unit): If RECL has been specified, used that as initial buffer size. From-SVN: r135433
This commit is contained in:
parent
65686652e4
commit
8947fd62fa
@ -1,3 +1,18 @@
|
|||||||
|
2008-05-16 Janne Blomqvist <jb@gcc.gnu.org>
|
||||||
|
|
||||||
|
PR libfortran/25561
|
||||||
|
* io/io.h (struct fbuf): Change pointer to position offset.
|
||||||
|
* io/fbuf.c (fbuf_init): Reduce default size of buffer, ptr=>pos
|
||||||
|
changes.
|
||||||
|
(fbuf_reset): ptr=>pos changes.
|
||||||
|
(fbuf_alloc): If the request doesn't fit, don't waste memory by
|
||||||
|
keeping flushed bytes. ptr=>pos changes.
|
||||||
|
(fbuf_flush): ptr=>pos changes.
|
||||||
|
(fbuf_seek): Don't seek past the left tab limit, don't update active
|
||||||
|
byte count.
|
||||||
|
* io/open.c (new_unit): If RECL has been specified, used that as
|
||||||
|
initial buffer size.
|
||||||
|
|
||||||
2008-05-16 Janne Blomqvist <jb@gcc.gnu.org>
|
2008-05-16 Janne Blomqvist <jb@gcc.gnu.org>
|
||||||
|
|
||||||
PR libfortran/35632
|
PR libfortran/35632
|
||||||
|
@ -37,20 +37,19 @@ void
|
|||||||
fbuf_init (gfc_unit * u, size_t len)
|
fbuf_init (gfc_unit * u, size_t len)
|
||||||
{
|
{
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
len = 4096; /* Default size one page. */
|
len = 512; /* Default size. */
|
||||||
|
|
||||||
u->fbuf = get_mem (sizeof (fbuf));
|
u->fbuf = get_mem (sizeof (fbuf));
|
||||||
u->fbuf->buf = u->fbuf->ptr = get_mem (len);
|
u->fbuf->buf = get_mem (len);
|
||||||
u->fbuf->len = len;
|
u->fbuf->len = len;
|
||||||
u->fbuf->act = u->fbuf->flushed = 0;
|
u->fbuf->act = u->fbuf->flushed = u->fbuf->pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
fbuf_reset (gfc_unit * u)
|
fbuf_reset (gfc_unit * u)
|
||||||
{
|
{
|
||||||
u->fbuf->act = u->fbuf->flushed = 0;
|
u->fbuf->act = u->fbuf->flushed = u->fbuf->pos = 0;
|
||||||
u->fbuf->ptr = u->fbuf->buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -67,33 +66,65 @@ fbuf_destroy (gfc_unit * u)
|
|||||||
|
|
||||||
/* Return a pointer to the current position in the buffer, and increase
|
/* Return a pointer to the current position in the buffer, and increase
|
||||||
the pointer by len. Makes sure that the buffer is big enough,
|
the pointer by len. Makes sure that the buffer is big enough,
|
||||||
reallocating if necessary. */
|
reallocating if necessary. If the buffer is not big enough, there are
|
||||||
|
three cases to consider:
|
||||||
|
1. If we haven't flushed anything, realloc
|
||||||
|
2. If we have flushed enough that by discarding the flushed bytes
|
||||||
|
the request fits into the buffer, do that.
|
||||||
|
3. Else allocate a new buffer, memcpy unflushed active bytes from old
|
||||||
|
buffer. */
|
||||||
|
|
||||||
char *
|
char *
|
||||||
fbuf_alloc (gfc_unit * u, size_t len)
|
fbuf_alloc (gfc_unit * u, size_t len)
|
||||||
{
|
{
|
||||||
size_t newlen, ptrpos;
|
size_t newlen;
|
||||||
char *dest;
|
char *dest;
|
||||||
if (u->fbuf->ptr + len > u->fbuf->buf + u->fbuf->len)
|
if (u->fbuf->pos + len > u->fbuf->len)
|
||||||
|
{
|
||||||
|
if (u->fbuf->flushed == 0)
|
||||||
{
|
{
|
||||||
/* Round up to nearest multiple of the current buffer length. */
|
/* Round up to nearest multiple of the current buffer length. */
|
||||||
ptrpos = u->fbuf->ptr - u->fbuf->buf;
|
newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) * u->fbuf->len;
|
||||||
newlen = ((ptrpos + len) / u->fbuf->len + 1) * u->fbuf->len;
|
|
||||||
dest = realloc (u->fbuf->buf, newlen);
|
dest = realloc (u->fbuf->buf, newlen);
|
||||||
if (dest == NULL)
|
if (dest == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
u->fbuf->buf = dest;
|
u->fbuf->buf = dest;
|
||||||
u->fbuf->ptr = dest + ptrpos;
|
|
||||||
u->fbuf->len = newlen;
|
u->fbuf->len = newlen;
|
||||||
}
|
}
|
||||||
dest = u->fbuf->ptr;
|
else if (u->fbuf->act - u->fbuf->flushed + len < u->fbuf->len)
|
||||||
u->fbuf->ptr += len;
|
{
|
||||||
if ((size_t) (u->fbuf->ptr - u->fbuf->buf) > u->fbuf->act)
|
memmove (u->fbuf->buf, u->fbuf->buf + u->fbuf->flushed,
|
||||||
u->fbuf->act = u->fbuf->ptr - u->fbuf->buf;
|
u->fbuf->act - u->fbuf->flushed);
|
||||||
|
u->fbuf->act -= u->fbuf->flushed;
|
||||||
|
u->fbuf->pos -= u->fbuf->flushed;
|
||||||
|
u->fbuf->flushed = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Most general case, flushed != 0, request doesn't fit. */
|
||||||
|
newlen = ((u->fbuf->pos - u->fbuf->flushed + len)
|
||||||
|
/ u->fbuf->len + 1) * u->fbuf->len;
|
||||||
|
dest = get_mem (newlen);
|
||||||
|
memcpy (dest, u->fbuf->buf + u->fbuf->flushed,
|
||||||
|
u->fbuf->act - u->fbuf->flushed);
|
||||||
|
u->fbuf->act -= u->fbuf->flushed;
|
||||||
|
u->fbuf->pos -= u->fbuf->flushed;
|
||||||
|
u->fbuf->flushed = 0;
|
||||||
|
u->fbuf->buf = dest;
|
||||||
|
u->fbuf->len = newlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dest = u->fbuf->buf + u->fbuf->pos;
|
||||||
|
u->fbuf->pos += len;
|
||||||
|
if (u->fbuf->pos > u->fbuf->act)
|
||||||
|
u->fbuf->act = u->fbuf->pos;
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
fbuf_flush (gfc_unit * u, int record_done)
|
fbuf_flush (gfc_unit * u, int record_done)
|
||||||
{
|
{
|
||||||
@ -107,7 +138,7 @@ fbuf_flush (gfc_unit * u, int record_done)
|
|||||||
if (record_done)
|
if (record_done)
|
||||||
nbytes = u->fbuf->act - u->fbuf->flushed;
|
nbytes = u->fbuf->act - u->fbuf->flushed;
|
||||||
else
|
else
|
||||||
nbytes = u->fbuf->ptr - u->fbuf->buf - u->fbuf->flushed;
|
nbytes = u->fbuf->pos - u->fbuf->flushed;
|
||||||
status = swrite (u->s, u->fbuf->buf + u->fbuf->flushed, &nbytes);
|
status = swrite (u->s, u->fbuf->buf + u->fbuf->flushed, &nbytes);
|
||||||
u->fbuf->flushed += nbytes;
|
u->fbuf->flushed += nbytes;
|
||||||
}
|
}
|
||||||
@ -122,11 +153,12 @@ fbuf_flush (gfc_unit * u, int record_done)
|
|||||||
int
|
int
|
||||||
fbuf_seek (gfc_unit * u, gfc_offset off)
|
fbuf_seek (gfc_unit * u, gfc_offset off)
|
||||||
{
|
{
|
||||||
gfc_offset pos = u->fbuf->ptr - u->fbuf->buf + off;
|
gfc_offset pos = u->fbuf->pos + off;
|
||||||
if (pos < 0)
|
/* Moving to the left past the flushed marked would imply moving past
|
||||||
|
the left tab limit, which is never allowed. So return error if
|
||||||
|
that is attempted. */
|
||||||
|
if (pos < u->fbuf->flushed)
|
||||||
return -1;
|
return -1;
|
||||||
u->fbuf->ptr = u->fbuf->buf + pos;
|
u->fbuf->pos = pos;
|
||||||
if (pos > (gfc_offset) u->fbuf->act)
|
|
||||||
u->fbuf->act = pos;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -537,7 +537,7 @@ typedef struct fbuf
|
|||||||
size_t len; /* Length of buffer. */
|
size_t len; /* Length of buffer. */
|
||||||
size_t act; /* Active bytes in buffer. */
|
size_t act; /* Active bytes in buffer. */
|
||||||
size_t flushed; /* Flushed bytes from beginning of buffer. */
|
size_t flushed; /* Flushed bytes from beginning of buffer. */
|
||||||
char *ptr; /* Current position in buffer. */
|
size_t pos; /* Current position in buffer. */
|
||||||
}
|
}
|
||||||
fbuf;
|
fbuf;
|
||||||
|
|
||||||
|
@ -628,11 +628,17 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags)
|
|||||||
free_mem (opp->file);
|
free_mem (opp->file);
|
||||||
|
|
||||||
if (flags->form == FORM_FORMATTED && (flags->action != ACTION_READ))
|
if (flags->form == FORM_FORMATTED && (flags->action != ACTION_READ))
|
||||||
|
{
|
||||||
|
if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN))
|
||||||
|
fbuf_init (u, u->recl);
|
||||||
|
else
|
||||||
fbuf_init (u, 0);
|
fbuf_init (u, 0);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
u->fbuf = NULL;
|
u->fbuf = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return u;
|
return u;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
Loading…
Reference in New Issue
Block a user