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