[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: pipes & ptys
> But if I open a pipe as a pseudo tty and use 1 Bytes reads/writes - which
> looks normal for shell i/o to me
hmm user processes doing 1 byte read()/write()s _is_ slow. :( system
calls are expensive... (and also the library adds its share too...)
A simple shell would just use cooked mode and read a line at a time, not
single-character, btw...
not sure how much can be done about 1-byte IO (i fear the library
and system call overhead are the biggest part already...) i think the
first thing to do would be change gnulib and all your other programs
that still do it to avoid 1-byte IO where possible. (might need a few
if (__mint) and Fcntls on ttys but the result should be worth it...)
and then improve tty.c&friends so that long read/writes can get _really_
efficient. currently the problem is they do a lot of device-level
1-char IO and shuffling bytes into 32-bit `chars' and back... i.e. when a
pty slave writes 1k that gets expanded into 4k, and when the master then
does a 1k read its collapsed again. and whats worse pipefs' read then
gets called a 1000 times! instead of once. that is what makes ptys
slow... (and serial ports too, but i said that before. :)
(Just a note to TeSche - the 1 byte I/Os are converted to 4 bytes to allow
pty's to pass scan code and shift status info, just like Bconin from console.)
now how fix this (i mean _really_ fix this. so that a 1k read ends up
as one 1k device read whenever possible, without additional moving data
around) and stay compatible with existing devices? here is an idea...
1. add 2 optional functions to DEVDRV struct, for now i call them bread
and bwrite. (NULL means they are not there) they work like device read
and write, only with bytes instead of longs. (btw there are 3 longs
reserved in DEVDRV now and i can think of atleast 2 more functions to
add later, readv and writev... so extend the struct somehow?)
2. if bwrite is there use it instead of write in tty_write (also in
bflush, midiws...), if the write is RAW just check for job control and
return (*f->dev->bwrite)(f, buf, nbytes);
and if bread is there do the same atleast for RAW reads in tty_read.
(this includes reading pty masters...)
3. add bread and bwrite functions to the pty device. the slaves output
pipe can then be changed to use bytes directly. (i think. the other
direction of course not...)
4. add support for CLOCAL, HUPCL, VMIN etc and make _real_ modem devices...
with bread/bwrite they finally could get decent thruput without 99% CPU load.
...and CTLECHO, I guess we want full termio(s) support, eh?
this is just an idea i got and i have no idea if and when i could do
all this... :) but what do you think?
I kind of like it. The main point being, we want a system call that actually
reads or writes more than 1 byte at a time for ttys. So doing an Fread of 1K
on /dev/modem1 does a single call, not 1000 Bconin's... I would like to see
these new read and write functions replace Bconin/Bconout, with Bcon* just
being a special-case (single-character) of them.
I would suggest that a better way to handle this would be to continue
supporting the 4 bytes per character, but have an additional flag bit which
indicates whether or not the caller is interested in the 3 extra bytes. If not,
just perform the data copy by incrementing the pointer by 4 instead of by 1...