TESTB(9F)               Kernel Functions for Drivers               TESTB(9F)
NAME
       testb - check for an available buffer
SYNOPSIS
       #include <sys/stream.h>       
int testb(
size_t size, 
uint_t pri);
INTERFACE LEVEL
       Architecture independent level 1 (DDI/DKI).
PARAMETERS
       size               Size of the requested buffer.       
pri               Priority of the allocb request.
DESCRIPTION
       The 
testb() function checks to see if an 
allocb(9F) call is likely to
       succeed if a buffer of 
size bytes at priority 
pri is requested.  Even
       if 
testb() returns successfully, the call to 
allocb(9F) can fail. The       
pri argument is no longer used, but is retained for compatibility.
RETURN VALUES
       Returns 
1 if a buffer of the requested size is available, and 
0 if
       one is not.
CONTEXT
       The 
testb() function can be called user, interrupt, or kernel
       context.
EXAMPLES
       Example 1 testb() example
       In a service routine, if 
copymsg(9F) fails (line 6), the message is
       put back on the queue (line 7) and a routine, 
tryagain, is scheduled
       to be run in one tenth of a second. Then the service routine returns.
       When the 
timeout(9F) function runs, if there is no message on the
       front of the queue, it just returns. Otherwise, for each message
       block in the first message, check to see if an allocation would
       succeed.  If the number of message blocks equals the number we can
       allocate, then enable the service procedure.  Otherwise, reschedule       
tryagain to run again in another tenth of a second.  Note that       
tryagain is merely an approximation. Its accounting may be faulty.
       Consider the case of a message comprised of two 1024-byte message
       blocks. If there is only one free 1024-byte message block and no free
       2048-byte message blocks, then 
testb() will still succeed twice. If
       no message blocks are freed of these sizes before the service
       procedure runs again, then the 
copymsg(9F) will still fail. The
       reason 
testb() is used here is because it is significantly faster
       than calling 
copymsg. We must minimize the amount of time spent in a       
timeout() routine.         
1  xxxsrv(q)          2      queue_t *q;          3  {          4   mblk_t *mp;          5   mblk_t *nmp;                 ...          6   if ((nmp = copymsg(mp)) == NULL) {          7        putbq(q, mp);          8        timeout(tryagain, (intptr_t)q, drv_usectohz(100000));          9        return;         10   }              ...         11  }         12         13  tryagain(q)         14      queue_t *q;         15  {         16   register int can_alloc = 0;         17   register int num_blks = 0;         18   register mblk_t *mp;         19         20   if (!q->q_first)         21        return;         22   for (mp = q->q_first; mp; mp = mp->b_cont) {         23        num_blks++;         24        can_alloc += testb((mp->b_datap->db_lim -         25            mp->b_datap->db_base), BPRI_MED);         26   }         27   if (num_blks == can_alloc)         28        qenable(q);         29   else         30        timeout(tryagain, (intptr_t)q, drv_usectohz(100000));         31  }SEE ALSO
       allocb(9F), 
bufcall(9F), 
copymsg(9F), 
timeout(9F)       Writing Device Drivers       STREAMS Programming GuideNOTES
       The 
pri argument is provided for compatibility only. Its value is
       ignored.
                              January 16, 2006                     TESTB(9F)