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
This commit is contained in:
parent
9998bd4b7c
commit
5e36b70104
@ -113,6 +113,12 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef QUEUE_MACRO_DEBUG
|
#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 */
|
/* Store the last 2 places the queue element or head was altered */
|
||||||
struct qm_trace {
|
struct qm_trace {
|
||||||
unsigned long lastline;
|
unsigned long lastline;
|
||||||
@ -123,8 +129,6 @@ struct qm_trace {
|
|||||||
|
|
||||||
#define TRACEBUF struct qm_trace trace;
|
#define TRACEBUF struct qm_trace trace;
|
||||||
#define TRACEBUF_INITIALIZER { __LINE__, 0, __FILE__, NULL } ,
|
#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 { \
|
#define QMD_TRACE_HEAD(head) do { \
|
||||||
(head)->trace.prevline = (head)->trace.lastline; \
|
(head)->trace.prevline = (head)->trace.lastline; \
|
||||||
@ -140,14 +144,26 @@ struct qm_trace {
|
|||||||
(elem)->trace.lastfile = __FILE__; \
|
(elem)->trace.lastfile = __FILE__; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#else
|
#else /* !QUEUE_MACRO_DEBUG_TRACE */
|
||||||
#define QMD_TRACE_ELEM(elem)
|
#define QMD_TRACE_ELEM(elem)
|
||||||
#define QMD_TRACE_HEAD(head)
|
#define QMD_TRACE_HEAD(head)
|
||||||
#define QMD_SAVELINK(name, link)
|
|
||||||
#define TRACEBUF
|
#define TRACEBUF
|
||||||
#define TRACEBUF_INITIALIZER
|
#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)
|
#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
|
#ifdef __cplusplus
|
||||||
/*
|
/*
|
||||||
@ -187,6 +203,16 @@ struct { \
|
|||||||
/*
|
/*
|
||||||
* Singly-linked List functions.
|
* 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 { \
|
#define SLIST_CONCAT(head1, head2, type, field) do { \
|
||||||
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
|
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
|
||||||
if (curelm == NULL) { \
|
if (curelm == NULL) { \
|
||||||
@ -268,6 +294,12 @@ struct { \
|
|||||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||||
} while (0)
|
} 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 { \
|
#define SLIST_SWAP(head1, head2, type) do { \
|
||||||
QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
|
QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
|
||||||
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
|
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user