Tighten debug consistency checks in ADDHEAD(), ADDTAIL() and ENQUEUE()
through the macro LIST_ASSERT_NOT_CONTAINS(). Suggestions for a
better name very welcome.
This check is expensive (O(n)) and too permissive, as what we should
really check for is the node not being already part of *any* list.
This could be simplified by changing the list API to demand
pre-initialization of the node pointers to NULL.
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@1772
38d2e660-2303-0410-9eaa-
f027e97ec537
* ADDHEAD(&foo_list, &foo1);
* INSERT_BEFORE(&foo_list, &foo2);
* FOREACH_NODE(fp, &foo_list)
* ADDHEAD(&foo_list, &foo1);
* INSERT_BEFORE(&foo_list, &foo2);
* FOREACH_NODE(fp, &foo_list)
ASSERT(n == &(l)->tail); \
} while (0)
ASSERT(n == &(l)->tail); \
} while (0)
+ /// Checks that a node isn't part of a given list
+ #define LIST_ASSERT_NOT_CONTAINS(list,node) \
+ do { \
+ Node *ln; \
+ ASSERT_VALID_PTR(list); \
+ ASSERT_VALID_PTR(node); \
+ FOREACH_NODE(ln, list) \
+ ASSERT(ln != (Node *)(node)); \
+ } while (0)
+
#define INVALIDATE_NODE(n) ((n)->succ = (n)->pred = NULL)
#else
#define LIST_ASSERT_VALID(l) do {} while (0)
#define INVALIDATE_NODE(n) do {} while (0)
#endif
#define INVALIDATE_NODE(n) ((n)->succ = (n)->pred = NULL)
#else
#define LIST_ASSERT_VALID(l) do {} while (0)
#define INVALIDATE_NODE(n) do {} while (0)
#endif
+/** Tell whether a list is empty. */
+#define LIST_EMPTY(l) ( (void *)((l)->head.succ) == (void *)(&(l)->tail) )
+
/** Add node to list head. */
#define ADDHEAD(l,n) \
do { \
/** Add node to list head. */
#define ADDHEAD(l,n) \
do { \
- ASSERT_VALID_PTR(l); \
- ASSERT_VALID_PTR(n); \
+ LIST_ASSERT_NOT_CONTAINS((l),(n)); \
(n)->succ = (l)->head.succ; \
(n)->pred = (l)->head.succ->pred; \
(n)->succ->pred = (n); \
(n)->succ = (l)->head.succ; \
(n)->pred = (l)->head.succ->pred; \
(n)->succ->pred = (n); \
/** Add node to list tail. */
#define ADDTAIL(l,n) \
do { \
/** Add node to list tail. */
#define ADDTAIL(l,n) \
do { \
- ASSERT_VALID_PTR(l); \
- ASSERT_VALID_PTR(n); \
+ LIST_ASSERT_NOT_CONTAINS((l),(n)); \
(n)->succ = &(l)->tail; \
(n)->pred = (l)->tail.pred; \
(n)->pred->succ = (n); \
(n)->succ = &(l)->tail; \
(n)->pred = (l)->tail.pred; \
(n)->pred->succ = (n); \
INVALIDATE_NODE(n); \
} while (0)
INVALIDATE_NODE(n); \
} while (0)
-/** Tell whether a list is empty. */
-#define LIST_EMPTY(l) ( (void *)((l)->head.succ) == (void *)(&(l)->tail) )
-
/**
* Insert a priority node in a priority queue.
*
/**
* Insert a priority node in a priority queue.
*
#define LIST_ENQUEUE(list, node) \
do { \
PriNode *ln; \
#define LIST_ENQUEUE(list, node) \
do { \
PriNode *ln; \
- ASSERT_VALID_PTR(list); \
- ASSERT_VALID_PTR(node); \
+ LIST_ASSERT_NOT_CONTAINS((list),(node)); \
FOREACH_NODE(ln, (list)) \
if (ln->pri < (node)->pri) \
break; \
FOREACH_NODE(ln, (list)) \
if (ln->pri < (node)->pri) \
break; \