git: fa940dd2bf03 - stable/14 - queue: New debug macros for STAILQ
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 16 Jan 2025 18:08:05 UTC
The branch stable/14 has been updated by olce:
URL: https://cgit.FreeBSD.org/src/commit/?id=fa940dd2bf034a294f6638bd0def2022c7746fd5
commit fa940dd2bf034a294f6638bd0def2022c7746fd5
Author: Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2024-07-08 16:15:49 +0000
Commit: Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-01-16 18:06:53 +0000
queue: New debug macros for STAILQ
The new STAILQ_ASSERT_EMPTY() macro allows callers to assert that some
STAILQ is empty. It leverages the new QMD_STAILQ_CHECK_EMPTY() internal
macro.
QMD_STAILQ_CHECK_EMPTY() is a check for empty STAILQ, where heads's
'stqh_last' field must point to the 'stqh_first' one. Use it in
STAILQ_ASSERT_EMPTY().
QMD_STAILQ_CHECK_TAIL() checks that the tail pointed by 'head' does not
have a next element. It is similar to the already existing
QMD_TAILQ_CHECK_TAIL(), but without the superfluous 'field' argument and
clearer documentation. Use it in STAILQ_INSERT_TAIL().
Approved by: markj (mentor)
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D46889
(cherry picked from commit 34740937f7a46c7475bb57e804701ba8830bf6ed)
---
sys/sys/queue.h | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
index 9bdfd497b165..fee6618ee88c 100644
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -341,6 +341,40 @@ struct { \
/*
* Singly-linked Tail queue functions.
*/
+#if (defined(_KERNEL) && defined(INVARIANTS))
+/*
+ * QMD_STAILQ_CHECK_EMPTY(STAILQ_HEAD *head)
+ *
+ * Validates that the stailq head's pointer to the last element's next pointer
+ * actually points to the head's first element pointer field.
+ */
+#define QMD_STAILQ_CHECK_EMPTY(head) do { \
+ if ((head)->stqh_last != &(head)->stqh_first) \
+ panic("Empty stailq %p->stqh_last is %p, not head's " \
+ "first field address", (head), (head)->stqh_last); \
+} while (0)
+
+#define STAILQ_ASSERT_EMPTY(head) do { \
+ if (!STAILQ_EMPTY((head))) \
+ panic("stailq %p is not empty", (head)); \
+}
+
+/*
+ * QMD_STAILQ_CHECK_TAIL(STAILQ_HEAD *head)
+ *
+ * Validates that the stailq's last element's next pointer is NULL.
+ */
+#define QMD_STAILQ_CHECK_TAIL(head) do { \
+ if (*(head)->stqh_last != NULL) \
+ panic("Stailq %p last element's next pointer is %p, " \
+ "not NULL", (head), *(head)->stqh_last); \
+} while (0)
+#else
+#define QMD_STAILQ_CHECK_EMPTY(head)
+#define STAILQ_ASSERT_EMPTY(head)
+#define QMD_STAILQ_CHECK_TAIL(head)
+#endif /* (_KERNEL && INVARIANTS) */
+
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
@@ -349,7 +383,11 @@ struct { \
} \
} while (0)
-#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
+#define STAILQ_EMPTY(head) ({ \
+ if (STAILQ_FIRST(head) == NULL) \
+ QMD_STAILQ_CHECK_EMPTY(head); \
+ STAILQ_FIRST(head) == NULL; \
+})
#define STAILQ_FIRST(head) ((head)->stqh_first)
@@ -391,6 +429,7 @@ struct { \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
+ QMD_STAILQ_CHECK_TAIL(head); \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \