Reduce stack usage of _vfiprintf_r()
Freddie Chopin
freddie_chopin@op.pl
Wed Oct 10 17:06:00 GMT 2012
Hi!
I'm using newlib on ARM microcontrollers that have limited amount of RAM
("few" to "few tens" of kilobytes). Due to design of _vfiprintf_r() it's
almost unusable for such targets, as static function __sbprintf() is
inlined into it - sbprintf() has a 1kB buffer on stack. This buffer is
there for optimizing access to unbuffered streams, but my application
does not use them and 1kB is a tremendous waste of space... If I would
be using such buffer, there would be a waste of space too, as
__sbprintf() recursively calls _vfiprintf() which would have a buffered
"fake" file now, but still allocate 1kB on stack in case it's unbuffered...
I've changed that for myself to use dynamic allocation like this (that's
from version 1.19.0):
>
> /*
> * Helper function for `fprintf to unbuffered unix file': creates a
> * temporary buffer. We only work on write-only files; this avoids
> * worries about ungetc buffers and so forth.
> */
> static int
> _DEFUN(__sbprintf, (rptr, fp, fmt, ap),
> struct _reent *rptr _AND
> register FILE *fp _AND
> _CONST char *fmt _AND
> va_list ap)
> {
> int ret;
> FILE fake;
> unsigned char *buf;
>
> /* copy the important variables */
> fake._flags = fp->_flags & ~__SNBF;
> fake._flags2 = fp->_flags2;
> fake._file = fp->_file;
> fake._cookie = fp->_cookie;
> fake._write = fp->_write;
>
> buf = _malloc_r(rptr, BUFSIZ);
>
> if (buf == NULL)
> return EOF;
>
> /* set up the buffer */
> fake._bf._base = fake._p = buf;
> fake._bf._size = fake._w = BUFSIZ;
> fake._lbfsize = 0; /* not actually used, but Just In Case */
> #ifndef __SINGLE_THREAD__
> __lock_init_recursive (fake._lock);
> #endif
>
> /* do the work, then copy any error status */
> ret = _VFPRINTF_R (rptr, &fake, fmt, ap);
> if (ret >= 0 && _fflush_r (rptr, &fake))
> ret = EOF;
> if (fake._flags & __SERR)
> fp->_flags |= __SERR;
>
> _free_r(rptr, buf);
>
> #ifndef __SINGLE_THREAD__
> __lock_close_recursive (fake._lock);
> #endif
> return (ret);
> }
I can provide a patch against current trunk if you think this solution
is reasonable - I hope you do, because such a waste of stack on small
microcontrollers is unacceptable...
Regards,
Freddie Chopin
More information about the Newlib
mailing list