Pointers
IOBLOCK Anonymous Pipe data structure
A 'pipe' is a connection between (among) file handles (JFN's). Data written to the 'write end' of the pipe are made available for reading on the 'read end'. The $Pipe system call creates a pipe and returns two file handles, one for the read end and one for the write end. These handles are manipulated in the same way as normal file handles; they may be 'dup'ed and are inherited in the same way. Data are written into a pipe via a 'write' system call on the write end of the pipe. Likewise, data are read from the pipe via a 'read' call on the read end.
Data that are written to a pipe are captured in a circular buffer. The size of the buffer is specified when the pipe is created; if no size is specified, a default size is used.
The circular buffer is described by an 'ioblock'. The ioblock is the buffer's header; the circular buffer proper follows the ioblock in a heap memory object (mapped by a GDT selector) allocated when the pipe is created. The ioblock contains all of the per-pipe information, such as reader, writer, and reference counts, and also holds the pointers into the circular buffer proper.
The selector that points to the circular buffer is stored in the SFT, at sfi_hVPB.
When the in and out pointers are equal, the circular buffer is empty. When the in pointer trails the out pointer by 1, the buffer is full. Thus, a 512 byte buffer can hold only 511 bytes; one byte is lost so that full and empty conditions can be distinguished. So that the user can put 512 bytes in a pipe that they created with a size of 512, we allow for this byte lost when allocating the segment.
┌──────────────┬──────┬──────┬────┬────────────────────────────────────────┐│Field Name │Offset│Length│Type│Description │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_inprogcnt │+0 │1 │B │count of read/wrts in progress │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_refcnt │+1 │1 │B │count of references │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_rdrcnt │+2 │1 │B │count of readers │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_wtrcnt │+3 │1 │B │count of writers │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_selector │+4 │2 │W │buffer selector │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_first │+6 │2 │W │ptr to base of circular buffer │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_in │+8 │2 │W │ptr to next free byte │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_out │+a │2 │W │ptr to next byte of data │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_last │+c │2 │W │ptr to end+1 of buffer │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_rdlksem │+e │2 │W │read lock semaphore │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_wtlksem │+10 │2 │W │write lock semaphore │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_rdsem │+12 │2 │W │read sync semaphore │ ├──────────────┼──────┼──────┼────┼────────────────────────────────────────┤ │io_wtsem │+14 │2 │W │write sync semaphore │ └──────────────┴──────┴──────┴────┴────────────────────────────────────────┘