Page 1 of 1

Character device buffering

Posted: Wed Jan 28, 2009 9:57 am
by ruisleipa
I have got my device driver interface to a point where I can do reads and writes to block devices. But I have problems with coming up a good way of implementing buffering for character devices. I have tried to find information on the net, but without luck.

I think there must be some kind of buffer between the device and the processes reading it, so a process can read the device without taking away the data from other processes.

I have come up with this idea:
When a handle is opened for the character device, a new buffer is created for the handle.
When the device driver has new data to read it sends it to a buffer manager which writes the new data to all buffers.
When a read is issued on the handle the data is read from the buffer, instead of asking it directly from the device which is the case with block devices.

While simple, this approach has the problem of (possibly) keeping the same data in many places, thereby wasting memory.

I also have a concern about this scenario:

Imagine a process opening a handle for a device but not reading it. The data is buffered for the handle so the process could read it. The buffer would grow and grow, because the data can't be wiped out because the process has not read it. This would cause, maybe slowly but eventually, running out of memory.

Is the idea above worth implementing, or would you suggest a better way of doing the buffering?

Thanks for your interest.

Re: Character device buffering

Posted: Wed Jan 28, 2009 3:24 pm
by dosfan
so a process can read the device without taking away the data from other processes
I honestly can't think of a situation where I'd like multiple processes reading the same data from a character device.
When a read is issued on the handle the data is read from the buffer, instead of asking it directly from the device which is the case with block devices.
My kernel does this in some fashion with the keyboard for example. Although the driver handles it's own buffer in its own specific way.
When a handle is opened for the character device, a new buffer is created for the handle.
In my experience I've only ever needed a buffer per device. I consider that once data has been read out the character device... it's gone. I wouldn't expect to hold it for someone else to read it. If that makes sense.

A generic buffer implementation sounds good though.

Re: Character device buffering

Posted: Wed Jan 28, 2009 7:27 pm
by chezzestix
mikkop92 wrote: Imagine a process opening a handle for a device but not reading it. The data is buffered for the handle so the process could read it. The buffer would grow and grow, because the data can't be wiped out because the process has not read it. This would cause, maybe slowly but eventually, running out of memory.
Make it a static length buffer. If the program misses a beat it probably wasn't trying to read the buffer or if it was then its lagging behind and the user has too much running.

Re: Character device buffering

Posted: Sun Feb 01, 2009 12:30 am
by ruisleipa
Thank you for your replies.

Re: Character device buffering

Posted: Sun Feb 01, 2009 1:56 am
by Solar
The Standard C library knows three ways of buffering a stream: Unbuffered, Line Buffered, and Fully Buffered.

Which buffering type it should be, as well as the size of the buffer, can be set by the process using the setvbuf() function.

For me as a C library implementor, that means I rely on the kernel to handle instantaneous reads/writes, and come up with a buffering technique for myself. (As dosfan already said, it's hard to picture a scenario where more than one process access the same character device simultaneously.)

Bottom line, if I would write a kernel, I'd leave the buffering stuff to the C library...