]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/queue.h
xnu-2422.90.20.tar.gz
[apple/xnu.git] / osfmk / kern / queue.h
index ca0f91eaf390341024b053109312da67b08c6ac9..db7377840ce8f5fb7724bd595f5512eaf14cbf13 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
@@ -106,7 +106,7 @@ typedef     struct queue_entry      *queue_entry_t;
 /*
  *     enqueue puts "elt" on the "queue".
  *     dequeue returns the first element in the "queue".
 /*
  *     enqueue puts "elt" on the "queue".
  *     dequeue returns the first element in the "queue".
- *     remqueue removes the specified "elt" from the specified "queue".
+ *     remqueue removes the specified "elt" from its queue.
  */
 
 #define enqueue(queue,elt)     enqueue_tail(queue, elt)
  */
 
 #define enqueue(queue,elt)     enqueue_tail(queue, elt)
@@ -137,7 +137,6 @@ extern queue_entry_t        dequeue_tail(
 
 /* Dequeue element */
 extern void            remqueue(
 
 /* Dequeue element */
 extern void            remqueue(
-                               queue_t         que,
                                queue_entry_t   elt);
 
 /* Enqueue element after a particular elem */
                                queue_entry_t   elt);
 
 /* Enqueue element after a particular elem */
@@ -146,13 +145,22 @@ extern void               insque(
                                queue_entry_t   pred);
 
 /* Dequeue element */
                                queue_entry_t   pred);
 
 /* Dequeue element */
-extern int             remque(
+extern void            remque(
                                queue_entry_t elt);
 
 __END_DECLS
 
 #else  /* !__GNUC__ */
 
                                queue_entry_t elt);
 
 __END_DECLS
 
 #else  /* !__GNUC__ */
 
+#ifdef XNU_KERNEL_PRIVATE
+#define __DEQUEUE_ELT_CLEANUP(elt) do { \
+               (elt)->next = (queue_entry_t) 0; \
+               (elt)->prev = (queue_entry_t) 0; \
+       } while (0)
+#else
+#define __DEQUEUE_ELT_CLEANUP(elt) do { } while(0)
+#endif /* !XNU_KERNEL_PRIVATE */
+
 static __inline__ void
 enqueue_head(
        queue_t         que,
 static __inline__ void
 enqueue_head(
        queue_t         que,
@@ -185,6 +193,7 @@ dequeue_head(
                elt = que->next;
                elt->next->prev = que;
                que->next = elt->next;
                elt = que->next;
                elt->next->prev = que;
                que->next = elt->next;
+               __DEQUEUE_ELT_CLEANUP(elt);
        }
 
        return (elt);
        }
 
        return (elt);
@@ -200,6 +209,7 @@ dequeue_tail(
                elt = que->prev;
                elt->prev->next = que;
                que->prev = elt->prev;
                elt = que->prev;
                elt->prev->next = que;
                que->prev = elt->prev;
+               __DEQUEUE_ELT_CLEANUP(elt);
        }
 
        return (elt);
        }
 
        return (elt);
@@ -207,11 +217,11 @@ dequeue_tail(
 
 static __inline__ void
 remqueue(
 
 static __inline__ void
 remqueue(
-       __unused queue_t                que,
        queue_entry_t   elt)
 {
        elt->next->prev = elt->prev;
        elt->prev->next = elt->next;
        queue_entry_t   elt)
 {
        elt->next->prev = elt->prev;
        elt->prev->next = elt->next;
+       __DEQUEUE_ELT_CLEANUP(elt);
 }
 
 static __inline__ void
 }
 
 static __inline__ void
@@ -225,14 +235,13 @@ insque(
        pred->next = entry;
 }
 
        pred->next = entry;
 }
 
-static __inline__ integer_t
+static __inline__ void
 remque(
        register queue_entry_t elt)
 {
        (elt->next)->prev = elt->prev;
        (elt->prev)->next = elt->next;
 remque(
        register queue_entry_t elt)
 {
        (elt->next)->prev = elt->prev;
        (elt->prev)->next = elt->next;
-
-       return((integer_t)elt);
+       __DEQUEUE_ELT_CLEANUP(elt);
 }
 
 #endif /* !__GNUC__ */
 }
 
 #endif /* !__GNUC__ */
@@ -341,7 +350,8 @@ MACRO_BEGIN                                                 \
                (head)->next = (queue_entry_t) (elt);           \
        }                                                       \
        else {                                                  \
                (head)->next = (queue_entry_t) (elt);           \
        }                                                       \
        else {                                                  \
-               ((type)__prev)->field.next = (queue_entry_t)(elt);\
+               ((type)(void *)__prev)->field.next =            \
+                       (queue_entry_t)(elt);                   \
        }                                                       \
        (elt)->field.prev = __prev;                             \
        (elt)->field.next = head;                               \
        }                                                       \
        (elt)->field.prev = __prev;                             \
        (elt)->field.next = head;                               \
@@ -368,7 +378,8 @@ MACRO_BEGIN                                                 \
                (head)->prev = (queue_entry_t) (elt);           \
        }                                                       \
        else {                                                  \
                (head)->prev = (queue_entry_t) (elt);           \
        }                                                       \
        else {                                                  \
-               ((type)__next)->field.prev = (queue_entry_t)(elt);\
+               ((type)(void *)__next)->field.prev =            \
+                       (queue_entry_t)(elt);                   \
        }                                                       \
        (elt)->field.next = __next;                             \
        (elt)->field.prev = head;                               \
        }                                                       \
        (elt)->field.next = __next;                             \
        (elt)->field.prev = head;                               \
@@ -398,7 +409,8 @@ MACRO_BEGIN                                                         \
                        (head)->next = (queue_entry_t)(elt);            \
                } else {                        /* last element */      \
                        __prev = (elt)->field.prev = (head)->prev;      \
                        (head)->next = (queue_entry_t)(elt);            \
                } else {                        /* last element */      \
                        __prev = (elt)->field.prev = (head)->prev;      \
-                       ((type)__prev)->field.next = (queue_entry_t)(elt);\
+                       ((type)(void *)__prev)->field.next =            \
+                               (queue_entry_t)(elt);                   \
                }                                                       \
                (head)->prev = (queue_entry_t)(elt);                    \
        } else {                                                        \
                }                                                       \
                (head)->prev = (queue_entry_t)(elt);                    \
        } else {                                                        \
@@ -409,7 +421,8 @@ MACRO_BEGIN                                                         \
                        (head)->next = (queue_entry_t)(elt);            \
                } else {                        /* middle element */    \
                        __prev = (elt)->field.prev = (cur)->field.prev; \
                        (head)->next = (queue_entry_t)(elt);            \
                } else {                        /* middle element */    \
                        __prev = (elt)->field.prev = (cur)->field.prev; \
-                       ((type)__prev)->field.next = (queue_entry_t)(elt);\
+                       ((type)(void *)__prev)->field.next =            \
+                               (queue_entry_t)(elt);                   \
                }                                                       \
                (cur)->field.prev = (queue_entry_t)(elt);               \
        }                                                               \
                }                                                       \
                (cur)->field.prev = (queue_entry_t)(elt);               \
        }                                                               \
@@ -438,7 +451,8 @@ MACRO_BEGIN                                                         \
                        (head)->prev = (queue_entry_t)(elt);            \
                } else {                        /* first element */     \
                        __next = (elt)->field.next = (head)->next;      \
                        (head)->prev = (queue_entry_t)(elt);            \
                } else {                        /* first element */     \
                        __next = (elt)->field.next = (head)->next;      \
-                       ((type)__next)->field.prev = (queue_entry_t)(elt);\
+                       ((type)(void *)__next)->field.prev =            \
+                               (queue_entry_t)(elt);                   \
                }                                                       \
                (head)->next = (queue_entry_t)(elt);                    \
        } else {                                                        \
                }                                                       \
                (head)->next = (queue_entry_t)(elt);                    \
        } else {                                                        \
@@ -449,7 +463,8 @@ MACRO_BEGIN                                                         \
                        (head)->prev = (queue_entry_t)(elt);            \
                } else {                        /* middle element */    \
                        __next = (elt)->field.next = (cur)->field.next; \
                        (head)->prev = (queue_entry_t)(elt);            \
                } else {                        /* middle element */    \
                        __next = (elt)->field.next = (cur)->field.next; \
-                       ((type)__next)->field.prev = (queue_entry_t)(elt);\
+                       ((type)(void *)__next)->field.prev =            \
+                               (queue_entry_t)(elt);                   \
                }                                                       \
                (cur)->field.next = (queue_entry_t)(elt);               \
        }                                                               \
                }                                                       \
                (cur)->field.next = (queue_entry_t)(elt);               \
        }                                                               \
@@ -462,7 +477,7 @@ MACRO_END
  *             given element (thing) in the given queue (head)
  */
 #define        queue_field(head, thing, type, field)                   \
  *             given element (thing) in the given queue (head)
  */
 #define        queue_field(head, thing, type, field)                   \
-               (((head) == (thing)) ? (head) : &((type)(thing))->field)
+               (((head) == (thing)) ? (head) : &((type)(void *)(thing))->field)
 
 /*
  *     Macro:          queue_remove
 
 /*
  *     Macro:          queue_remove
@@ -482,12 +497,15 @@ MACRO_BEGIN                                                       \
        if ((head) == __next)                                   \
                (head)->prev = __prev;                          \
        else                                                    \
        if ((head) == __next)                                   \
                (head)->prev = __prev;                          \
        else                                                    \
-               ((type)__next)->field.prev = __prev;            \
+               ((type)(void *)__next)->field.prev = __prev;    \
                                                                \
        if ((head) == __prev)                                   \
                (head)->next = __next;                          \
        else                                                    \
                                                                \
        if ((head) == __prev)                                   \
                (head)->next = __next;                          \
        else                                                    \
-               ((type)__prev)->field.next = __next;            \
+               ((type)(void *)__prev)->field.next = __next;    \
+                                                               \
+       (elt)->field.next = NULL;                               \
+       (elt)->field.prev = NULL;                               \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -503,14 +521,17 @@ MACRO_END
 MACRO_BEGIN                                                    \
        register queue_entry_t  __next;                         \
                                                                \
 MACRO_BEGIN                                                    \
        register queue_entry_t  __next;                         \
                                                                \
-       (entry) = (type) ((head)->next);                        \
+       (entry) = (type)(void *) ((head)->next);                \
        __next = (entry)->field.next;                           \
                                                                \
        if ((head) == __next)                                   \
                (head)->prev = (head);                          \
        else                                                    \
        __next = (entry)->field.next;                           \
                                                                \
        if ((head) == __next)                                   \
                (head)->prev = (head);                          \
        else                                                    \
-               ((type)(__next))->field.prev = (head);          \
+               ((type)(void *)(__next))->field.prev = (head);  \
        (head)->next = __next;                                  \
        (head)->next = __next;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -526,14 +547,17 @@ MACRO_END
 MACRO_BEGIN                                                    \
        register queue_entry_t  __prev;                         \
                                                                \
 MACRO_BEGIN                                                    \
        register queue_entry_t  __prev;                         \
                                                                \
-       (entry) = (type) ((head)->prev);                        \
+       (entry) = (type)(void *) ((head)->prev);                \
        __prev = (entry)->field.prev;                           \
                                                                \
        if ((head) == __prev)                                   \
                (head)->next = (head);                          \
        else                                                    \
        __prev = (entry)->field.prev;                           \
                                                                \
        if ((head) == __prev)                                   \
                (head)->next = (head);                          \
        else                                                    \
-               ((type)(__prev))->field.next = (head);          \
+               ((type)(void *)(__prev))->field.next = (head);  \
        (head)->prev = __prev;                                  \
        (head)->prev = __prev;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -541,8 +565,8 @@ MACRO_END
  */
 #define        queue_assign(to, from, type, field)                     \
 MACRO_BEGIN                                                    \
  */
 #define        queue_assign(to, from, type, field)                     \
 MACRO_BEGIN                                                    \
-       ((type)((from)->prev))->field.next = (to);              \
-       ((type)((from)->next))->field.prev = (to);              \
+       ((type)(void *)((from)->prev))->field.next = (to);      \
+       ((type)(void *)((from)->next))->field.prev = (to);      \
        *to = *from;                                            \
 MACRO_END
 
        *to = *from;                                            \
 MACRO_END
 
@@ -561,8 +585,10 @@ MACRO_END
 MACRO_BEGIN                                                    \
        if (!queue_empty(old)) {                                \
                *(new) = *(old);                                \
 MACRO_BEGIN                                                    \
        if (!queue_empty(old)) {                                \
                *(new) = *(old);                                \
-               ((type)((new)->next))->field.prev = (new);      \
-               ((type)((new)->prev))->field.next = (new);      \
+               ((type)(void *)((new)->next))->field.prev =     \
+                       (new);                                  \
+               ((type)(void *)((new)->prev))->field.next =     \
+                       (new);                                  \
        } else {                                                \
                queue_init(new);                                \
        }                                                       \
        } else {                                                \
                queue_init(new);                                \
        }                                                       \
@@ -582,9 +608,9 @@ MACRO_END
  *                     <field> is the chain field in (*<type>)
  */
 #define queue_iterate(head, elt, type, field)                  \
  *                     <field> is the chain field in (*<type>)
  */
 #define queue_iterate(head, elt, type, field)                  \
-       for ((elt) = (type) queue_first(head);                  \
+       for ((elt) = (type)(void *) queue_first(head);          \
             !queue_end((head), (queue_entry_t)(elt));          \
             !queue_end((head), (queue_entry_t)(elt));          \
-            (elt) = (type) queue_next(&(elt)->field))
+            (elt) = (type)(void *) queue_next(&(elt)->field))
 
 #ifdef MACH_KERNEL_PRIVATE
 
 
 #ifdef MACH_KERNEL_PRIVATE
 
@@ -596,34 +622,61 @@ MACRO_END
  */
 struct mpqueue_head {
        struct queue_entry      head;           /* header for queue */
  */
 struct mpqueue_head {
        struct queue_entry      head;           /* header for queue */
-       decl_simple_lock_data(, lock)           /* lock for queue */
+       uint64_t                earliest_soft_deadline;
+       uint64_t                count;
+#if defined(__i386__) || defined(__x86_64__)
+       lck_mtx_t               lock_data;
+       lck_mtx_ext_t           lock_data_ext;
+#else
+       lck_spin_t              lock_data;
+#endif
 };
 
 typedef struct mpqueue_head    mpqueue_head_t;
 
 #define        round_mpq(size)         (size)
 
 };
 
 typedef struct mpqueue_head    mpqueue_head_t;
 
 #define        round_mpq(size)         (size)
 
-#define mpqueue_init(q)                                        \
+
+#if defined(__i386__) || defined(__x86_64__)
+
+#define mpqueue_init(q, lck_grp, lck_attr)             \
 MACRO_BEGIN                                            \
        queue_init(&(q)->head);                         \
 MACRO_BEGIN                                            \
        queue_init(&(q)->head);                         \
-       simple_lock_init(&(q)->lock, 0);        \
+        lck_mtx_init_ext(&(q)->lock_data,              \
+                        &(q)->lock_data_ext,           \
+                        lck_grp,                       \
+                        lck_attr);                     \
+       (q)->earliest_soft_deadline = UINT64_MAX;       \
+       (q)->count = 0;                                 \
 MACRO_END
 
 MACRO_END
 
+#else
+
+#define mpqueue_init(q, lck_grp, lck_attr)             \
+MACRO_BEGIN                                            \
+       queue_init(&(q)->head);                         \
+        lck_spin_init(&(q)->lock_data,                 \
+                     lck_grp,                          \
+                     lck_attr);                        \
+MACRO_END
+#endif
+
+
 #define mpenqueue_tail(q, elt)                         \
 MACRO_BEGIN                                            \
 #define mpenqueue_tail(q, elt)                         \
 MACRO_BEGIN                                            \
-       simple_lock(&(q)->lock);                        \
+        lck_mtx_lock_spin_always(&(q)->lock_data);     \
        enqueue_tail(&(q)->head, elt);                  \
        enqueue_tail(&(q)->head, elt);                  \
-       simple_unlock(&(q)->lock);                      \
+       lck_mtx_unlock_always(&(q)->lock_data);         \
 MACRO_END
 
 #define mpdequeue_head(q, elt)                         \
 MACRO_BEGIN                                            \
 MACRO_END
 
 #define mpdequeue_head(q, elt)                         \
 MACRO_BEGIN                                            \
-       simple_lock(&(q)->lock);                        \
+        lck_mtx_lock_spin_always(&(q)->lock_data);     \
        if (queue_empty(&(q)->head))                    \
                *(elt) = 0;                             \
        else                                            \
                *(elt) = dequeue_head(&(q)->head);      \
        if (queue_empty(&(q)->head))                    \
                *(elt) = 0;                             \
        else                                            \
                *(elt) = dequeue_head(&(q)->head);      \
-       simple_unlock(&(q)->lock);                      \
+       lck_mtx_unlock_always(&(q)->lock_data);         \
 MACRO_END
 
 #endif /* MACH_KERNEL_PRIVATE */
 MACRO_END
 
 #endif /* MACH_KERNEL_PRIVATE */