tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[PATCH] implementation of backward traversing of lists
Hi all,
the LIST data structure is the only one of the six data structures (SLIST,
LIST, SIMPLEQ, STAILQ, TAILQ, CIRCLEQ), which is a double linked structure,
but can't be traversed backwards.
Here is an implementation of a macro definition LIST_PREV enabling to traverse
a double linked list (defined by LIST_HEAD and other LIST_* macros) backwards.
For some list and an entry pointer defined by
LIST_HEAD(listhead, entry) ;
struct data
{
... ;
LIST_ENTRY(data) xxx ;
... ;
} *pointer, ..... ;
the usage is:
struct data *previous = LIST_PREV(pointer, xxx, data) ;
That can be a little confusing, because the LIST_NEXT macro does not need the
third parameter:
struct entry *next = LIST_NEXT(pointer, xxx) ;
Any comments are welcome.
With best regards,
-- Ilya Dogolazky
---
sys/sys/queue.h | 7 ++++++-
1 files changed, 6 insertions(+), 1 deletions(-)
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index bce1ca0..a3f8a2d 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -165,13 +165,18 @@ struct {
\
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
-
+/*
+ * Two private helper methods
+ */
+#define LIST_DIFF(elm, field)
((uintptr_t)(&(elm)->field.le_next)-(uintptr_t)(elm))
+#define LIST_PREV_ADDR(elm, field)
((uintptr_t)((elm)->field.le_prev)-LIST_DIFF(elm,field))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
+#define LIST_PREV(elm, field, type) ((elm)->field.le_prev?(struct type
*)LIST_PREV_ADDR(elm,field):NULL)
/*
--
1.5.6.3
Home |
Main Index |
Thread Index |
Old Index