Module Name: src Committed By: jdolecek Date: Sun Jan 31 16:18:22 UTC 2021
Modified Files: src/lib/libc/stdio: fread.c Log Message: for unbuffered I/O arrange for the destination buffer to be filled in one go, instead of triggering long series of 1 byte read(2)s; this speeds up fread() several order of magnitudes for this case, directly proportional to the size of the supplied buffer change adapted from OpenBSD rev. 1.19 fixes PR lib/55808 by Roland Illig To generate a diff of this commit: cvs rdiff -u -r1.23 -r1.24 src/lib/libc/stdio/fread.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/stdio/fread.c diff -u src/lib/libc/stdio/fread.c:1.23 src/lib/libc/stdio/fread.c:1.24 --- src/lib/libc/stdio/fread.c:1.23 Sat Feb 22 22:02:46 2020 +++ src/lib/libc/stdio/fread.c Sun Jan 31 16:18:22 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: fread.c,v 1.23 2020/02/22 22:02:46 kamil Exp $ */ +/* $NetBSD: fread.c,v 1.24 2021/01/31 16:18:22 jdolecek Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -37,7 +37,7 @@ #if 0 static char sccsid[] = "@(#)fread.c 8.2 (Berkeley) 12/11/93"; #else -__RCSID("$NetBSD: fread.c,v 1.23 2020/02/22 22:02:46 kamil Exp $"); +__RCSID("$NetBSD: fread.c,v 1.24 2021/01/31 16:18:22 jdolecek Exp $"); #endif #endif /* LIBC_SCCS and not lint */ @@ -68,12 +68,38 @@ fread(void *buf, size_t size, size_t cou _DIAGASSERT(buf != NULL); FLOCKFILE(fp); + if (fp->_r < 0) + fp->_r = 0; total = resid; p = buf; - if (fp->_r <= 0) { - /* Nothing to read on enter, refill the buffers. */ - goto refill; + /* + * If we're unbuffered we know that the buffer in fp is empty so + * we can read directly into buf. This is much faster than a + * series of one byte reads into fp->_nbuf. + */ + if ((fp->_flags & __SNBF) != 0) { + while (resid > 0) { + /* set up the buffer */ + fp->_bf._base = fp->_p = (unsigned char *)p; + fp->_bf._size = resid; + + if (__srefill(fp)) { + /* no more input: return partial result */ + count = (total - resid) / size; + break; + } + p += fp->_r; + resid -= fp->_r; + } + + /* restore the old buffer (see __smakebuf) */ + fp->_bf._base = fp->_p = fp->_nbuf; + fp->_bf._size = 1; + fp->_r = 0; + + FUNLOCKFILE(fp); + return (count); } while (resid > (size_t)(r = fp->_r)) { @@ -82,7 +108,6 @@ fread(void *buf, size_t size, size_t cou /* fp->_r = 0 ... done in __srefill */ p += r; resid -= r; -refill: if (__srefill(fp)) { /* no more input: return partial result */ FUNLOCKFILE(fp);