SVR5 and SCO OpenServer 5


allocb -- allocate a message block


   #include <sys/types.h>
   #include <sys/stream.h>
   #include <sys/ddi.h>

mblk_t *allocb(int size, uint_t pri);


allocb( ) tries to allocate a STREAMS message block.


The number of bytes in the message block.

Hint to the allocator indicating priority of the request. Valid values are:

Used for normal data allocations. At this priority, allocb( ) may fail even though the requested buffer size is available. This priority is used the the Stream head write( ) routine to hold data associated with user calls.

Used for other non-critical allocations such as normal data and control block allocation. As with BPRI_LO, allocb( ) may fail at this priority even though a buffer of the requested size is available. However, BPRI_MED calls will fail less frequently than BPRI_LO calls.

Use for allocations that must succeed such as critical control message allocations, although success is not guaranteed.

Some implementations may choose to ignore this parameter.

Return values

If successful, allocb returns a pointer to the allocated message block of type M_DATA(D7str). If a block cannot be allocated, a NULL pointer is returned.


Buffer allocation fails for DDI drivers only when the system is out of memory. STREAMS does not guarantee successful buffer allocation; any set of resources can be exhausted under the right conditions. If no buffer is available, the bufcall(D3str) function can help a module recover from an allocation failure, but it does not guarantee that the resources will be available. Developers should be aware of this when developing modules.

If the message block cannot be allocated, the allocb( ) call fails. The driver should silently drop the message or data being processed and increment the mac_frame_nosr statistic. allocb( ) failures show up in the STREAMS statistics that can be viewed with the crash command.

DDI drivers should not assume that the memory allocated for the data buffer is usable for DMA operations, although all allocations are made below the 4GB boundary. Drivers should not assume that the memory has any specific physical properties such as starting address alignment, physical address range, or physical contiguity. Beginning with DDI version 6, memory with specific physical properties can be obtained through the allocb_physreq(D3str) function.


Base or Interrupt.

Synchronization constraints

Does not block.

Driver-defined basic locks, read/write locks, and sleep locks may be held across calls to this function.

Hardware applicability


Version applicability

ddi: 1, 2, 3, 4, 5, 5mp, 6, 6mp, 7, 7mp, 7.1, 7.1mp, 8, 8mp
oddi: 1, 2, 2mp, 3, 3mp, 4, 4mp, 5, 5mp, 6, 6mp

Differences between versions

In versions 1, 2, 3, 4, 5, and 5mp, the memory for the data buffer returned by allocb( ) is DMA-able; that is, it satisfies worst-case DMA-ability requirements on systems with restricted DMA and is physically contiguous; see the phys_dmasize member of the physreq(D4) structure. For other versions, there are no guarantees on the memory properties.

SCO OpenServer 5 ODDI compatibility

SCO OpenServer 5 ODDI drivers can use allocb( ) to allocate messages for DMA operations. The driver should allocate a replacement block with allocb( ) before attempting to pass the completed receive frame upstream. A DMA device usually uses some sort of receive buffer descriptor list, with each descriptor holding a pointer to a STREAMS block. At interrupt time, the driver disassociates the block from the descriptor and passes it upstream, then calls allocb( ) to allocate a replacement. If the allocb( ) call fails, the descriptor is left without a place for the adapter to place data. The descriptor is now orphaned and cannot be placed back in the RBD list. The driver must manage the orphan list and try to get a STREAMS block at some later time.

The following code fragment illustrates how to avoid this condition. If the allocb( ) call fails, this frame is dropped. STREAMS allocation failures usually result in a lost frame and it does not really matter which frame gets dropped.

   /* receive allocb logic for BusMaster DMA devices */
   if ((mp=allocb(size, pri) == NULL)
   	;	/* no STREAMS memory available, drop completed frame */
   	;	/* pass up, replace with 'mp' */

On SCO OpenServer 5 system, allocb( ) failures can also be viewed with the netstat -m command.


allocb_physreq(D3str), bufcall(D3str), esballoc(D3str), esbbcall(D3str), freeb(D3str), msgb(D4str)


Given a pointer to a queue (q) and an error number (err), the send_error routine sends an M_ERROR(D7str) type message to the stream head.

If a message cannot be allocated, 0 is returned, indicating an allocation failure (line 8). Otherwise, the message type is set to M_ERROR (line 9). Line 10 increments the write pointer (bp->b_wptr) by the size (one byte) of the data in the message.

A message must be sent up the read side of the stream to arrive at the stream head. To determine whether q points to a read queue or a write queue, the q->q_flag member is tested to see if QREADR is set (line 12). If it is not set, q points to a write queue, and on line 13 the RD(D3str) function is used to find the corresponding read queue. In line 14, the putnext(D3str) function is used to send the message upstream. Then send_error returns 1 indicating success.

    1  send_error(q, err)
    2	queue_t *q;
    3	uchar_t err;
    4  {
    5	mblk_t *bp;
    6	long fl=0;

7 if ((bp = allocb(1, BPRI_HI)) == NULL) 8 return(0); 9 bp->b_datap->db_type = M_ERROR; 10 *bp->b_wptr++ = err; 11 (void) strqget(q, QFLAG, 0, &fl); 12 if (fl & QREADR)) 13 q = RD(q); 14 putnext(q, bp); 15 return(1); 16 }

19 June 2005
© 2005 The SCO Group, Inc. All rights reserved.
OpenServer 6 and UnixWare (SVR5) HDK - June 2005