diff options
author | cem <cem@FreeBSD.org> | 2017-04-04 12:00:29 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2017-04-04 12:16:05 +0200 |
commit | 5e36b7010419bdd22116ac26c1b33a4b0831a047 (patch) | |
tree | c45e6f37ec4e0aad77926b365652bd9b91ae00e0 | |
parent | 9998bd4b7c4596e47d8e0fbc6f1f370d096a6618 (diff) | |
download | cygnal-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.h | 42 |
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); \ |