From 2a98b3363e43c324e4ab5be5d6260f2ff6fbf18d Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Nov 2013 14:18:44 +0000 Subject: [PATCH] * libc/stdio/fvwrite.c: Allow writing in larger chunks for fully buffered and unbuffered files, to improve write performance. --- newlib/ChangeLog | 5 +++++ newlib/libc/stdio/fvwrite.c | 33 +++++++++++++++------------------ 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/newlib/ChangeLog b/newlib/ChangeLog index 09527c92e..98789da5d 100644 --- a/newlib/ChangeLog +++ b/newlib/ChangeLog @@ -1,3 +1,8 @@ +2013-11-04 Terraneo Federico + + * libc/stdio/fvwrite.c: Allow writing in larger chunks for fully + buffered and unbuffered files, to improve write performance. + 2013-10-31 Terraneo Federico * libc/stdio/fvwrite.h: change type of uio_resid from int to size_t to diff --git a/newlib/libc/stdio/fvwrite.c b/newlib/libc/stdio/fvwrite.c index 36a467845..455666006 100644 --- a/newlib/libc/stdio/fvwrite.c +++ b/newlib/libc/stdio/fvwrite.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "local.h" #include "fvwrite.h" @@ -89,12 +90,14 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio), if (fp->_flags & __SNBF) { /* - * Unbuffered: write up to BUFSIZ bytes at a time. + * Unbuffered: Split buffer in the largest multiple of BUFSIZ < INT_MAX + * as some legacy code may expect int instead of size_t. */ do { GETIOV (;); - w = fp->_write (ptr, fp->_cookie, p, MIN (len, BUFSIZ)); + w = fp->_write (ptr, fp->_cookie, p, + MIN (len, INT_MAX - INT_MAX % BUFSIZ)); if (w <= 0) goto err; p += w; @@ -177,29 +180,23 @@ _DEFUN(__sfvwrite_r, (ptr, fp, uio), fp->_p += w; w = len; /* but pretend copied all */ } - else if (fp->_p > fp->_bf._base && len > w) + else if (fp->_p > fp->_bf._base || len < fp->_bf._size) { - /* fill and flush */ + /* pass through the buffer */ + w = MIN (len, w); COPY (w); - /* fp->_w -= w; *//* unneeded */ + fp->_w -= w; fp->_p += w; - if (_fflush_r (ptr, fp)) - goto err; - } - else if (len >= (w = fp->_bf._size)) - { - /* write directly */ - w = fp->_write (ptr, fp->_cookie, p, w); - if (w <= 0) + if (fp->_w == 0 && _fflush_r (ptr, fp)) goto err; } else { - /* fill and done */ - w = len; - COPY (w); - fp->_w -= w; - fp->_p += w; + /* write directly */ + w = ((int)MIN (len, INT_MAX)) / fp->_bf._size * fp->_bf._size; + w = fp->_write (ptr, fp->_cookie, p, w); + if (w <= 0) + goto err; } p += w; len -= w;