These are macros that call _insque and _remque. The VAX conveniently provided single instructions for these (apparently). On the m68k and sparc these were coded in assembly. On the i386 they were simply coded in straightforward C. I made some changes to it and produced the following:
The macros themselves are in sys/systm.h
struct llist { struct llist *f_link; struct llist *r_link; }; void _insque ( struct llist *element, struct llist *head) { element->f_link = head->f_link; head->f_link = element; element->r_link = head; (element->f_link)->r_link = element; } void _remque ( struct llist *element) { (element->f_link)->r_link = element->r_link; (element->r_link)->f_link = element->f_link; // element->r_link = (struct llist *)0; }A peek at NetBSD-1.3 shows that they introduced macros with names like LIST_REMOVE, LIST_INSERT_HEAD, LIST_INSERT_AFTER.
The following line initializes the queue:
tcb.inp_next = tcb.inp_prev = &tcb;This list is used in a variety of places, in particular tcp_input calls in_pcblookup() to scan the list for a matching entry. It begins with head and keeps going until it goes full circle to the head. A doubly linked list allows entries to be removed.
For code like that shown above to work, the inpcb structure must have the first two elements be links as follows:
struct inpcb { struct inpcb *inp_next,*inp_prev;
caddr_t ih_next, ih_prev;
The function "insque" is called from one place in tcp_input.c. The call is in tcp_reass() and is putting a segment on the reassembly queue.
The function "remque" is called from three places. Two are in tcp_input.c and one is in tcp_subr.c (in tcp_close()). The calls in tcp_input.c are both in tcp_reass() and deal with the reassembly queue. The call in tcp_close() cleans up the reassembly queue, removing and freeing any mbufs on it.
Kyu / [email protected]