mirror of git://git.musl-libc.org/musl
use a local temp buffer for unbuffered streams in vfprintf
this change makes it so most calls to fprintf(stderr, ...) will result in a single writev syscall, as opposed to roughly 2*N syscalls (and possibly more) where N is the number of format specifiers. in principle we could use a much larger buffer, but it's best not to increase the stack requirements too much. most messages are under 80 chars.
This commit is contained in:
parent
5600088d38
commit
bd57e2b43a
|
@ -6,6 +6,7 @@ static FILE f = {
|
|||
.buf_size = 0,
|
||||
.fd = 2,
|
||||
.flags = F_PERM | F_NORD,
|
||||
.lbf = -1,
|
||||
.write = __stdio_write,
|
||||
.seek = __stdio_seek,
|
||||
.close = __stdio_close,
|
||||
|
|
|
@ -627,13 +627,26 @@ int vfprintf(FILE *f, const char *fmt, va_list ap)
|
|||
va_list ap2;
|
||||
int nl_type[NL_ARGMAX] = {0};
|
||||
union arg nl_arg[NL_ARGMAX];
|
||||
unsigned char internal_buf[80], *saved_buf = 0;
|
||||
int ret;
|
||||
|
||||
va_copy(ap2, ap);
|
||||
if (printf_core(0, fmt, &ap2, nl_arg, nl_type) < 0) return -1;
|
||||
|
||||
FLOCK(f);
|
||||
if (!f->buf_size) {
|
||||
saved_buf = f->buf;
|
||||
f->buf = internal_buf;
|
||||
f->buf_size = sizeof internal_buf;
|
||||
}
|
||||
ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
|
||||
if (saved_buf) {
|
||||
f->write(f, 0, 0);
|
||||
if (!f->wpos) ret = -1;
|
||||
f->buf = saved_buf;
|
||||
f->buf_size = 0;
|
||||
f->wpos = f->wbase = f->wend = 0;
|
||||
}
|
||||
FUNLOCK(f);
|
||||
va_end(ap2);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue