159 lines · 5.8 KB · Text
RawDownload
= 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)