QUEUE(9S) Data Structures for Drivers QUEUE(9S)
NAME
queue - STREAMS queue structure
SYNOPSIS
#include <sys/stream.h>
INTERFACE LEVEL
Architecture independent level 1 (DDI/DKI)
DESCRIPTION
A
STREAMS driver or module consists of two
queue structures:
read for
upstream processing and
write for downstream processing. The queue
structure is the major building block of a stream.
queue Structure Members
The
queue structure is defined as type
queue_t. The structure can be
accessed at any time from inside a
STREAMS entry point associated
with that queue.
struct qinit *q_qinfo; /* queue processing procedure */
struct msgb *q_first; /* first message in queue */
struct msgb *q_last; /* last message in queue */
struct queue *q_next; /* next queue in stream */
void *q_ptr; /* module-specific data */
size_t q_count; /* number of bytes on queue */
uint_t q_flag; /* queue state */
ssize_t q_minpsz; /* smallest packet OK on queue */
ssize_t q_maxpsz; /* largest packet OK on queue */
size_t q_hiwat; /* queue high water mark */
size_t q_lowat; /* queue low water mark */
Contstraints and restrictions on the use of
q_flag and
queue_t fields
and the
q_next values are detailed in the following sections.
q_flag Field
The
q_flag field must be used only to check the following flag
values.
QFULL Queue is full.
QREADR Queue is used for upstream (read-side) processing.
QUSE Queue has been allocated.
QENAB Queue has been enabled for service by
qenable(9F).
QNOENB Queue will not be scheduled for service by
putq(9F).
QWANTR Upstream processing element wants to read from queue.
QWANTW Downstream processing element wants to write to queue.
queue_t Fields
Aside from
q_ptr and
q_qinfo, a module or driver must never assume
that a
queue_t field value will remain unchanged across calls to
STREAMS entry points. In addition, many fields can change values
inside a
STREAMS entry point, especially if the
STREAMS module or
driver has perimeters that allow parallelism. See
mt-streams(9F).
Fields that are not documented below are private to the
STREAMS framework and must not be accessed.
o The values of the
q_hiwat,
q_lowat,
q_minpsz, and
q_maxpsz fields can be changed at the discretion of the module or
driver. As such, the stability of their values depends on
the perimeter configuration associated with any routines
that modify them.
o The values of the
q_first,
q_last, and
q_count fields can
change whenever
putq(9F),
putbq(9F),
getq(9F),
insq(9F),
or
rmvq(9F) is used on the queue. As such, the stability
of their values depends on the perimeter configuration
associated with any routines that call those
STREAMS functions.
o The
q_flag field can change at any time.
o The
q_next field will not change while inside a given
STREAMS entry point. Additional restrictions on the use of
the
q_next value are described in the next section.
A
STREAMS module or driver can assign any value to
q_ptr. Typically
q_ptr is used to point to module-specific per-queue state, allocated
in
open(9E) and freed in
close(9E). The value or contents of
q_ptr is
never inspected by the
STREAMS framework.
The initial values for
q_minpsz,
q_maxpsz,
q_hiwat, and
q_lowat are
set using the
module_info(9S) structure when
mod_install(9F) is
called. A
STREAMS module or driver can subsequently change the values
of those fields as necessary. The remaining visible fields,
q_qinfo,
q_first,
q_last,
q_next,
q_count, and
q_flag, must never be modified
by a module or driver.
The illumos DDI requires that
STREAMS modules and drivers obey the
rules described on this page. Those that do not follow the rules can
cause data corruption or system instability, and might change in
behavior across updates or upgrades.
q_next Restrictions
There are additional restrictions associated with the use of the
q_next value. In particular, a
STREAMS module or driver:
o Must not access the data structure pointed to by
q_next.
o Must not rely on the value of
q_next before calling
qprocson(9F) or after calling
qprocsoff(9F).
o Must not pass the value into any
STREAMS framework
function other than
put(9F),
canput(9F),
bcanput(9F),
putctl(9F),
putctl1(9F). However, in all cases the "next"
version of these functions, such as
putnext(9F), should be
preferred.
o Must not use the value to compare against queue pointers
from other streams. However, checking
q_next for NULL can
be used to distinguish a module from a driver in code
shared by both.
SEE ALSO
close(9E),
open(9E),
bcanput(9F),
canput(9F),
getq(9F),
insq(9F),
mod_install(9F),
put(9F),
putbq(9F),
putctl(9F),
putctl1(9F),
putnext(9F),
putq(9F),
qprocsoff(9F),
qprocson(9F),
rmvq(9F),
strqget(9F),
strqset(9F),
module_info(9S),
msgb(9S),
qinit(9S),
streamtab(9S) Writing Device Drivers STREAMS Programming Guide May 13, 2017 QUEUE(9S)