فهرست منبع

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.
Rich Felker 14 سال پیش
والد
کامیت
bd57e2b43a
2فایلهای تغییر یافته به همراه14 افزوده شده و 0 حذف شده
  1. 1 0
      src/stdio/stderr.c
  2. 13 0
      src/stdio/vfprintf.c

+ 1 - 0
src/stdio/stderr.c

@@ -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,

+ 13 - 0
src/stdio/vfprintf.c

@@ -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;