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

     testb() 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

     testb() can be called from user or interrupt 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 Guide


NOTES

     The pri argument is provided  for  compatibility  only.  Its
     value is ignored.


Man(1) output converted with man2html