mirror of
https://github.com/freebsd/freebsd-src.git
synced 2026-11-07 04:36:52 -10:00
stdio: *memstream: decouple the buffer size from the stream length
It's useful to be able to track both facts with a single variable, but it also makes it more difficult to change how the buffer size scales. As an example, Apple's implementation seems to scale the buffer size by 1.5x on growth, presumably in an attempt to reduce trips into realloc(). This might be questionable in the face of stdio buffering, but avoiding serious churn in the line- or un-buffered case is a net positive if doing so isn't incredibly invasive. Reviewed by: des, jhb, obiwac Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D57354
This commit is contained in:
1 parent
28327c58ee
commit
781defc7eb
2 files changed
+17
-8
No files matched your search
@@ -46,6 +46,7 @@
|
||||
struct memstream {
|
||||
char **bufp;
|
||||
size_t *sizep;
|
||||
size_t size;
|
||||
ssize_t len;
|
||||
fpos_t offset;
|
||||
};
|
||||
@@ -60,19 +61,22 @@ memstream_grow(struct memstream *ms, fpos_t newoff)
|
||||
newsize = SSIZE_MAX - 1;
|
||||
else
|
||||
newsize = newoff;
|
||||
if (newsize > ms->len) {
|
||||
if (newsize > ms->size) {
|
||||
buf = realloc(*ms->bufp, newsize + 1);
|
||||
if (buf == NULL)
|
||||
return (0);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "MS: %p growing from %zd to %zd\n",
|
||||
ms, ms->len, newsize);
|
||||
ms, ms->size, newsize);
|
||||
#endif
|
||||
memset(buf + ms->len + 1, 0, newsize - ms->len);
|
||||
memset(buf + ms->size + 1, 0, newsize - ms->size);
|
||||
*ms->bufp = buf;
|
||||
ms->len = newsize;
|
||||
ms->size = newsize;
|
||||
}
|
||||
|
||||
if (newsize > ms->len)
|
||||
ms->len = newsize;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -192,6 +196,7 @@ open_memstream(char **bufp, size_t *sizep)
|
||||
}
|
||||
ms->bufp = bufp;
|
||||
ms->sizep = sizep;
|
||||
ms->size = 0;
|
||||
ms->len = 0;
|
||||
ms->offset = 0;
|
||||
memstream_update(ms);
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
struct wmemstream {
|
||||
wchar_t **bufp;
|
||||
size_t *sizep;
|
||||
size_t size;
|
||||
ssize_t len;
|
||||
fpos_t offset;
|
||||
mbstate_t mbstate;
|
||||
@@ -61,18 +62,20 @@ wmemstream_grow(struct wmemstream *ms, fpos_t newoff)
|
||||
newsize = SSIZE_MAX / sizeof(wchar_t) - 1;
|
||||
else
|
||||
newsize = newoff;
|
||||
if (newsize > ms->len) {
|
||||
if (newsize > ms->size) {
|
||||
buf = reallocarray(*ms->bufp, newsize + 1, sizeof(wchar_t));
|
||||
if (buf == NULL)
|
||||
return (0);
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr, "WMS: %p growing from %zd to %zd\n",
|
||||
ms, ms->len, newsize);
|
||||
ms, ms->size, newsize);
|
||||
#endif
|
||||
wmemset(buf + ms->len + 1, 0, newsize - ms->len);
|
||||
wmemset(buf + ms->size + 1, 0, newsize - ms->size);
|
||||
*ms->bufp = buf;
|
||||
ms->len = newsize;
|
||||
ms->size = newsize;
|
||||
}
|
||||
if (newsize > ms->len)
|
||||
ms->len = newsize;
|
||||
return (1);
|
||||
}
|
||||
|
||||
@@ -252,6 +255,7 @@ open_wmemstream(wchar_t **bufp, size_t *sizep)
|
||||
}
|
||||
ms->bufp = bufp;
|
||||
ms->sizep = sizep;
|
||||
ms->size = 0;
|
||||
ms->len = 0;
|
||||
ms->offset = 0;
|
||||
memset(&ms->mbstate, 0, sizeof(mbstate_t));
|
||||
|
||||
Reference in new issue
Block a user