I/O Buffering
With I/O buffering, we perform input transfers (I/O CPU) in advance of requests being made, and output transfers (CPU I/O) some time after the request is made.
I/O buffering speeds up the flow of data between an I/O device and a process by prefetching the I/O.
Why is I/O buffering needed?
- Processes must wait for I/O to complete before proceeding
- Certain pages must remain in main memory during I/O
Risk of Deadlock:
- Process calls an I/O routine and blocks
- Process is swapped out
- Process waits for I/O completion, but I/O waits for the process to be swapped in to access the memory
2 kinds of I/O buffering:
- Block-Oriented
- Stream-Oriented
Block-oriented (Block-Oriented Device)
- Information is stored in fixed sized blocks
- Transfers are made a block at a time
- Used for disks and USB keys
Stream-oriented (Stream-Oriented Device)
- Transfer information as a stream of bytes
- Used for terminals, printers, communication ports, mouse and other pointing devices, and most other devices that are not secondary storage
The kernel (I/O routines) handle buffering.
Main difference:
The main difference is that there is no
fseek()
for stream-oriented buffering, no going backwards.
Double Buffer
- A process can transfer data to or from one buffer while the operating system empties or fills the other buffer
A double-buffer scheme should smooth out the flow of data between an I/O device and a process.
Circular Buffer
- More than two buffers are used
- Each individual buffer is one unit in a circular buffer
- This is simply the bounded-buffer Producer-Consumer Problem
- Good for bursty I/O
More
Operating system assigns a buffer in main memory for an I/O request.
In Block-oriented
- Input transfers are made to buffer
- When transfer is complete, block is moved to user space (as opposed to Kernel Mode)
- Another block is moved into the buffer
- User process can process one block of data while next block is read in
- This is called reading ahead, or anticipated input; it is done in the expectation that the block will eventually be needed
- Swapping can occur since input is taking place in system memory, not user memory
- OS keeps track of assignment of system buffers to user processes
In Stream-oriented
- Use a line at a time
- User input from a terminal is one line at a time with carriage return signalling the end of the line
- Output to the terminal is one line at a time
- Flush() call in C