I needed this in a program and searching the kernel I see that this is
also hacked in a few places (e.g. mpii(4)).
Here is a small regression test
-----------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
SIMPLEQ_HEAD(listhead, entry) head = SIMPLEQ_HEAD_INITIALIZER(head);
struct entry {
int i; /* data */
SIMPLEQ_ENTRY(entry) entries; /* Simple queue. */
} *n1, *n2, *n3, *np;
void
printq()
{
SIMPLEQ_FOREACH(np, &head, entries)
printf("%d", np->i);
printf("\n");
}
int main()
{
int i = 0;
n1 = malloc(sizeof(struct entry)); /* Insert at the head. */
n1->i = i++;
SIMPLEQ_INSERT_HEAD(&head, n1, entries);
n2 = malloc(sizeof(struct entry)); /* Insert after. */
n2->i = i++;
SIMPLEQ_INSERT_AFTER(&head, n1, n2, entries);
n3 = malloc(sizeof(struct entry)); /* Insert at the tail. */
n3->i = i++;
SIMPLEQ_INSERT_TAIL(&head, n3, entries);
printq();
SIMPLEQ_REMOVE(&head, n2, entry, entries);
printq();
while (!SIMPLEQ_EMPTY(&head)) {
n1 = SIMPLEQ_FIRST(&head);
SIMPLEQ_REMOVE(&head, n1, entry, entries);
free(n1);
printq();
}
return 0;
}
-----------------------------------------------------------------------
that outputs
-----------------------------------------------------------------------
$ ./test_sqrm
012
02
2
-----------------------------------------------------------------------
Thoughts? OK?
Index: queue.h
===================================================================
RCS file: /cvs/src/sys/sys/queue.h,v
retrieving revision 1.44
diff -u -p -u -p -r1.44 queue.h
--- queue.h 9 Sep 2016 20:31:46 -0000 1.44
+++ queue.h 9 Oct 2017 21:06:37 -0000
@@ -315,6 +315,18 @@ struct {
\
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
+#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
+ if ((head)->sqh_first == (elm)) \
+ SIMPLEQ_REMOVE_HEAD((head), field); \
+ else { \
+ struct type *curelm = (head)->sqh_first; \
+ \
+ while (curelm->field.sqe_next != (elm)) \
+ curelm = curelm->field.sqe_next; \
+ SIMPLEQ_REMOVE_AFTER((head), curelm, field); \
+ } \
+} while (0)
+
#define SIMPLEQ_CONCAT(head1, head2) do { \
if (!SIMPLEQ_EMPTY((head2))) { \
*(head1)->sqh_last = (head2)->sqh_first; \