Subject: syntactic sugar for mbuf queue
To: None <tech-kern@netbsd.org>
From: Iain Hibbert <plunky@rya-online.net>
List: tech-kern
Date: 02/03/2006 16:31:29
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?
Is there a better way?
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)