#include <kern/macro_help.h>
#include <sys/cdefs.h>
+#include <string.h>
__BEGIN_DECLS
{
queue_entry_t elt_next, elt_prev;
- if (__improbable(elt == (queue_entry_t)0)) {
+ if (__improbable(elt == (queue_entry_t)NULL)) {
panic("Invalid queue element %p", elt);
}
elt_next = elt->next;
elt_prev = elt->prev;
- if (__improbable(elt_next == (queue_entry_t)0 || elt_prev == (queue_entry_t)0)) {
+ if (__improbable(elt_next == (queue_entry_t)NULL || elt_prev == (queue_entry_t)NULL)) {
panic("Invalid queue element pointers for %p: next %p prev %p", elt, elt_next, elt_prev);
}
if (__improbable(elt_next->prev != elt || elt_prev->next != elt)) {
static inline void
__DEQUEUE_ELT_CLEANUP(queue_entry_t elt)
{
- (elt)->next = (queue_entry_t) 0;
- (elt)->prev = (queue_entry_t) 0;
+ (elt)->next = (queue_entry_t)NULL;
+ (elt)->prev = (queue_entry_t)NULL;
}
#else
#define __QUEUE_ELT_VALIDATE(elt) do { } while (0)
dequeue_head(
queue_t que)
{
- queue_entry_t elt = (queue_entry_t) 0;
+ queue_entry_t elt = (queue_entry_t)NULL;
queue_entry_t new_head;
if (que->next != que) {
dequeue_tail(
queue_t que)
{
- queue_entry_t elt = (queue_entry_t) 0;
+ queue_entry_t elt = (queue_entry_t)NULL;
queue_entry_t new_tail;
if (que->prev != que) {
remque(
queue_entry_t elt)
{
- queue_entry_t next_elt, prev_elt;
-
- __QUEUE_ELT_VALIDATE(elt);
- next_elt = elt->next;
- prev_elt = elt->prev; /* next_elt may equal prev_elt (and the queue head) if elt was the only element */
- next_elt->prev = prev_elt;
- prev_elt->next = next_elt;
- __DEQUEUE_ELT_CLEANUP(elt);
+ remqueue(elt);
}
/*
* Note:
* Do not use pointer types for <type>
*/
-#define qe_element(qe, type, field) \
- ((type *)((void *)((char *)(qe) - __offsetof(type, field))))
+#define qe_element(qe, type, field) __container_of(qe, type, field)
/*
* Macro: qe_foreach
_tmp_element; \
})
+/* Peek at the next element, or return NULL if the next element is head (indicating queue_end) */
+#define qe_queue_next(head, element, type, field) ({ \
+ queue_entry_t _tmp_entry = queue_next(&(element)->field); \
+ type *_tmp_element = (type*) NULL; \
+ if (_tmp_entry != (queue_entry_t) head) \
+ _tmp_element = qe_element(_tmp_entry, type, field); \
+ _tmp_element; \
+})
+
+/* Peek at the prev element, or return NULL if the prev element is head (indicating queue_end) */
+#define qe_queue_prev(head, element, type, field) ({ \
+ queue_entry_t _tmp_entry = queue_prev(&(element)->field); \
+ type *_tmp_element = (type*) NULL; \
+ if (_tmp_entry != (queue_entry_t) head) \
+ _tmp_element = qe_element(_tmp_entry, type, field); \
+ _tmp_element; \
+})
+
#endif /* XNU_KERNEL_PRIVATE */
+/*
+ * Macro: QUEUE_HEAD_INITIALIZER()
+ * Function:
+ * Static queue head initializer
+ */
+#define QUEUE_HEAD_INITIALIZER(name) \
+ { &name, &name }
+
/*
* Macro: queue_init
* Function: