avoiding stdio
Chris Torek
chris at mimsy.umd.edu
Sun Jan 21 09:52:58 AEST 1990
In article <28888 at stealth.acf.nyu.edu> brnstnd at stealth.acf.nyu.edu writes:
>What Chris means is that in most cases, there is a definite disadvantage
>in speed in avoiding buffering. There's also a definite disadvantage in
>programmer time in rewriting all the standard libraries.
There is also the problem that `appropriate buffering' can change with
a new release of the system. For instance, the OS/2 file system is
much like the BSD FFS in some ways, and there an advantage to using
larger buffers (under older PC OSes, a `disk block' is smaller than
under OS/2).
>There is, however, a definite advantage in speed in using the facilities
>of the operating system without stdio to get in the way.
This can indeed happen, since stdio tends to do too much data copying:
e.g., the loop
while (fgets(s, n, rstream) != NULL)
(void) fputs(s, wstream);
works by reading from rstream to a buffer, copying the buffer into
s, copying s into a buffer for wstream, and then writing to wstream.
>By the way, Chris, will the new BSD stdio have a working putc(c,*f++)?
The ANSI standard says that putc(c, *f++) is a no-no. As a side
effect of being an inline function under gcc, however, it will happen
to work there. This putc() handles full, line, and no buffering, and
the macro is rather complicated. (__s stands for `stdio'; the __
version of putc exists so that it is easy to define a function version
in the library.)
[excerpt 1]
* The following always hold:
*
* if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR),
* _lbfsize is -_bufsize, else _lbfsize is 0
* if _flags&__SRD, _w is 0
* if _flags&__SWR, _r is 0
*
* This ensures that the getc and putc macros (or inline functions) never
* try to write or read from a file that is in `read' or `write' mode.
* (Moreover, they can, and do, automatically switch from read mode to
* write mode, and back, on "r+" and "w+" files.)
*
* _lbfsize is used only to make the inline line-buffered output stream
* code as compact as possible.
[excerpt 2]
#ifdef __GNUC__
static __inline int __sputc(int _c, FILE *_p) {
if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n'))
return (*_p->_p++ = _c);
else
return (__swbuf(_c, _p));
}
#else
/*
* This has been tuned to generate reasonable code on the vax using pcc
*/
#define __sputc(c, p) \
(--(p)->_w < 0 ? \
(p)->_w >= (p)->_lbfsize ? \
(*(p)->_p = (c)), *(p)->_p != '\n' ? \
(int)*(p)->_p++ : \
__swbuf('\n', p) : \
__swbuf((int)(c), p) : \
(*(p)->_p = (c), (int)*(p)->_p++))
#endif
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at cs.umd.edu Path: uunet!mimsy!chris
More information about the Comp.lang.c
mailing list