]> 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 3d32db7a898588167631e21e4c4dd13285851fca..2202f812d133eb9c837e848537949acd868dba3e 100644 (file)
@@ -1,31 +1,29 @@
 /*
- * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2009 Apple Inc. All rights reserved.
  *
- * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
- * 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.
- *
- * 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, 
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
- * Please see the License for the specific language governing rights and 
+ * 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.
+ * 
+ * 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,
+ * 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_OSREFERENCE_HEADER_END@
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /*
  * @OSF_COPYRIGHT@
@@ -108,7 +106,7 @@ typedef     struct queue_entry      *queue_entry_t;
 /*
  *     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)
@@ -139,7 +137,6 @@ extern queue_entry_t        dequeue_tail(
 
 /* Dequeue element */
 extern void            remqueue(
-                               queue_t         que,
                                queue_entry_t   elt);
 
 /* Enqueue element after a particular elem */
@@ -148,13 +145,22 @@ extern void               insque(
                                queue_entry_t   pred);
 
 /* Dequeue element */
-extern int             remque(
+extern void            remque(
                                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,
@@ -187,6 +193,7 @@ dequeue_head(
                elt = que->next;
                elt->next->prev = que;
                que->next = elt->next;
+               __DEQUEUE_ELT_CLEANUP(elt);
        }
 
        return (elt);
@@ -202,6 +209,7 @@ dequeue_tail(
                elt = que->prev;
                elt->prev->next = que;
                que->prev = elt->prev;
+               __DEQUEUE_ELT_CLEANUP(elt);
        }
 
        return (elt);
@@ -209,11 +217,11 @@ dequeue_tail(
 
 static __inline__ void
 remqueue(
-       __unused queue_t                que,
        queue_entry_t   elt)
 {
        elt->next->prev = elt->prev;
        elt->prev->next = elt->next;
+       __DEQUEUE_ELT_CLEANUP(elt);
 }
 
 static __inline__ void
@@ -227,14 +235,13 @@ insque(
        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;
-
-       return((integer_t)elt);
+       __DEQUEUE_ELT_CLEANUP(elt);
 }
 
 #endif /* !__GNUC__ */
@@ -490,6 +497,9 @@ MACRO_BEGIN                                                 \
                (head)->next = __next;                          \
        else                                                    \
                ((type)__prev)->field.next = __next;            \
+                                                               \
+       (elt)->field.next = NULL;                               \
+       (elt)->field.prev = NULL;                               \
 MACRO_END
 
 /*
@@ -513,6 +523,9 @@ MACRO_BEGIN                                                 \
        else                                                    \
                ((type)(__next))->field.prev = (head);          \
        (head)->next = __next;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
@@ -536,6 +549,9 @@ MACRO_BEGIN                                                 \
        else                                                    \
                ((type)(__prev))->field.next = (head);          \
        (head)->prev = __prev;                                  \
+                                                               \
+       (entry)->field.next = NULL;                             \
+       (entry)->field.prev = NULL;                             \
 MACRO_END
 
 /*
@@ -598,34 +614,57 @@ MACRO_END
  */
 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)
 
-#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);                         \
-       simple_lock_init(&(q)->lock, 0);        \
+        lck_spin_init(&(q)->lock_data,                 \
+                     lck_grp,                          \
+                     lck_attr);                        \
 MACRO_END
+#endif
+
 
 #define mpenqueue_tail(q, elt)                         \
 MACRO_BEGIN                                            \
-       simple_lock(&(q)->lock);                        \
+        lck_mtx_lock_spin_always(&(q)->lock_data);     \
        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                                            \
-       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);      \
-       simple_unlock(&(q)->lock);                      \
+       lck_mtx_unlock_always(&(q)->lock_data);         \
 MACRO_END
 
 #endif /* MACH_KERNEL_PRIVATE */