Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/lib/libc/stdio for unbuffered I/O arrange for the destinatio...



details:   https://anonhg.NetBSD.org/src/rev/d248a60b1752
branches:  trunk
changeset: 950806:d248a60b1752
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Sun Jan 31 16:18:22 2021 +0000

description:
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

diffstat:

 lib/libc/stdio/fread.c |  37 +++++++++++++++++++++++++++++++------
 1 files changed, 31 insertions(+), 6 deletions(-)

diffs (68 lines):

diff -r 120c8868273a -r d248a60b1752 lib/libc/stdio/fread.c
--- a/lib/libc/stdio/fread.c    Sun Jan 31 16:00:05 2021 +0000
+++ b/lib/libc/stdio/fread.c    Sun Jan 31 16:18:22 2021 +0000
@@ -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 @@
        _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 @@
                /* fp->_r = 0 ... done in __srefill */
                p += r;
                resid -= r;
-refill:
                if (__srefill(fp)) {
                        /* no more input: return partial result */
                        FUNLOCKFILE(fp);



Home | Main Index | Thread Index | Old Index