= allocb, iallocb, freeb, freeblist, BLEN, blocklen, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb: data block management Block* allocb(int size) Block* iallocb(int size) void freeb(Block *b) void freeblist(Block *b) long BLEN(Block *b) int blocklen(Block *b) Block* concatblock(Block *b) Block* copyblock(Block *b, int n) Block* trimblock(Block *b, int offset, int n) Block* packblock(Block *b) Block* padblock(Block *b, int n) int pullblock(Block **bph, int n) Block* pullupblock(Block *b, int n) Block* adjustblock(Block *b, int n) void checkb(Block *b, char *msg) A Block provides a receptacle for data: typedef struct Block { Block* next; Block* list; uchar* rp; /* first unconsumed byte */ uchar* wp; /* first empty byte */ uchar* lim; /* 1 past the end of the buffer */ uchar* base; /* start of the buffer */ void (*free)(Block*); ulong flag; } Block; Each Block has an associated buffer, located at base, andaccessed via wp when filling the buffer, or rp when fetchingdata from it. Each pointer should be incremented to reflectthe amount of data written or read. A Block is empty when rpreaches wp. The pointer lim bounds the allocated space.Some operations described below accept lists of Blocks, whichare chained via their next pointers, with a null pointer end‐ing the list. Blocks are usually intended for a Queue (seeqio(10.2)), but can be used independently. A Block and its buffer are normally allocated by one call tomalloc(10.2) and aligned on an 8 byte (BY2V) boundary. Somedevices with particular allocation constraints (eg, requiringcertain addresses for DMA) might allocate their own Block andbuffer; free must then point to a function that can deallo‐cate the specially allocated Block. Many Block operations cannot be used in interrupt handlersbecause they either sleep(10.2) or raise an error(10.2). Ofoperations that allocate blocks, only iallocb is usable. Allocb allocates a Block of at least size bytes. The blockis initially empty: rp and wp point to the start of the data.If it cannot allocate memory, allocb raises an error(10.2);it cannot be used by an interrupt handler. Iallocb is similar to allocb but is intended for use byinterrupt handlers, and returns a null pointer if no memoryis available. It also limits its allocation to a quota allo‐cated at system initialisation to interrupt-time buffering. Freeb frees a single Block (and its buffer). Freeblist frees the whole list of blocks headed by b. BLEN returns the number of unread bytes in a single block b;it is implemented as a macro. Blocklen returns the number of bytes of unread data in thewhole list of blocks headed by b. Concatblock returns b if it is not a list, and otherwisereturns a single Block containing all the data in the list ofblocks b, which it frees. Copyblock by contrast returns a single Block containing acopy of the first n bytes of data in the block list b, pad‐ding with zeroes if the list contained less than n bytes.The list b is unchanged. Padblock can pad a single Block at either end, to reservespace for protocol headers or trailers. If n≥0, it inserts nbytes at the start of the block, setting the read pointer rpto point to the new space. If n<0, it adds n bytes at theend of the block, leaving the write pointer wp pointing atthe new space. In both cases, it allocates a new Block ifnecessary, freeing the old, and it always returns a pointerto the resulting Block. Trimblock trims the list b to contain no more than n bytesstarting at offset bytes into the data of the original list.It returns a new list, freeing unneeded parts of the old. Ifno data remains, it returns a null pointer. Packblock examines each Block in the list b, reallocating anyblock in the list that has four times more available spacethan actual data. It returns a pointer to the revised list. Pullblock discards up to n bytes from the start of the listheaded by *bph. Unneeded blocks are freed. Pullblock sets*bph to point to the new list head and returns the number ofbytes discarded (which might be less than n). It is used bytransport protocols to discard ack'd data at the head of aretransmission queue. Pullupblock rearranges the data in the list of blocks b toensure that there are at least n bytes of contiguous data inthe first block, and returns a pointer to the new list head.It frees any blocks that it empties. It returns a nullpointer if there is not enough data in the list. Adjustblock ensures that the block b has at least n bytes ofdata, reallocating or padding with zero if necessary. Itreturns a pointer to the new Block. (If n is negative, itfrees the block and returns a null pointer.) Checkb does some consistency checking of the state of b; apanic(10.2) results if things look grim. It is intended forinternal use by the queue I/O routines (see qio(10.2)) butcould be used elsewhere. The only functions that can be called at interrupt level areiallocb, freeb, freeblist, BLEN, blocklen, trimblock andpullupblock. The others allocate memory and can potentiallyblock. == diagnosticsMany functions directly or indirectly can raise anerror(10.2), and callers must therefore provide for propererror recovery as described therein to prevent memory leaksand other bugs. Except for iallocb, any functions that allo‐cate new blocks or lists are unsuitable for use by interrupthandlers. Iallocb returns a null pointer when it runs out ofmemory. == source/os/port/qio.c/emu/port/qio.c == see ALSOqio(10.2)
= allocb, iallocb, freeb, freeblist, BLEN, blocklen, concatblock, copyblock, trimblock, packblock, padblock, pullblock, pullupblock, adjustblock, checkb: data block management
Block* allocb(int size)
Block* iallocb(int size)
void freeb(Block *b)
void freeblist(Block *b)
long BLEN(Block *b)
int blocklen(Block *b)
Block* concatblock(Block *b)
Block* copyblock(Block *b, int n)
Block* trimblock(Block *b, int offset, int n)
Block* packblock(Block *b)
Block* padblock(Block *b, int n)
int pullblock(Block **bph, int n)
Block* pullupblock(Block *b, int n)
Block* adjustblock(Block *b, int n)
void checkb(Block *b, char *msg)
A Block provides a receptacle for data:
typedef
struct Block
{
Block* next;
Block* list;
uchar* rp; /* first unconsumed byte */
uchar* wp; /* first empty byte */
uchar* lim; /* 1 past the end of the buffer */
uchar* base; /* start of the buffer */
void (*free)(Block*);
ulong flag;
} Block;
Each Block has an associated buffer, located at base, and
accessed via wp when filling the buffer, or rp when fetching
data from it. Each pointer should be incremented to reflect
the amount of data written or read. A Block is empty when rp
reaches wp. The pointer lim bounds the allocated space.
Some operations described below accept lists of Blocks, which
are chained via their next pointers, with a null pointer end‐
ing the list. Blocks are usually intended for a Queue (see
qio(10.2)), but can be used independently.
A Block and its buffer are normally allocated by one call to
malloc(10.2) and aligned on an 8 byte (BY2V) boundary. Some
devices with particular allocation constraints (eg, requiring
certain addresses for DMA) might allocate their own Block and
buffer; free must then point to a function that can deallo‐
cate the specially allocated Block.
Many Block operations cannot be used in interrupt handlers
because they either sleep(10.2) or raise an error(10.2). Of
operations that allocate blocks, only iallocb is usable.
Allocb allocates a Block of at least size bytes. The block
is initially empty: rp and wp point to the start of the data.
If it cannot allocate memory, allocb raises an error(10.2);
it cannot be used by an interrupt handler.
Iallocb is similar to allocb but is intended for use by
interrupt handlers, and returns a null pointer if no memory
is available. It also limits its allocation to a quota allo‐
cated at system initialisation to interrupt-time buffering.
Freeb frees a single Block (and its buffer).
Freeblist frees the whole list of blocks headed by b.
BLEN returns the number of unread bytes in a single block b;
it is implemented as a macro.
Blocklen returns the number of bytes of unread data in the
whole list of blocks headed by b.
Concatblock returns b if it is not a list, and otherwise
returns a single Block containing all the data in the list of
blocks b, which it frees.
Copyblock by contrast returns a single Block containing a
copy of the first n bytes of data in the block list b, pad‐
ding with zeroes if the list contained less than n bytes.
The list b is unchanged.
Padblock can pad a single Block at either end, to reserve
space for protocol headers or trailers. If n≥0, it inserts n
bytes at the start of the block, setting the read pointer rp
to point to the new space. If n<0, it adds n bytes at the
end of the block, leaving the write pointer wp pointing at
the new space. In both cases, it allocates a new Block if
necessary, freeing the old, and it always returns a pointer
to the resulting Block.
Trimblock trims the list b to contain no more than n bytes
starting at offset bytes into the data of the original list.
It returns a new list, freeing unneeded parts of the old. If
no data remains, it returns a null pointer.
Packblock examines each Block in the list b, reallocating any
block in the list that has four times more available space
than actual data. It returns a pointer to the revised list.
Pullblock discards up to n bytes from the start of the list
headed by *bph. Unneeded blocks are freed. Pullblock sets
*bph to point to the new list head and returns the number of
bytes discarded (which might be less than n). It is used by
transport protocols to discard ack'd data at the head of a
retransmission queue.
Pullupblock rearranges the data in the list of blocks b to
ensure that there are at least n bytes of contiguous data in
the first block, and returns a pointer to the new list head.
It frees any blocks that it empties. It returns a null
pointer if there is not enough data in the list.
Adjustblock ensures that the block b has at least n bytes of
data, reallocating or padding with zero if necessary. It
returns a pointer to the new Block. (If n is negative, it
frees the block and returns a null pointer.)
Checkb does some consistency checking of the state of b; a
panic(10.2) results if things look grim. It is intended for
internal use by the queue I/O routines (see qio(10.2)) but
could be used elsewhere.
The only functions that can be called at interrupt level are
iallocb, freeb, freeblist, BLEN, blocklen, trimblock and
pullupblock. The others allocate memory and can potentially
block.
== diagnostics
Many functions directly or indirectly can raise an
error(10.2), and callers must therefore provide for proper
error recovery as described therein to prevent memory leaks
and other bugs. Except for iallocb, any functions that allo‐
cate new blocks or lists are unsuitable for use by interrupt
handlers. Iallocb returns a null pointer when it runs out of
memory.
== source
/os/port/qio.c
/emu/port/qio.c
== see ALSO
qio(10.2)