* [PATCH v2 6/8] queue(3): Enhance queue debugging macros
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 3/8] Pass macro arguments properly Sebastian Huber
` (6 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: cem <cem@FreeBSD.org>
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
---
newlib/libc/include/sys/queue.h | 42 ++++++++++++++++++++++++++++++++++++-----
1 file changed, 37 insertions(+), 5 deletions(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index 46bb69f..8a9d07e 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); \
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 3/8] Pass macro arguments properly.
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 6/8] queue(3): Enhance queue debugging macros Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 2/8] Fix order of arguments in the TRACEBUF_INITIALIZER Sebastian Huber
` (5 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: hselasky <hselasky@FreeBSD.org>
MFC after: 1 week
---
newlib/libc/include/sys/queue.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index d9908a4..f00e92f 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -617,7 +617,7 @@ struct { \
TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
- QMD_TRACE_ELEM(&listelm->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
@@ -627,7 +627,7 @@ struct { \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
- QMD_TRACE_ELEM(&listelm->field); \
+ QMD_TRACE_ELEM(&(listelm)->field); \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 2/8] Fix order of arguments in the TRACEBUF_INITIALIZER
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 6/8] queue(3): Enhance queue debugging macros Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 3/8] Pass macro arguments properly Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 5/8] Add two new macros, SLIST_CONCAT and LIST_CONCAT Sebastian Huber
` (4 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: hselasky <hselasky@FreeBSD.org>
Fix order of arguments in the TRACEBUF_INITIALIZER macro so that we can
define QUEUE_MACRO_DEBUG to debug list problems.
MFC after: 1 week
---
newlib/libc/include/sys/queue.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index 7a5bc79..d9908a4 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -116,7 +116,7 @@ struct qm_trace {
};
#define TRACEBUF struct qm_trace trace;
-#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } ,
+#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)
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 5/8] Add two new macros, SLIST_CONCAT and LIST_CONCAT
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
` (2 preceding siblings ...)
2017-04-04 10:00 ` [PATCH v2 2/8] Fix order of arguments in the TRACEBUF_INITIALIZER Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 7/8] queue.3: Document existing QMD_* macros Sebastian Huber
` (3 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: mckusick <mckusick@FreeBSD.org>
Add two new macros, SLIST_CONCAT and LIST_CONCAT. Note in both the
queue.h header file and in the queue.3 manual page that they are O(n) so
should be used only in low-usage paths with short lists (otherwise an
STAILQ or TAILQ should be used).
Reviewed by: kib
---
newlib/libc/include/sys/queue.h | 38 ++++++++++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index d6c821f..46bb69f 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -76,6 +76,10 @@
*
* For details on the use of these macros, see the queue(3) manual page.
*
+ * Below is a summary of implemented functions where:
+ * + means the macro is available
+ * - means the macro is not available
+ * s means the macro is available but is slow (runs in O(n) time)
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
@@ -101,10 +105,10 @@
* _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + +
* _INSERT_TAIL - - + +
- * _CONCAT - - + +
+ * _CONCAT s s + +
* _REMOVE_AFTER + - + -
* _REMOVE_HEAD + - + -
- * _REMOVE + + + +
+ * _REMOVE s + s +
* _SWAP + + + +
*
*/
@@ -183,6 +187,19 @@ struct { \
/*
* Singly-linked List functions.
*/
+#define SLIST_CONCAT(head1, head2, type, field) do { \
+ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
+ if (curelm == NULL) { \
+ if ((SLIST_FIRST(head1) = SLIST_FIRST(head2)) != NULL) \
+ SLIST_INIT(head2); \
+ } else if (SLIST_FIRST(head2) != NULL) { \
+ while (SLIST_NEXT(curelm, field) != NULL) \
+ curelm = SLIST_NEXT(curelm, field); \
+ SLIST_NEXT(curelm, field) = SLIST_FIRST(head2); \
+ SLIST_INIT(head2); \
+ } \
+} while (0)
+
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
@@ -452,6 +469,23 @@ struct { \
#define QMD_LIST_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */
+#define LIST_CONCAT(head1, head2, type, field) do { \
+ QUEUE_TYPEOF(type) *curelm = LIST_FIRST(head1); \
+ if (curelm == NULL) { \
+ if ((LIST_FIRST(head1) = LIST_FIRST(head2)) != NULL) { \
+ LIST_FIRST(head2)->field.le_prev = \
+ &LIST_FIRST((head1)); \
+ LIST_INIT(head2); \
+ } \
+ } else if (LIST_FIRST(head2) != NULL) { \
+ while (LIST_NEXT(curelm, field) != NULL) \
+ curelm = LIST_NEXT(curelm, field); \
+ LIST_NEXT(curelm, field) = LIST_FIRST(head2); \
+ LIST_FIRST(head2)->field.le_prev = &LIST_NEXT(curelm, field); \
+ LIST_INIT(head2); \
+ } \
+} while (0)
+
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 7/8] queue.3: Document existing QMD_* macros
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
` (3 preceding siblings ...)
2017-04-04 10:00 ` [PATCH v2 5/8] Add two new macros, SLIST_CONCAT and LIST_CONCAT Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 4/8] Make the <sys/queue.h> fully usable within C++ Sebastian Huber
` (2 subsequent siblings)
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: cem <cem@FreeBSD.org>
Feedback from: bapt, bdrewery, emaste
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D3983
---
newlib/libc/include/sys/queue.h | 39 +++++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index 8a9d07e..6cae4c1 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -477,6 +477,12 @@ struct { \
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
+/*
+ * QMD_LIST_CHECK_HEAD(LIST_HEAD *head, LIST_ENTRY NAME)
+ *
+ * If the list is non-empty, validates that the first element of the list
+ * points back at 'head.'
+ */
#define QMD_LIST_CHECK_HEAD(head, field) do { \
if (LIST_FIRST((head)) != NULL && \
LIST_FIRST((head))->field.le_prev != \
@@ -484,6 +490,12 @@ struct { \
panic("Bad list head %p first->prev != head", (head)); \
} while (0)
+/*
+ * QMD_LIST_CHECK_NEXT(TYPE *elm, LIST_ENTRY NAME)
+ *
+ * If an element follows 'elm' in the list, validates that the next element
+ * points back at 'elm.'
+ */
#define QMD_LIST_CHECK_NEXT(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL && \
LIST_NEXT((elm), field)->field.le_prev != \
@@ -491,6 +503,11 @@ struct { \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
+/*
+ * QMD_LIST_CHECK_PREV(TYPE *elm, LIST_ENTRY NAME)
+ *
+ * Validates that the previous element (or head of the list) points to 'elm.'
+ */
#define QMD_LIST_CHECK_PREV(elm, field) do { \
if (*(elm)->field.le_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
@@ -639,6 +656,12 @@ struct { \
* Tail queue functions.
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
+/*
+ * QMD_TAILQ_CHECK_HEAD(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
+ *
+ * If the tailq is non-empty, validates that the first element of the tailq
+ * points back at 'head.'
+ */
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
if (!TAILQ_EMPTY(head) && \
TAILQ_FIRST((head))->field.tqe_prev != \
@@ -646,11 +669,22 @@ struct { \
panic("Bad tailq head %p first->prev != head", (head)); \
} while (0)
+/*
+ * QMD_TAILQ_CHECK_TAIL(TAILQ_HEAD *head, TAILQ_ENTRY NAME)
+ *
+ * Validates that the tail of the tailq is a pointer to pointer to NULL.
+ */
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
if (*(head)->tqh_last != NULL) \
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
} while (0)
+/*
+ * QMD_TAILQ_CHECK_NEXT(TYPE *elm, TAILQ_ENTRY NAME)
+ *
+ * If an element follows 'elm' in the tailq, validates that the next element
+ * points back at 'elm.'
+ */
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
if (TAILQ_NEXT((elm), field) != NULL && \
TAILQ_NEXT((elm), field)->field.tqe_prev != \
@@ -658,6 +692,11 @@ struct { \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
+/*
+ * QMD_TAILQ_CHECK_PREV(TYPE *elm, TAILQ_ENTRY NAME)
+ *
+ * Validates that the previous element (or head of the tailq) points to 'elm.'
+ */
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
if (*(elm)->field.tqe_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 4/8] Make the <sys/queue.h> fully usable within C++
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
` (4 preceding siblings ...)
2017-04-04 10:00 ` [PATCH v2 7/8] queue.3: Document existing QMD_* macros Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:00 ` [PATCH v2 8/8] Renumber copyright clause 4 Sebastian Huber
2017-04-04 10:18 ` [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Corinna Vinschen
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: hselasky <hselasky@FreeBSD.org>
Make the system queue header file fully usable within C++ programs by
adding macros to define class lists.
This change is backwards compatible for all use within C and C++
programs. Only C++ programs will have added support to use the queue
macros within classes. Previously the queue macros could only be used
within structures.
The queue.3 manual page has been updated to describe the new
functionality and some alphabetic sorting has been done while
at it.
Differential Revision: https://reviews.freebsd.org/D2745
PR: 200827 (exp-run)
MFC after: 2 weeks
---
newlib/libc/include/sys/queue.h | 87 ++++++++++++++++++++++++++++++++++-------
1 file changed, 73 insertions(+), 14 deletions(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index f00e92f..d6c821f 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -79,8 +79,10 @@
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
+ * _CLASS_HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
+ * _CLASS_ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
@@ -143,6 +145,15 @@ struct qm_trace {
#define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */
+#ifdef __cplusplus
+/*
+ * In C++ there can be structure lists and class lists:
+ */
+#define QUEUE_TYPEOF(type) type
+#else
+#define QUEUE_TYPEOF(type) struct type
+#endif
+
/*
* Singly-linked List declarations.
*/
@@ -151,6 +162,11 @@ struct name { \
struct type *slh_first; /* first element */ \
}
+#define SLIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *slh_first; /* first element */ \
+}
+
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
@@ -159,6 +175,11 @@ struct { \
struct type *sle_next; /* next element */ \
}
+#define SLIST_CLASS_ENTRY(type) \
+struct { \
+ class type *sle_next; /* next element */ \
+}
+
/*
* Singly-linked List functions.
*/
@@ -213,7 +234,7 @@ struct { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
- struct type *curelm = SLIST_FIRST((head)); \
+ QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_REMOVE_AFTER(curelm, field); \
@@ -231,7 +252,7 @@ struct { \
} while (0)
#define SLIST_SWAP(head1, head2, type) do { \
- struct type *swap_first = SLIST_FIRST(head1); \
+ QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
SLIST_FIRST(head2) = swap_first; \
} while (0)
@@ -245,6 +266,12 @@ struct name { \
struct type **stqh_last;/* addr of last next element */ \
}
+#define STAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *stqh_first; /* first element */ \
+ class type **stqh_last; /* addr of last next element */ \
+}
+
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
@@ -253,6 +280,11 @@ struct { \
struct type *stqe_next; /* next element */ \
}
+#define STAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *stqe_next; /* next element */ \
+}
+
/*
* Singly-linked Tail queue functions.
*/
@@ -311,9 +343,10 @@ struct { \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
-#define STAILQ_LAST(head, type, field) \
- (STAILQ_EMPTY((head)) ? NULL : \
- __containerof((head)->stqh_last, struct type, field.stqe_next))
+#define STAILQ_LAST(head, type, field) \
+ (STAILQ_EMPTY((head)) ? NULL : \
+ __containerof((head)->stqh_last, \
+ QUEUE_TYPEOF(type), field.stqe_next))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
@@ -323,7 +356,7 @@ struct { \
STAILQ_REMOVE_HEAD((head), field); \
} \
else { \
- struct type *curelm = STAILQ_FIRST((head)); \
+ QUEUE_TYPEOF(type) *curelm = STAILQ_FIRST(head); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_AFTER(head, curelm, field); \
@@ -349,8 +382,8 @@ struct { \
} while (0)
#define STAILQ_SWAP(head1, head2, type) do { \
- struct type *swap_first = STAILQ_FIRST(head1); \
- struct type **swap_last = (head1)->stqh_last; \
+ QUEUE_TYPEOF(type) *swap_first = STAILQ_FIRST(head1); \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->stqh_last; \
STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_FIRST(head2) = swap_first; \
@@ -370,6 +403,11 @@ struct name { \
struct type *lh_first; /* first element */ \
}
+#define LIST_CLASS_HEAD(name, type) \
+struct name { \
+ class type *lh_first; /* first element */ \
+}
+
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
@@ -379,6 +417,12 @@ struct { \
struct type **le_prev; /* address of previous next element */ \
}
+#define LIST_CLASS_ENTRY(type) \
+struct { \
+ class type *le_next; /* next element */ \
+ class type **le_prev; /* address of previous next element */ \
+}
+
/*
* List functions.
*/
@@ -463,9 +507,10 @@ struct { \
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-#define LIST_PREV(elm, head, type, field) \
- ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
- __containerof((elm)->field.le_prev, struct type, field.le_next))
+#define LIST_PREV(elm, head, type, field) \
+ ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \
+ __containerof((elm)->field.le_prev, \
+ QUEUE_TYPEOF(type), field.le_next))
#define LIST_REMOVE(elm, field) do { \
QMD_SAVELINK(oldnext, (elm)->field.le_next); \
@@ -481,7 +526,7 @@ struct { \
} while (0)
#define LIST_SWAP(head1, head2, type, field) do { \
- struct type *swap_tmp = LIST_FIRST((head1)); \
+ QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
LIST_FIRST((head2)) = swap_tmp; \
if ((swap_tmp = LIST_FIRST((head1))) != NULL) \
@@ -500,6 +545,13 @@ struct name { \
TRACEBUF \
}
+#define TAILQ_CLASS_HEAD(name, type) \
+struct name { \
+ class type *tqh_first; /* first element */ \
+ class type **tqh_last; /* addr of last next element */ \
+ TRACEBUF \
+}
+
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first, TRACEBUF_INITIALIZER }
@@ -510,6 +562,13 @@ struct { \
TRACEBUF \
}
+#define TAILQ_CLASS_ENTRY(type) \
+struct { \
+ class type *tqe_next; /* next element */ \
+ class type **tqe_prev; /* address of previous next element */ \
+ TRACEBUF \
+}
+
/*
* Tail queue functions.
*/
@@ -680,8 +739,8 @@ struct { \
} while (0)
#define TAILQ_SWAP(head1, head2, type, field) do { \
- struct type *swap_first = (head1)->tqh_first; \
- struct type **swap_last = (head1)->tqh_last; \
+ QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
+ QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
(head1)->tqh_first = (head2)->tqh_first; \
(head1)->tqh_last = (head2)->tqh_last; \
(head2)->tqh_first = swap_first; \
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 8/8] Renumber copyright clause 4
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
` (5 preceding siblings ...)
2017-04-04 10:00 ` [PATCH v2 4/8] Make the <sys/queue.h> fully usable within C++ Sebastian Huber
@ 2017-04-04 10:00 ` Sebastian Huber
2017-04-04 10:18 ` [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Corinna Vinschen
7 siblings, 0 replies; 9+ messages in thread
From: Sebastian Huber @ 2017-04-04 10:00 UTC (permalink / raw)
To: newlib
From: imp <imp@FreeBSD.org>
Renumber cluase 4 to 3, per what everybody else did when BSD granted
them permission to remove clause 3. My insistance on keeping the same
numbering for legal reasons is too pedantic, so give up on that point.
Submitted by: Jan Schaumann <jschauma@stevens.edu>
Pull Request: https://github.com/freebsd/freebsd/pull/96
---
newlib/libc/include/sys/queue.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/newlib/libc/include/sys/queue.h b/newlib/libc/include/sys/queue.h
index 6cae4c1..491bdde 100644
--- a/newlib/libc/include/sys/queue.h
+++ b/newlib/libc/include/sys/queue.h
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
--
1.8.4.5
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3)
2017-04-04 10:00 [PATCH v2 1/8] Add new FOREACH_FROM variants for queue(3) Sebastian Huber
` (6 preceding siblings ...)
2017-04-04 10:00 ` [PATCH v2 8/8] Renumber copyright clause 4 Sebastian Huber
@ 2017-04-04 10:18 ` Corinna Vinschen
7 siblings, 0 replies; 9+ messages in thread
From: Corinna Vinschen @ 2017-04-04 10:18 UTC (permalink / raw)
To: newlib
[-- Attachment #1: Type: text/plain, Size: 531 bytes --]
On Apr 4 12:00, Sebastian Huber wrote:
> From: lstewart <lstewart@FreeBSD.org>
>
> Add new FOREACH_FROM variants of the queue(3) FOREACH macros which can
> optionally start the traversal from a previously found element by
> passing the element in as "var". Passing a NULL "var" retains the same
> semantics as the regular FOREACH macros.
>
> Kudos to phk for suggesting the "FROM" suffix instead of my original
> proposal.
Patchset pushed.
Thanks,
Corinna
--
Corinna Vinschen
Cygwin Maintainer
Red Hat
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread