Patchwork [3/8] petitboot: Add list debugging support

login
register
mail settings
Submitter Geoff Levand
Date Feb. 16, 2009, 6:57 a.m.
Message ID <20090216065712.814757320@am.sony.com>
Download mbox | patch
Permalink /patch/23205/
State Accepted
Delegated to: Jeremy Kerr
Headers show

Comments

Geoff Levand - Feb. 16, 2009, 6:57 a.m.
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(-)
Jeremy Kerr - Feb. 21, 2009, 3:14 a.m.
Geoff,

> Add list and list item signature checking when the DEBUG preprocessor
> macro is defined.

Do we really need list debugging support? This is a pretty small 
codebase..

Cheers,

Jeremy

Patch

--- a/lib/list/list.c
+++ b/lib/list/list.c
@@ -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;
--- a/lib/list/list.h
+++ b/lib/list/list.h
@@ -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);
 }