Description
The Buffered Stream object provides a mechanism for transmitting a buffered, unidirectional stream of data. Reader(s) and writer(s) may operate on the stream concurrently, and neither will block unless the buffer underflows (reader) or overflows (writer).
A buffered stream object contains a buffer of bounded size, initially one page. The size of the buffer may be altered at run time.
To external appearances, the buffered stream object implements two keys: a writer key and a reader key. The writer key is used to append data to the buffered stream. The reader key is used to consume data from the buffered stream. The writer key also conveys the authority to adjust the size of the buffer.
Internally, the buffered stream object is implemented as a trio of cooperating processes, using a commonly-held address space as a ring buffer:

Unnecessary use of the semaphore object is avoided by having a shared page of state between reader and writer. Reader and writer then use the following algorithms to avoid use of the semaphore where possible. A circular buffer is used, ensuring that the algorithm described can be correctly executed given only an atomic word write operation.
| Writer | Reader |
|---|
Goal: Write N bytes into buffer DesiredWrite : = N W : = min(N, BufFree); Append W bytes to buffer. DesiredWrite := DesiredWrite - W IF (DesiredWrite > 0) CALL semaphore ELSE IF (DesiredRead > BufCount) FORK semaphore | Goal: Read N bytes from buffer DesiredRead : = N R : = min(N, BufCount); Remove R bytes from buffer. DesiredRead := DesiredRead - R IF (DesiredRead > 0) CALL semaphore ELSE IF (DesiredWrite< BufFree) FORK semaphore |
Operations
- Check Alleged Key Type (OC = KT)
Returns the alleged type of the key.
| Result | R1 | 0x010000: Key is a writer key to a buffered stream. Key is a writer key to a buffered stream. 0x010001: Key is a reader key to a buffered stream. |
- Non-Blocking Write (OC = 1)
- Blocking Write (OC = 2)
- Extended Non-Blocking Write (OC = 3)
- Extended Blocking Write (OC = 4)
Write some number of bytes to the stream. The number of bytes written is implicit in the sent string length. The stream will copy as many bytes as possible from the sent message, up to the limit imposed by the space available in the stream buffer. It returns the number of bytes copied as a data value. If the write is non-blocking, this may be less than the number of bytes that were transmitted.
The extended form of the write request differs from the base form in that the return is performed with a call invocation, leaving the original invoker with exclusive control over the write side of the data stream.
| Request | B* | Data to be written to the stream. |
| Reply | W | Number of bytes copied from the message into the byte stream. |
| RK3 | A resume key to the write side of the stream. This key is returned by the extended forms only. |
| Result | 0 | Write proceeded successfully. |
| KT+3 | Access violation. Key is a reader key. |
- Non-Blocking Read (OC = 16)
- Blocking Read (OC = 17)
- Extended Non-Blocking Read (OC = 18)
- Extended Blocking Read (OC = 19)
Read some number of bytes from the stream. The stream will copy as many bytes as requested from the buffer into a reply message, but not exceeding the limit specified by the requestor. The number of bytes returned is implicit in the returned string length. If the read is non-blocking, the number of bytes returned may be less than the number of bytes that were requested.
The extended form of the read request differs from the base form in that the return is performed with a call invocation, leaving the original invoker with exclusive control over the read side of the data stream.
| Request | W | Number of bytes to be read from the stream. |
| Reply | B* | Bytes copied from the byte stream into the reply message. |
| RK3 | A resume key to the read side of the stream. This key is returned by the extended forms only. |
| Result | 0 | Read proceeded successfully. |
| KT+3 | Access violation. Key is a writer key. |