SVR5 and SCO OpenServer 5
allocb(D3str)
allocb --
allocate a message block
Synopsis
#include <sys/types.h>
#include <sys/stream.h>
#include <sys/ddi.h>
mblk_t *allocb(int size, uint_t pri);
Description
allocb( )
tries to allocate a STREAMS message block.
Arguments
size-
The number of bytes in the message block.
pri-
Hint to the allocator indicating priority of the request.
Valid values are:
BPRI_LO-
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.
BPRI_MED-
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.
BPRI_HI-
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.
Usage
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.
Context
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
All
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 */
else
; /* pass up RBD.mp, replace RBD.mp with 'mp' */
On SCO OpenServer 5 system,
allocb( )
failures can also be viewed with the netstat -m command.
References
allocb_physreq(D3str),
bufcall(D3str),
esballoc(D3str),
esbbcall(D3str),
freeb(D3str),
msgb(D4str)
Example
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