Set tchain earliest/latest on any removal
[akaros.git] / kern / include / sys / queue.h
index 841032a..8524177 100644 (file)
@@ -30,8 +30,7 @@
  * $FreeBSD$
  */
 
-#ifndef ROS_KERN_SYS_QUEUE_H
-#define ROS_KERN_SYS_QUEUE_H
+#pragma once
 
 #include <ros/common.h>    /* for __offsetof */
 
  *
  */
 #ifdef QUEUE_MACRO_DEBUG
+/* ROS has TAILQ-sized elements in a vcore, exposed to userspace via the
+ * vcoremap.  If you have QM tracing turned on, you'll mess it up. */
+#error "Don't use sys/queue QUEUE_MACRO_DEBUG without dealing with the vcoremap"
 /* Store the last 2 places the queue element or head was altered */
 struct qm_trace {
        char * lastfile;
@@ -330,15 +332,15 @@ struct {                                                          \
 /*
  * List declarations.
  */
-#define        LIST_HEAD(name, type)                                           \
+#define        BSD_LIST_HEAD(name, type)                                               \
 struct name {                                                          \
        struct type *lh_first;  /* first element */                     \
 }
 
-#define        LIST_HEAD_INITIALIZER(head)                                     \
+#define        BSD_LIST_HEAD_INITIALIZER(head)                                 \
        { NULL }
 
-#define        LIST_ENTRY(type)                                                \
+#define        BSD_LIST_ENTRY(type)                                            \
 struct {                                                               \
        struct type *le_next;   /* next element */                      \
        struct type **le_prev;  /* address of previous next element */  \
@@ -350,15 +352,15 @@ struct {                                                          \
 
 #if (defined(_KERNEL) && defined(INVARIANTS))
 #define        QMD_LIST_CHECK_HEAD(head, field) do {                           \
-       if (LIST_FIRST((head)) != NULL &&                               \
-           LIST_FIRST((head))->field.le_prev !=                        \
-            &LIST_FIRST((head)))                                       \
+       if (BSD_LIST_FIRST((head)) != NULL &&                           \
+           BSD_LIST_FIRST((head))->field.le_prev !=                    \
+            &BSD_LIST_FIRST((head)))                                   \
                panic("Bad list head %p first->prev != head", (head));  \
 } while (0)
 
 #define        QMD_LIST_CHECK_NEXT(elm, field) do {                            \
-       if (LIST_NEXT((elm), field) != NULL &&                          \
-           LIST_NEXT((elm), field)->field.le_prev !=                   \
+       if (BSD_LIST_NEXT((elm), field) != NULL &&                              \
+           BSD_LIST_NEXT((elm), field)->field.le_prev !=                       \
             &((elm)->field.le_next))                                   \
                panic("Bad link elm %p next->prev != elm", (elm));      \
 } while (0)
@@ -373,72 +375,77 @@ struct {                                                          \
 #define        QMD_LIST_CHECK_PREV(elm, field)
 #endif /* (_KERNEL && INVARIANTS) */
 
-#define        LIST_EMPTY(head)        ((head)->lh_first == NULL)
+#define        BSD_LIST_EMPTY(head)    ((head)->lh_first == NULL)
 
-#define        LIST_FIRST(head)        ((head)->lh_first)
+#define        BSD_LIST_FIRST(head)    ((head)->lh_first)
 
-#define        LIST_FOREACH(var, head, field)                                  \
-       for ((var) = LIST_FIRST((head));                                \
+#define        BSD_LIST_FOREACH(var, head, field)                                      \
+       for ((var) = BSD_LIST_FIRST((head));                            \
            (var);                                                      \
-           (var) = LIST_NEXT((var), field))
+           (var) = BSD_LIST_NEXT((var), field))
 
-#define        LIST_FOREACH_SAFE(var, head, field, tvar)                       \
-       for ((var) = LIST_FIRST((head));                                \
-           (var) && ((tvar) = LIST_NEXT((var), field), 1);             \
+#define        BSD_LIST_FOREACH_SAFE(var, head, field, tvar)                   \
+       for ((var) = BSD_LIST_FIRST((head));                            \
+           (var) && ((tvar) = BSD_LIST_NEXT((var), field), 1);         \
            (var) = (tvar))
 
-#define        LIST_INIT(head) do {                                            \
-       LIST_FIRST((head)) = NULL;                                      \
+#define        BSD_LIST_INIT(head) do {                                                \
+       BSD_LIST_FIRST((head)) = NULL;                                  \
 } while (0)
 
-#define        LIST_INSERT_AFTER(listelm, elm, field) do {                     \
+#define        BSD_LIST_INSERT_AFTER(listelm, elm, field) do {                 \
        QMD_LIST_CHECK_NEXT(listelm, field);                            \
-       if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
-               LIST_NEXT((listelm), field)->field.le_prev =            \
-                   &LIST_NEXT((elm), field);                           \
-       LIST_NEXT((listelm), field) = (elm);                            \
-       (elm)->field.le_prev = &LIST_NEXT((listelm), field);            \
+       if ((BSD_LIST_NEXT((elm), field) = BSD_LIST_NEXT((listelm), field)) != NULL)\
+               BSD_LIST_NEXT((listelm), field)->field.le_prev =                \
+                   &BSD_LIST_NEXT((elm), field);                               \
+       BSD_LIST_NEXT((listelm), field) = (elm);                                \
+       (elm)->field.le_prev = &BSD_LIST_NEXT((listelm), field);                \
 } while (0)
 
-#define        LIST_INSERT_BEFORE(listelm, elm, field) do {                    \
+#define        BSD_LIST_INSERT_BEFORE(listelm, elm, field) do {                        \
        QMD_LIST_CHECK_PREV(listelm, field);                            \
        (elm)->field.le_prev = (listelm)->field.le_prev;                \
-       LIST_NEXT((elm), field) = (listelm);                            \
+       BSD_LIST_NEXT((elm), field) = (listelm);                                \
        *(listelm)->field.le_prev = (elm);                              \
-       (listelm)->field.le_prev = &LIST_NEXT((elm), field);            \
+       (listelm)->field.le_prev = &BSD_LIST_NEXT((elm), field);                \
 } while (0)
 
-#define        LIST_INSERT_HEAD(head, elm, field) do {                         \
+#define        BSD_LIST_INSERT_HEAD(head, elm, field) do {                             \
        QMD_LIST_CHECK_HEAD((head), field);                             \
-       if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL)     \
-               LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
-       LIST_FIRST((head)) = (elm);                                     \
-       (elm)->field.le_prev = &LIST_FIRST((head));                     \
+       if ((BSD_LIST_NEXT((elm), field) = BSD_LIST_FIRST((head))) != NULL)     \
+               BSD_LIST_FIRST((head))->field.le_prev = &BSD_LIST_NEXT((elm), field);\
+       BSD_LIST_FIRST((head)) = (elm);                                 \
+       (elm)->field.le_prev = &BSD_LIST_FIRST((head));                 \
 } while (0)
 
-#define        LIST_NEXT(elm, field)   ((elm)->field.le_next)
+#define        BSD_LIST_NEXT(elm, field)       ((elm)->field.le_next)
 
-#define        LIST_REMOVE(elm, field) do {                                    \
+#define        BSD_LIST_PREV(elm, head, type, field)                   \
+       ((elm)->field.le_prev == &BSD_LIST_FIRST((head)) ? NULL :       \
+           container_of((elm)->field.le_prev,                  \
+           struct type, field.le_next))
+
+#define        BSD_LIST_REMOVE(elm, field) do {                                        \
        QMD_SAVELINK(oldnext, (elm)->field.le_next);                    \
        QMD_SAVELINK(oldprev, (elm)->field.le_prev);                    \
        QMD_LIST_CHECK_NEXT(elm, field);                                \
        QMD_LIST_CHECK_PREV(elm, field);                                \
-       if (LIST_NEXT((elm), field) != NULL)                            \
-               LIST_NEXT((elm), field)->field.le_prev =                \
+       if (BSD_LIST_NEXT((elm), field) != NULL)                                \
+               BSD_LIST_NEXT((elm), field)->field.le_prev =            \
                    (elm)->field.le_prev;                               \
-       *(elm)->field.le_prev = LIST_NEXT((elm), field);                \
+       *(elm)->field.le_prev = BSD_LIST_NEXT((elm), field);            \
        TRASHIT(*oldnext);                                              \
        TRASHIT(*oldprev);                                              \
 } while (0)
 
-#define LIST_SWAP(head1, head2, type, field) do {                      \
-       struct type *swap_tmp = LIST_FIRST((head1));                    \
-       LIST_FIRST((head1)) = LIST_FIRST((head2));                      \
-       LIST_FIRST((head2)) = swap_tmp;                                 \
-       if ((swap_tmp = LIST_FIRST((head1))) != NULL)                   \
-               swap_tmp->field.le_prev = &LIST_FIRST((head1));         \
-       if ((swap_tmp = LIST_FIRST((head2))) != NULL)                   \
-               swap_tmp->field.le_prev = &LIST_FIRST((head2));         \
+#define BSD_LIST_SWAP(head1, head2, type, field) do {                  \
+       struct type *swap_tmp = BSD_LIST_FIRST((head1));                        \
+       BSD_LIST_FIRST((head1)) = BSD_LIST_FIRST((head2));                      \
+       BSD_LIST_FIRST((head2)) = swap_tmp;                                     \
+       if ((swap_tmp = BSD_LIST_FIRST((head1))) != NULL)                       \
+               swap_tmp->field.le_prev = &BSD_LIST_FIRST((head1));             \
+       if ((swap_tmp = BSD_LIST_FIRST((head2))) != NULL)                       \
+               swap_tmp->field.le_prev = &BSD_LIST_FIRST((head2));             \
 } while (0)
 
 /*
@@ -626,5 +633,3 @@ struct {                                                            \
        else                                                            \
                (head2)->tqh_last = &(head2)->tqh_first;                \
 } while (0)
-
-#endif /* ROS_KERN_SYS_QUEUE_H */