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;                \

Reply via email to