]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/kern/queue.h
xnu-2050.48.11.tar.gz
[apple/xnu.git] / osfmk / kern / queue.h
index 98effaac491d28c40fbbc7810a192cf4c29882ef..2202f812d133eb9c837e848537949acd868dba3e 100644 (file)
@@ -1,23 +1,29 @@
 /*
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
  *
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * 
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
  * 
  * 
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
  */
 /*
  * @OSF_COPYRIGHT@
@@ -100,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)
@@ -131,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 */
@@ -140,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,
@@ -179,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);
@@ -194,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);
@@ -201,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
@@ -219,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__ */
@@ -482,6 +497,9 @@ MACRO_BEGIN                                                 \
                (head)->next = __next;                          \
        else                                                    \
                ((type)__prev)->field.next = __next;            \
                (head)->next = __next;                          \
        else                                                    \
                ((type)__prev)->field.next = __next;            \
+                                                               \
+       (elt)->field.next = NULL;                               \
+       (elt)->field.prev = NULL;                               \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -505,6 +523,9 @@ MACRO_BEGIN                                                 \
        else                                                    \
                ((type)(__next))->field.prev = (head);          \
        (head)->next = __next;                                  \
        else                                                    \
                ((type)(__next))->field.prev = (head);          \
        (head)->next = __next;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -528,6 +549,9 @@ MACRO_BEGIN                                                 \
        else                                                    \
                ((type)(__prev))->field.next = (head);          \
        (head)->prev = __prev;                                  \
        else                                                    \
                ((type)(__prev))->field.next = (head);          \
        (head)->prev = __prev;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
 MACRO_END
 
 /*
@@ -590,34 +614,57 @@ 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 */
+#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);                         \
+        lck_mtx_init_ext(&(q)->lock_data,              \
+                        &(q)->lock_data_ext,           \
+                        lck_grp,                       \
+                        lck_attr);                     \
+MACRO_END
+
+#else
+
+#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_spin_init(&(q)->lock_data,                 \
+                     lck_grp,                          \
+                     lck_attr);                        \
 MACRO_END
 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 */