@@ -1,13 +1,13 @@
#include "list/list.h"
-void list_init(struct list *list)
+void list_init_nc(struct list *list)
{
list->head.next = &list->head;
list->head.prev = &list->head;
}
-void list_insert_before(struct list_item *next, struct list_item *new)
+void list_insert_before_nc(struct list_item *next, struct list_item *new)
{
new->next = next;
new->prev = next->prev;
@@ -15,7 +15,7 @@ void list_insert_before(struct list_item
next->prev = new;
}
-void list_insert_after(struct list_item *prev, struct list_item *new)
+void list_insert_after_nc(struct list_item *prev, struct list_item *new)
{
new->next = prev->next;
new->prev = prev;
@@ -23,7 +23,7 @@ void list_insert_after(struct list_item
prev->next = new;
}
-void list_remove(struct list_item *item)
+void list_remove_nc(struct list_item *item)
{
item->next->prev = item->prev;
item->prev->next = item->next;
@@ -1,14 +1,43 @@
#ifndef _LIST_H
#define _LIST_H
+#define DEBUG
+
+#if defined(DEBUG)
+# undef NDEBUG
+#endif
+
+#include <assert.h>
+
+enum list_sig {
+ list_sig = 1111,
+ list_item_sig = 2222,
+ list_removed_sig = -3333,
+};
+
struct list_item {
+#if defined(DEBUG)
+ enum list_sig i_sig;
+#endif
struct list_item *prev, *next;
};
struct list {
+#if defined(DEBUG)
+ enum list_sig l_sig;
+#endif
struct list_item head;
};
+#if defined(DEBUG)
+# define list_item_check(_i) assert((_i)->i_sig == list_item_sig)
+# define list_check(_l) (assert((_l)->l_sig == list_sig), \
+ list_item_check(&(_l)->head))
+#else
+static inline void list_item_check(struct list_item *i) {}
+static inline void list_check(struct list *l) {}
+#endif
+
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
@@ -20,31 +49,81 @@ struct list {
#endif
#define list_for_each(list, pos) \
- for (pos = (list)->head.next; pos != ((list)->head); pos = pos->next)
+ for (list_check(list), \
+ pos = (list)->head.next; pos != ((list)->head); \
+ pos = pos->next, list_item_check(pos))
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_for_each_entry(list, pos, member) \
- for (pos = list_entry((list)->head.next, typeof(*pos), member); \
+ for (list_check(list), \
+ pos = list_entry((list)->head.next, typeof(*pos), member); \
&pos->member != &(list)->head; \
- pos = list_entry(pos->member.next, typeof(*pos), member))
+ pos = list_entry(pos->member.next, typeof(*pos), member), \
+ list_item_check(&pos->member))
+
+#define list_continue_each_entry(list, pos, member) \
+ for (list_check(list); &pos->member != &(list)->head; \
+ pos = list_entry(pos->member.next, typeof(*pos), member), \
+ list_item_check(&pos->member))
+
+/* No-check versions */
+
+void list_init_nc(struct list *list);
+void list_insert_before_nc(struct list_item *next, struct list_item *new);
+void list_insert_after_nc(struct list_item *prev, struct list_item *new);
+void list_remove_nc(struct list_item *item);
+
+/* Checked versions */
+
+static inline void list_init(struct list *list)
+{
+#if defined(DEBUG)
+ list->l_sig = list_sig;
+ list->head.i_sig = list_item_sig;
+#endif
+ list_init_nc(list);
+}
-#define list_continue_each_entry(_list, _pos, _member) \
- for (; &_pos->_member != &(_list)->head; \
- _pos = list_entry(_pos->_member.next, typeof(*_pos), _member))
-
-void list_init(struct list *list);
-void list_insert_before(struct list_item *next, struct list_item *new);
-void list_insert_after(struct list_item *prev, struct list_item *new);
-void list_remove(struct list_item *item);
+static inline void list_insert_before(struct list_item *next,
+ struct list_item *new)
+{
+ list_item_check(next);
+#if defined(DEBUG)
+ new->i_sig = list_item_sig;
+#endif
+ list_insert_before_nc(next, new);
+}
+
+static inline void list_insert_after(struct list_item *prev,
+ struct list_item *new)
+{
+ list_item_check(prev);
+#if defined(DEBUG)
+ new->i_sig = list_item_sig;
+#endif
+ list_insert_after_nc(prev, new);
+}
+
+static inline void list_remove(struct list_item *item)
+{
+ list_item_check(item);
+ list_remove_nc(item);
+#if defined(DEBUG)
+ item->i_sig = list_removed_sig;
+#endif
+}
static inline void list_add(struct list *list, struct list_item *new)
{
+ list_check(list);
list_insert_after(&list->head, new);
}
+
static inline void list_add_tail(struct list *list, struct list_item *new)
{
+ list_check(list);
list_insert_before(&list->head, new);
}
Add list and list item signature checking when the DEBUG preprocessor macro is defined. The signatures are checked during most list operations. Signed-off-by: Geoff Levand <geoffrey.levand@am.sony.com> --- lib/list/list.c | 8 ++-- lib/list/list.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 94 insertions(+), 15 deletions(-)