Subject: Re: syntactic sugar for mbuf queue
To: Iain Hibbert <plunky@rya-online.net>
From: Jason Thorpe <thorpej@shagadelic.org>
List: tech-kern
Date: 02/03/2006 09:54:55
On Feb 3, 2006, at 8:31 AM, Iain Hibbert wrote:

> Hi,
>    While working on the Bluetooth protocol I didnt really want to use
> ifqueue which was embedded in the networking interface headers but  
> I still
> use mbufs and queues of mbufs..  so, I created a generic mbufq (see  
> below)
> which is basically a singly linked queue (SIMPLEQ) using the builtin
> m_nextpkt instead of field.sqe_next
>
>    I have this in netbt/btvar.h which is probably not the place for  
> it (I
> was thinking of splitting up btvar.h as its a bit of a catchall)
>
>    Should this (or something like) be in sys/queue.h? sys/mbuf.h?

mbuf.h

>
>    Is there a better way?

Eventually, mbufs should use queue.h macros... but until then, this  
looks fine.

>
> iain
>
> /*
>  * Simple mbuf chain queueing system, this is basically a SIMPLEQ
>  * adapted to mbuf use (ie using m_nextpkt instead of field.sqe_next).
>  */
> struct mbufq {
> 	struct mbuf *mq_first;
> 	struct mbuf **mq_last;
> };
>
> #define MBUFQ_INIT(q)		do {				\
> 	(q)->mq_first = NULL;					\
> 	(q)->mq_last = &(q)->mq_first;				\
> } while (/*CONSTCOND*/0)
>
> #define MBUFQ_ENQUEUE(q, m)	do {				\
> 	(m)->m_nextpkt = NULL;					\
> 	*(q)->mq_last = (m);					\
> 	(q)->mq_last = &(m)->m_nextpkt;				\
> } while (/*CONSTCOND*/0)
>
> #define MBUFQ_PREPEND(q, m)	do {				\
> 	if (((m)->m_nextpkt = (q)->mq_first) == NULL)		\
> 		(q)->mq_last = &(m)->m_nextpkt;			\
> 	(q)->mq_first = (m);					\
> } while (/*CONSTCOND*/0)
>
> #define MBUFQ_DEQUEUE(q, m)	do {				\
> 	if (((m) = (q)->mq_first) != NULL) { 			\
> 		if (((q)->mq_first = (m)->m_nextpkt) == NULL)	\
> 			(q)->mq_last = &(q)->mq_first;		\
> 		else						\
> 			(m)->m_nextpkt = NULL;			\
> 	}							\
> } while (/*CONSTCOND*/0)
>
> #define MBUFQ_DRAIN(q)		do {				\
> 	struct mbuf *__m0;					\
> 	while ((__m0 = (q)->mq_first) != NULL) {		\
> 		(q)->mq_first = __m0->m_nextpkt;		\
> 		m_freem(__m0);					\
> 	}							\
> 	(q)->mq_last = &(q)->mq_first;				\
> } while (/*CONSTCOND*/0)
>
> #define MBUFQ_FIRST(q)		((q)->mq_first)
> #define MBUFQ_NEXT(m)		((m)->m_nextpkt)

-- thorpej