Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
branch: master
Fetching contributors…

Cannot retrieve contributors at this time

711 lines (498 sloc) 36.691 kb
QUEUE(3) OpenBSD Programmer's Manual QUEUE(3)
NNAAMMEE
SSLLIISSTT__EENNTTRRYY, SSLLIISSTT__HHEEAADD, SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR, SSLLIISSTT__FFIIRRSSTT, SSLLIISSTT__NNEEXXTT,
SSLLIISSTT__EENNDD, SSLLIISSTT__EEMMPPTTYY, SSLLIISSTT__FFOORREEAACCHH, SSLLIISSTT__IINNIITT, SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR,
SSLLIISSTT__IINNSSEERRTT__HHEEAADD, SSLLIISSTT__RREEMMOOVVEE__HHEEAADD, LLIISSTT__EENNTTRRYY, LLIISSTT__HHEEAADD,
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR, LLIISSTT__FFIIRRSSTT, LLIISSTT__NNEEXXTT, LLIISSTT__EENNDD, LLIISSTT__EEMMPPTTYY,
LLIISSTT__FFOORREEAACCHH, LLIISSTT__IINNIITT, LLIISSTT__IINNSSEERRTT__AAFFTTEERR, LLIISSTT__IINNSSEERRTT__BBEEFFOORREE,
LLIISSTT__IINNSSEERRTT__HHEEAADD, LLIISSTT__RREEMMOOVVEE, SSIIMMPPLLEEQQ__EENNTTRRYY, SSIIMMPPLLEEQQ__HHEEAADD,
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, SSIIMMPPLLEEQQ__FFIIRRSSTT, SSIIMMPPLLEEQQ__NNEEXXTT, SSIIMMPPLLEEQQ__EENNDD,
SSIIMMPPLLEEQQ__EEMMPPTTYY, SSIIMMPPLLEEQQ__FFOORREEAACCHH, SSIIMMPPLLEEQQ__IINNIITT, SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD,
SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL, SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR, SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD,
TTAAIILLQQ__EENNTTRRYY, TTAAIILLQQ__HHEEAADD, TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, TTAAIILLQQ__FFIIRRSSTT, TTAAIILLQQ__NNEEXXTT,
TTAAIILLQQ__EENNDD, TTAAIILLQQ__LLAASSTT, TTAAIILLQQ__PPRREEVV, TTAAIILLQQ__EEMMPPTTYY, TTAAIILLQQ__FFOORREEAACCHH,
TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE, TTAAIILLQQ__IINNIITT, TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR,
TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE, TTAAIILLQQ__IINNSSEERRTT__HHEEAADD, TTAAIILLQQ__IINNSSEERRTT__TTAAIILL, TTAAIILLQQ__RREEMMOOVVEE,
CCIIRRCCLLEEQQ__EENNTTRRYY, CCIIRRCCLLEEQQ__HHEEAADD, CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR, CCIIRRCCLLEEQQ__FFIIRRSSTT,
CCIIRRCCLLEEQQ__LLAASSTT, CCIIRRCCLLEEQQ__EENNDD, CCIIRRCCLLEEQQ__NNEEXXTT, CCIIRRCCLLEEQQ__PPRREEVV, CCIIRRCCLLEEQQ__EEMMPPTTYY,
CCIIRRCCLLEEQQ__FFOORREEAACCHH, CCIIRRCCLLEEQQ__IINNIITT, CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR,
CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE, CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD, CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL,
CCIIRRCCLLEEQQ__RREEMMOOVVEE - implementations of singly-linked lists, doubly-linked
lists, simple queues, tail queues, and circular queues
SSYYNNOOPPSSIISS
##iinncclluuddee <<ssyyss//qquueeuuee..hh>>
SSLLIISSTT__EENNTTRRYY(_T_Y_P_E);
SSLLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR(_S_L_I_S_T___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__FFIIRRSSTT(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
SSLLIISSTT__EENNDD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_b_o_o_l
SSLLIISSTT__EEMMPPTTYY(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
SSLLIISSTT__FFOORREEAACCHH(_V_A_R_N_A_M_E, _S_L_I_S_T___H_E_A_D _*_h_e_a_d, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__IINNIITT(_S_L_I_S_T___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__IINNSSEERRTT__HHEEAADD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSLLIISSTT__RREEMMOOVVEE__HHEEAADD(_S_L_I_S_T___H_E_A_D _*_h_e_a_d, _S_L_I_S_T___E_N_T_R_Y _N_A_M_E);
LLIISSTT__EENNTTRRYY(_T_Y_P_E);
LLIISSTT__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR(_L_I_S_T___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__FFIIRRSSTT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
LLIISSTT__EENNDD(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_b_o_o_l
LLIISSTT__EEMMPPTTYY(_L_I_S_T___H_E_A_D _*_h_e_a_d);
LLIISSTT__FFOORREEAACCHH(_V_A_R_N_A_M_E, _L_I_S_T___H_E_A_D _*_h_e_a_d, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNIITT(_L_I_S_T___H_E_A_D _*_h_e_a_d);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__BBEEFFOORREE(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__IINNSSEERRTT__HHEEAADD(_L_I_S_T___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
LLIISSTT__RREEMMOOVVEE(_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _L_I_S_T___E_N_T_R_Y _N_A_M_E);
SSIIMMPPLLEEQQ__EENNTTRRYY(_T_Y_P_E);
SSIIMMPPLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_S_I_M_P_L_E_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__FFIIRRSSTT(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
SSIIMMPPLLEEQQ__EENNDD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNIITT(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD(_S_I_M_P_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_S_I_M_P_L_E_Q___E_N_T_R_Y _N_A_M_E);
TTAAIILLQQ__EENNTTRRYY(_T_Y_P_E);
TTAAIILLQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_T_A_I_L_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__FFIIRRSSTT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__EENNDD(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
TTAAIILLQQ__LLAASSTT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _H_E_A_D_N_A_M_E _N_A_M_E);
TTAAIILLQQ__PPRREEVV(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _H_E_A_D_N_A_M_E _N_A_M_E, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_b_o_o_l
TTAAIILLQQ__EEMMPPTTYY(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
TTAAIILLQQ__FFOORREEAACCHH(_V_A_R_N_A_M_E, _T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE(_V_A_R_N_A_M_E, _T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNIITT(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__HHEEAADD(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__IINNSSEERRTT__TTAAIILL(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
TTAAIILLQQ__RREEMMOOVVEE(_T_A_I_L_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _T_A_I_L_Q___E_N_T_R_Y _N_A_M_E);
CCIIRRCCLLEEQQ__EENNTTRRYY(_T_Y_P_E);
CCIIRRCCLLEEQQ__HHEEAADD(_H_E_A_D_N_A_M_E, _T_Y_P_E);
CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR(_C_I_R_C_L_E_Q___H_E_A_D _h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__FFIIRRSSTT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__LLAASSTT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__EENNDD(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__NNEEXXTT(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_s_t_r_u_c_t _T_Y_P_E _*
CCIIRRCCLLEEQQ__PPRREEVV(_s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_b_o_o_l
CCIIRRCCLLEEQQ__EEMMPPTTYY(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
CCIIRRCCLLEEQQ__FFOORREEAACCHH(_V_A_R_N_A_M_E, _C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
CCIIRRCCLLEEQQ__FFOORREEAACCHH__RREEVVEERRSSEE(_V_A_R_N_A_M_E, _C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNIITT(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_l_i_s_t_e_l_m,
_s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m,
_C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
_v_o_i_d
CCIIRRCCLLEEQQ__RREEMMOOVVEE(_C_I_R_C_L_E_Q___H_E_A_D _*_h_e_a_d, _s_t_r_u_c_t _T_Y_P_E _*_e_l_m, _C_I_R_C_L_E_Q___E_N_T_R_Y _N_A_M_E);
DDEESSCCRRIIPPTTIIOONN
These macros define and operate on five types of data structures: singly-
linked lists, simple queues, lists, tail queues, and circular queues.
All five structures support the following functionality:
1. Insertion of a new entry at the head of the list.
2. Insertion of a new entry after any element in the list.
3. Removal of an entry from the head of the list.
4. Forward traversal through the list.
Singly-linked lists are the simplest of the five data structures and sup-
port only the above functionality. Singly-linked lists are ideal for ap-
plications with large datasets and few or no removals, or for implement-
ing a LIFO queue.
Simple queues add the following functionality:
1. Entries can be added at the end of a list.
However:
1. All list insertions must specify the head of the list.
2. Each head entry requires two pointers rather than one.
3. Code size is about 15% greater and operations run about 20%
slower than singly-linked lists.
Simple queues are ideal for applications with large datasets and few or
no removals, or for implementing a FIFO queue.
All doubly linked types of data structures (lists, tail queues, and cir-
cle queues) additionally allow:
1. Insertion of a new entry before any element in the list.
2. Removal of any entry in the list.
However:
1. Each elements requires two pointers rather than one.
2. Code size and execution time of operations (except for re-
moval) is about twice that of the singly-linked data-struc-
tures.
Lists are the simplest of the doubly linked data structures and support
only the above functionality over singly-linked lists.
Tail queues add the following functionality:
1. Entries can be added at the end of a list.
2. They may be traversed backwards, at a cost.
However:
1. All list insertions and removals must specify the head of the
list.
2. Each head entry requires two pointers rather than one.
3. Code size is about 15% greater and operations run about 20%
slower than singly-linked lists.
Circular queues add the following functionality:
1. Entries can be added at the end of a list.
2. They may be traversed backwards, from tail to head.
However:
1. All list insertions and removals must specify the head of the
list.
2. Each head entry requires two pointers rather than one.
3. The termination condition for traversal is more complex.
4. Code size is about 40% greater and operations run about 45%
slower than lists.
In the macro definitions, _T_Y_P_E is the name tag of a user defined struc-
ture that must contain a field of type SLIST_ENTRY, LIST_ENTRY,
SIMPLEQ_ENTRY, TAILQ_ENTRY, or CIRCLEQ_ENTRY, named _N_A_M_E. The argument
_H_E_A_D_N_A_M_E is the name tag of a user defined structure that must be de-
clared using the macros SSLLIISSTT__HHEEAADD(), LLIISSTT__HHEEAADD(), SSIIMMPPLLEEQQ__HHEEAADD(),
TTAAIILLQQ__HHEEAADD(), or CCIIRRCCLLEEQQ__HHEEAADD(). See the examples below for further ex-
planation of how these macros are used.
SSIINNGGLLYY__LLIINNKKEEDD LLIISSTTSS
A singly-linked list is headed by a structure defined by the SSLLIISSTT__HHEEAADD()
macro. This structure contains a single pointer to the first element on
the list. The elements are singly linked for minimum space and pointer
manipulation overhead at the expense of O(n) removal for arbitrary ele-
ments. New elements can be added to the list after an existing element
or at the head of the list. A _S_L_I_S_T___H_E_A_D structure is declared as fol-
lows:
SLIST_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the list. A pointer
to the head of the list can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The _H_E_A_D_N_A_M_E facility is often not used, leading to the following bizarre
code:
SLIST_HEAD(, TYPE) head, *headp;
The SSLLIISSTT__EENNTTRRYY() macro declares a structure that connects the elements
in the list.
The SSLLIISSTT__IINNIITT() macro initializes the list referenced by _h_e_a_d.
The list can also be initialized statically by using the
SSLLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
SLIST_HEAD(HEADNAME, TYPE) head = SLIST_HEAD_INITIALIZER(head);
The SSLLIISSTT__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the list.
The SSLLIISSTT__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The SSLLIISSTT__RREEMMOOVVEE__HHEEAADD() macro removes the first element of the list
pointed by _h_e_a_d.
The SSLLIISSTT__FFIIRRSSTT(), and SSLLIISSTT__NNEEXXTT() macros can be used to traverse the
list:
for (np = SLIST_FIRST(&head); np != NULL; np = SLIST_NEXT(np, NAME))
Or, for simplicity, one can use the SSLLIISSTT__FFOORREEAACCHH() macro:
SLIST_FOREACH(np, head, NAME)
The SSLLIISSTT__EEMMPPTTYY() macro should be used to check whether a simple list is
empty.
LLIISSTTSS
A list is headed by a structure defined by the LLIISSTT__HHEEAADD() macro. This
structure contains a single pointer to the first element on the list.
The elements are doubly linked so that an arbitrary element can be re-
moved without traversing the list. New elements can be added to the list
after an existing element, before an existing element, or at the head of
the list. A _L_I_S_T___H_E_A_D structure is declared as follows:
LIST_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the list. A pointer
to the head of the list can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The _H_E_A_D_N_A_M_E facility is often not used, leading to the following bizarre
code:
LIST_HEAD(, TYPE) head, *headp;
The LLIISSTT__EENNTTRRYY() macro declares a structure that connects the elements in
the list.
The LLIISSTT__IINNIITT() macro initializes the list referenced by _h_e_a_d.
The list can also be initialized statically by using the
LLIISSTT__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
LIST_HEAD(HEADNAME, TYPE) head = LIST_HEAD_INITIALIZER(head);
The LLIISSTT__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the list.
The LLIISSTT__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The LLIISSTT__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the el-
ement _l_i_s_t_e_l_m.
The LLIISSTT__RREEMMOOVVEE() macro removes the element _e_l_m from the list.
The LLIISSTT__FFIIRRSSTT(), and LLIISSTT__NNEEXXTT() macros can be used to traverse the
list:
for (np = LIST_FIRST(&head); np != NULL; np = LIST_NEXT(np, NAME))
Or, for simplicity, one can use the LLIISSTT__FFOORREEAACCHH() macro:
LIST_FOREACH(np, head, NAME)
The LLIISSTT__EEMMPPTTYY() macro should be used to check whether a list is empty.
LLIISSTT EEXXAAMMPPLLEE
LIST_HEAD(listhead, entry) head;
struct listhead *headp; /* List head. */
struct entry {
...
LIST_ENTRY(entry) entries; /* List. */
...
} *n1, *n2, *np;
LIST_INIT(&head); /* Initialize the list. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
LIST_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
LIST_INSERT_AFTER(n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
LIST_INSERT_BEFORE(n1, n2, entries);
/* Forward traversal. */
for (np = head.lh_first; np != NULL; np = np->entries.le_next)
np-> ...
while (head.lh_first != NULL) /* Delete. */
LIST_REMOVE(head.lh_first, entries);
SSIIMMPPLLEE QQUUEEUUEESS
A simple queue is headed by a structure defined by the SSIIMMPPLLEEQQ__HHEEAADD()
macro. This structure contains a pair of pointers, one to the first ele-
ment in the simple queue and the other to the last element in the simple
queue. The elements are singly linked. New elements can be added to the
queue after an existing element, at the head of the queue or at the tail
of the queue. A _S_I_M_P_L_E_Q___H_E_A_D structure is declared as follows:
SIMPLEQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the queue. A pointer
to the head of the queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The SSIIMMPPLLEEQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the queue.
The SSIIMMPPLLEEQQ__IINNIITT() macro initializes the queue referenced by _h_e_a_d.
The queue can also be initialized statically by using the
SSIIMMPPLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro like this:
SIMPLEQ_HEAD(HEADNAME, TYPE) head = SIMPLEQ_HEAD_INITIALIZER(head);
The SSIIMMPPLLEEQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head
of the queue.
The SSIIMMPPLLEEQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the queue.
The SSIIMMPPLLEEQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the
element _l_i_s_t_e_l_m.
The SSIIMMPPLLEEQQ__RREEMMOOVVEE__HHEEAADD() macro removes the first element from the queue.
The SSIIMMPPLLEEQQ__FFIIRRSSTT(), and SSIIMMPPLLEEQQ__NNEEXXTT() macros can be used to traverse
the queue. The SSIIMMPPLLEEQQ__FFOORREEAACCHH() is used for queue traversal
SIMPLEQ_FOREACH(np, head, NAME)
The SSIIMMPPLLEEQQ__EEMMPPTTYY() macro should be used to check whether a list is emp-
ty.
SSIIMMPPLLEE QQUUEEUUEE EEXXAAMMPPLLEE
SIMPLEQ_HEAD(listhead, entry) head = SIMPLEQ_HEAD_INITIALIZER(head);
struct entry {
...
SIMPLEQ_ENTRY(entry) entries; /* List. */
...
} *n1, *n2, *np;
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
SIMPLEQ_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
SIMPLEQ_INSERT_AFTER(n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert at the tail. */
SIMPLEQ_INSERT_TAIL(&head, n1, entries);
/* Forward traversal. */
for (np = SIMPLEQ_FIRST(&head); np != NULL; np = SIMPLEQ_NEXT(np, entries))
np-> ...
/* Delete. */
while (SIMPLEQ_FIRST(&head) != NULL)
SIMPLEQ_REMOVE_HEAD(&head, n1, entries);
TTAAIILL QQUUEEUUEESS
A tail queue is headed by a structure defined by the TTAAIILLQQ__HHEEAADD() macro.
This structure contains a pair of pointers, one to the first element in
the tail queue and the other to the last element in the tail queue. The
elements are doubly linked so that an arbitrary element can be removed
without traversing the tail queue. New elements can be added to the
queue after an existing element, before an existing element, at the head
of the queue, or at the end the queue. A _T_A_I_L_Q___H_E_A_D structure is de-
clared as follows:
TAILQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the tail queue. A
pointer to the head of the tail queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The TTAAIILLQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the tail queue.
The TTAAIILLQQ__IINNIITT() macro initializes the tail queue referenced by _h_e_a_d.
The tail queue can also be initialized statically by using the
TTAAIILLQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro.
The TTAAIILLQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head of
the tail queue.
The TTAAIILLQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the tail queue.
The TTAAIILLQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the ele-
ment _l_i_s_t_e_l_m.
The TTAAIILLQQ__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the
element _l_i_s_t_e_l_m.
The TTAAIILLQQ__RREEMMOOVVEE() macro removes the element _e_l_m from the tail queue.
The TTAAIILL__FFIIRRSSTT(), TTAAIILLQQ__NNEEXXTT(), TTAAIILLQQ__LLAASSTT() and TTAAIILLQQ__PPRREEVV() macros can
be used to traverse a tail queue. The TTAAIILLQQ__FFOORREEAACCHH() is used for tail
queue traversal
TAILQ_FOREACH(np, head, NAME)
The TTAAIILLQQ__FFOORREEAACCHH__RREEVVEERRSSEE() acts like TTAAIILLQQ__FFOORREEAACCHH() but traverses the
tail queue in reverse.
The TTAAIILLQQ__EEMMPPTTYY() macro should be used to check whether a tail queue is
empty.
TTAAIILL QQUUEEUUEE EEXXAAMMPPLLEE
TAILQ_HEAD(tailhead, entry) head;
struct tailhead *headp; /* Tail queue head. */
struct entry {
...
TAILQ_ENTRY(entry) entries; /* Tail queue. */
...
} *n1, *n2, *np;
TAILQ_INIT(&head); /* Initialize the queue. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
TAILQ_INSERT_HEAD(&head, n1, entries);
n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
TAILQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
TAILQ_INSERT_AFTER(&head, n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
TAILQ_INSERT_BEFORE(n1, n2, entries);
/* Forward traversal. */
for (np = TAILQ_FIRST(&head); np; np = TAILQ_NEXT(&head, entries))
np-> ...
/* Delete. */
while (np = TAILQ_FIRST(&head))
TAILQ_REMOVE(&head, np, entries);
CCIIRRCCUULLAARR QQUUEEUUEESS
A circular queue is headed by a structure defined by the CCIIRRCCLLEEQQ__HHEEAADD()
macro. This structure contains a pair of pointers, one to the first ele-
ment in the circular queue and the other to the last element in the cir-
cular queue. The elements are doubly linked so that an arbitrary element
can be removed without traversing the queue. New elements can be added
to the queue after an existing element, before an existing element, at
the head of the queue, or at the end of the queue. A _C_I_R_C_L_E_Q___H_E_A_D struc-
ture is declared as follows:
CIRCLEQ_HEAD(HEADNAME, TYPE) head;
where _H_E_A_D_N_A_M_E is the name of the structure to be defined, and struct
_T_Y_P_E is the type of the elements to be linked into the circular queue. A
pointer to the head of the circular queue can later be declared as:
struct HEADNAME *headp;
(The names head and headp are user selectable.)
The CCIIRRCCLLEEQQ__EENNTTRRYY() macro declares a structure that connects the elements
in the circular queue.
The CCIIRRCCLLEEQQ__IINNIITT() macro initializes the circular queue referenced by
_h_e_a_d.
The circular queue can also be initialized statically by using the
CCIIRRCCLLEEQQ__HHEEAADD__IINNIITTIIAALLIIZZEERR() macro.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__HHEEAADD() macro inserts the new element _e_l_m at the head
of the circular queue.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__TTAAIILL() macro inserts the new element _e_l_m at the end of
the circular queue.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__AAFFTTEERR() macro inserts the new element _e_l_m after the
element _l_i_s_t_e_l_m.
The CCIIRRCCLLEEQQ__IINNSSEERRTT__BBEEFFOORREE() macro inserts the new element _e_l_m before the
element _l_i_s_t_e_l_m.
The CCIIRRCCLLEEQQ__RREEMMOOVVEE() macro removes the element _e_l_m from the circular
queue.
The CCIIRRCCLLEEQQ__FFIIRRSSTT(), CCIIRRCCLLEEQQ__LLAASSTT(), CCIIRRCCLLEEQQ__EENNDD(), CCIIRRCCLLEEQQ__NNEEXXTT() and
CCIIRRCCLLEEQQ__PPRREEVV() macros can be used to traverse a circular queue. The
CCIIRRCCLLEEQQ__FFOORREEAACCHH() is used for circular queue forward traversal
CIRCLEQ_FOREACH(np, head, NAME)
The CCIIRRCCLLEEQQ__FFOORREEAACCHH__RREEVVEERRSSEE() macro acts like CCIIRRCCLLEEQQ__FFOORREEAACCHH() but tra-
verses the circular queue backwards.
The CCIIRRCCLLEEQQ__EEMMPPTTYY() macro should be used to check whether a circular
queue is empty.
CCIIRRCCUULLAARR QQUUEEUUEE EEXXAAMMPPLLEE
CIRCLEQ_HEAD(circleq, entry) head;
struct circleq *headp; /* Circular queue head. */
struct entry {
...
CIRCLEQ_ENTRY entries; /* Circular queue. */
...
} *n1, *n2, *np;
CIRCLEQ_INIT(&head); /* Initialize the circular queue. */
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
CIRCLEQ_INSERT_HEAD(&head, n1, entries);
n1 = malloc(sizeof(struct entry)); /* Insert at the tail. */
CIRCLEQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);
n2 = malloc(sizeof(struct entry)); /* Insert before. */
CIRCLEQ_INSERT_BEFORE(&head, n1, n2, entries);
/* Forward traversal. */
for (np = CIRCLEQ_FIRST(&head); np != CIRCLEQ_END(&head);
np = CIRCLEQ_NEXT(np, entries))
np-> ...
/* Reverse traversal. */
for (np = CIRCLEQ_LAST(&head); np != CIRCLEQ_END(&head);
np = CIRCLEQ_PREV(np, entries))
np-> ...
/* Delete. */
while (CIRCLEQ_FIRST(&head) != CIRCLEQ_END(&head))
CIRCLEQ_REMOVE(&head, CIRCLEQ_FIRST(&head), entries);
NNOOTTEESS
The SSLLIISSTT__EENNDD(), LLIISSTT__EENNDD(), SSIIMMPPLLEEQQ__EENNDD() and TTAAIILLQQ__EENNDD() macros are
provided for symmetry with CCIIRRCCLLEEQQ__EENNDD(). They expand to NULL and don't
serve any useful purpose.
Trying to free a list in the following way is a common error:
LIST_FOREACH(var, head, entry)
free(var);
free(head);
Since _v_a_r is free'd, the FFOORREEAACCHH() macro refers to a pointer that may
have been reallocated already. Proper code needs a second variable.
for (var = LIST_FIRST(head); var != LIST_END(head); var = nxt) {
nxt = LIST_NEXT(var);
free(var);
}
LIST_INIT(head); /* to put the list back in order */
HHIISSTTOORRYY
The qquueeuuee functions first appeared in 4.4BSD.
OpenBSD 2.9 December 13, 1993 11
Jump to Line
Something went wrong with that request. Please try again.