Commit 8947fd62 by Janne Blomqvist

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
parent 65686652
2008-05-16 Janne Blomqvist <jb@gcc.gnu.org> 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>
PR libfortran/35632 PR libfortran/35632
* io/open.c (new_unit): Set stream position to correct value. * io/open.c (new_unit): Set stream position to correct value.
......
...@@ -37,20 +37,19 @@ void ...@@ -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) ...@@ -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)
{ {
/* Round up to nearest multiple of the current buffer length. */ if (u->fbuf->flushed == 0)
ptrpos = u->fbuf->ptr - u->fbuf->buf; {
newlen = ((ptrpos + len) / u->fbuf->len + 1) * u->fbuf->len; /* Round up to nearest multiple of the current buffer length. */
dest = realloc (u->fbuf->buf, newlen); newlen = ((u->fbuf->pos + len) / u->fbuf->len + 1) * u->fbuf->len;
if (dest == NULL) dest = realloc (u->fbuf->buf, newlen);
return NULL; if (dest == NULL)
u->fbuf->buf = dest; return NULL;
u->fbuf->ptr = dest + ptrpos; u->fbuf->buf = dest;
u->fbuf->len = newlen; u->fbuf->len = newlen;
}
else if (u->fbuf->act - u->fbuf->flushed + len < u->fbuf->len)
{
memmove (u->fbuf->buf, 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;
}
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->ptr;
u->fbuf->ptr += len; dest = u->fbuf->buf + u->fbuf->pos;
if ((size_t) (u->fbuf->ptr - u->fbuf->buf) > u->fbuf->act) u->fbuf->pos += len;
u->fbuf->act = u->fbuf->ptr - u->fbuf->buf; 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) ...@@ -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) ...@@ -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 ...@@ -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,9 +628,15 @@ new_unit (st_parameter_open *opp, gfc_unit *u, unit_flags * flags) ...@@ -628,9 +628,15 @@ 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))
fbuf_init (u, 0); {
if ((opp->common.flags & IOPARM_OPEN_HAS_RECL_IN))
fbuf_init (u, u->recl);
else
fbuf_init (u, 0);
}
else else
u->fbuf = NULL; u->fbuf = NULL;
return u; return u;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment