summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcem <cem@FreeBSD.org>2017-04-04 12:00:29 +0200
committerCorinna Vinschen <corinna@vinschen.de>2017-04-04 12:16:05 +0200
commit5e36b7010419bdd22116ac26c1b33a4b0831a047 (patch)
treec45e6f37ec4e0aad77926b365652bd9b91ae00e0
parent9998bd4b7c4596e47d8e0fbc6f1f370d096a6618 (diff)
downloadcygnal-5e36b7010419bdd22116ac26c1b33a4b0831a047.tar.gz
cygnal-5e36b7010419bdd22116ac26c1b33a4b0831a047.tar.bz2
cygnal-5e36b7010419bdd22116ac26c1b33a4b0831a047.zip
queue(3): Enhance queue debugging macros
Split the QUEUE_MACRO_DEBUG into QUEUE_MACRO_DEBUG_TRACE and QUEUE_MACRO_DEBUG_TRASH. Add the debug macrso QMD_IS_TRASHED() and QMD_SLIST_CHECK_PREVPTR(). Document these in queue.3. Reviewed by: emaste Sponsored by: Dell EMC Isilon Differential Revision: https://reviews.freebsd.org/D3984
-rw-r--r--newlib/libc/include/sys/queue.h42
1 files changed, 37 insertions, 5 deletions
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index 46bb69f29..8a9d07e11 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -113,6 +113,12 @@
*
*/
#ifdef QUEUE_MACRO_DEBUG
+#warn Use QUEUE_MACRO_DEBUG_TRACE and/or QUEUE_MACRO_DEBUG_TRASH
+#define QUEUE_MACRO_DEBUG_TRACE
+#define QUEUE_MACRO_DEBUG_TRASH
+#endif
+
+#ifdef QUEUE_MACRO_DEBUG_TRACE
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
unsigned long lastline;
@@ -123,8 +129,6 @@ struct qm_trace {
#define TRACEBUF struct qm_trace trace;
#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
-#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
-#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
#define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \
@@ -140,14 +144,26 @@ struct qm_trace {
(elem)->trace.lastfile = __FILE__; \
} while (0)
-#else
+#else /* !QUEUE_MACRO_DEBUG_TRACE */
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
-#define QMD_SAVELINK(name, link)
#define TRACEBUF
#define TRACEBUF_INITIALIZER
+#endif /* QUEUE_MACRO_DEBUG_TRACE */
+
+#ifdef QUEUE_MACRO_DEBUG_TRASH
+#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
+#define QMD_IS_TRASHED(x) ((x) == (void *)(intptr_t)-1)
+#else /* !QUEUE_MACRO_DEBUG_TRASH */
#define TRASHIT(x)
-#endif /* QUEUE_MACRO_DEBUG */
+#define QMD_IS_TRASHED(x) 0
+#endif /* QUEUE_MACRO_DEBUG_TRASH */
+
+#if defined(QUEUE_MACRO_DEBUG_TRACE) || defined(QUEUE_MACRO_DEBUG_TRASH)
+#define QMD_SAVELINK(name, link) void **name = (void *)&(link)
+#else /* !QUEUE_MACRO_DEBUG_TRACE && !QUEUE_MACRO_DEBUG_TRASH */
+#define QMD_SAVELINK(name, link)
+#endif /* QUEUE_MACRO_DEBUG_TRACE || QUEUE_MACRO_DEBUG_TRASH */
#ifdef __cplusplus
/*
@@ -187,6 +203,16 @@ struct { \
/*
* Singly-linked List functions.
*/
+#if (defined(_KERNEL) && defined(INVARIANTS))
+#define QMD_SLIST_CHECK_PREVPTR(prevp, elm) do { \
+ if (*(prevp) != (elm)) \
+ panic("Bad prevptr *(%p) == %p != %p", \
+ (prevp), *(prevp), (elm)); \
+} while (0)
+#else
+#define QMD_SLIST_CHECK_PREVPTR(prevp, elm)
+#endif
+
#define SLIST_CONCAT(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
if (curelm == NULL) { \
@@ -268,6 +294,12 @@ struct { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
+#define SLIST_REMOVE_PREVPTR(prevp, elm, field) do { \
+ QMD_SLIST_CHECK_PREVPTR(prevp, elm); \
+ *(prevp) = SLIST_NEXT(elm, field); \
+ TRASHIT((elm)->field.sle_next); \
+} while (0)
+
#define SLIST_SWAP(head1, head2, type) do { \
QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \