Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F156679585
D49969.id154147.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D49969.id154147.diff
View Options
diff --git a/share/man/man3/queue.3 b/share/man/man3/queue.3
--- a/share/man/man3/queue.3
+++ b/share/man/man3/queue.3
@@ -49,6 +49,7 @@
.Nm SLIST_REMOVE ,
.Nm SLIST_REMOVE_AFTER ,
.Nm SLIST_REMOVE_HEAD ,
+.Nm SLIST_SPLIT_AFTER ,
.Nm SLIST_SWAP ,
.Nm STAILQ_CLASS_ENTRY ,
.Nm STAILQ_CLASS_HEAD ,
@@ -72,6 +73,7 @@
.Nm STAILQ_REMOVE ,
.Nm STAILQ_REMOVE_AFTER ,
.Nm STAILQ_REMOVE_HEAD ,
+.Nm STAILQ_SPLIT_AFTER ,
.Nm STAILQ_SWAP ,
.Nm LIST_CLASS_ENTRY ,
.Nm LIST_CLASS_HEAD ,
@@ -94,6 +96,7 @@
.Nm LIST_PREV ,
.Nm LIST_REMOVE ,
.Nm LIST_REPLACE ,
+.Nm LIST_SPLIT_AFTER ,
.Nm LIST_SWAP ,
.Nm TAILQ_CLASS_ENTRY ,
.Nm TAILQ_CLASS_HEAD ,
@@ -122,6 +125,7 @@
.Nm TAILQ_PREV ,
.Nm TAILQ_REMOVE ,
.Nm TAILQ_REPLACE ,
+.Nm TAILQ_SPLIT_AFTER ,
.Nm TAILQ_SWAP
.Nd implementations of singly-linked lists, singly-linked tail queues,
lists and tail queues
@@ -148,6 +152,7 @@
.Fn SLIST_REMOVE "SLIST_HEAD *head" "TYPE *elm" "TYPE" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE_AFTER "TYPE *elm" "SLIST_ENTRY NAME"
.Fn SLIST_REMOVE_HEAD "SLIST_HEAD *head" "SLIST_ENTRY NAME"
+.Fn SLIST_SPLIT_AFTER "SLIST_HEAD *head" "TYPE *elm" "SLIST_HEAD *rest" "SLIST_ENTRY NAME"
.Fn SLIST_SWAP "SLIST_HEAD *head1" "SLIST_HEAD *head2" "TYPE"
.\"
.Fn STAILQ_CLASS_ENTRY "CLASSTYPE"
@@ -172,6 +177,7 @@
.Fn STAILQ_REMOVE "STAILQ_HEAD *head" "TYPE *elm" "TYPE" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_ENTRY NAME"
.Fn STAILQ_REMOVE_HEAD "STAILQ_HEAD *head" "STAILQ_ENTRY NAME"
+.Fn STAILQ_SPLIT_AFTER "STAILQ_HEAD *head" "TYPE *elm" "STAILQ_HEAD *rest" "STAILQ_ENTRY NAME"
.Fn STAILQ_SWAP "STAILQ_HEAD *head1" "STAILQ_HEAD *head2" "TYPE"
.\"
.Fn LIST_CLASS_ENTRY "CLASSTYPE"
@@ -195,6 +201,7 @@
.Fn LIST_PREV "TYPE *elm" "LIST_HEAD *head" "TYPE" "LIST_ENTRY NAME"
.Fn LIST_REMOVE "TYPE *elm" "LIST_ENTRY NAME"
.Fn LIST_REPLACE "TYPE *elm" "TYPE *new" "LIST_ENTRY NAME"
+.Fn LIST_SPLIT_AFTER "LIST_HEAD *head" "TYPE *elm" "LIST_HEAD *rest" "LIST_ENTRY NAME"
.Fn LIST_SWAP "LIST_HEAD *head1" "LIST_HEAD *head2" "TYPE" "LIST_ENTRY NAME"
.\"
.Fn TAILQ_CLASS_ENTRY "CLASSTYPE"
@@ -224,6 +231,7 @@
.Fn TAILQ_PREV "TYPE *elm" "HEADNAME" "TAILQ_ENTRY NAME"
.Fn TAILQ_REMOVE "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_ENTRY NAME"
.Fn TAILQ_REPLACE "TAILQ_HEAD *head" "TYPE *elm" "TYPE *new" "TAILQ_ENTRY NAME"
+.Fn TAILQ_SPLIT_AFTER "TAILQ_HEAD *head" "TYPE *elm" "TAILQ_HEAD *rest" "TAILQ_ENTRY NAME"
.Fn TAILQ_SWAP "TAILQ_HEAD *head1" "TAILQ_HEAD *head2" "TYPE" "TAILQ_ENTRY NAME"
.\"
.Sh DESCRIPTION
@@ -250,6 +258,8 @@
.It
Forward traversal through the list.
.It
+Splitting a list in two after any element in the list.
+.It
Swapping the contents of two lists.
.El
.Pp
@@ -547,6 +557,17 @@
high-usage code paths or to operate on long lists.
.Pp
The macro
+.Nm SLIST_SPLIT_AFTER
+splits the list referenced by
+.Fa head ,
+making
+.Fa rest
+reference the list formed by elements after
+.Fa elm
+in
+.Fa head .
+.Pp
+The macro
.Nm SLIST_SWAP
swaps the contents of
.Fa head1
@@ -770,6 +791,17 @@
high-usage code paths or to operate on long tail queues.
.Pp
The macro
+.Nm STAILQ_SPLIT_AFTER
+splits the tail queue referenced by
+.Fa head ,
+making
+.Fa rest
+reference the tail queue formed by elements after
+.Fa elm
+in
+.Fa head .
+.Pp
+The macro
.Nm STAILQ_SWAP
swaps the contents of
.Fa head1
@@ -998,6 +1030,17 @@
must not already be on a list.
.Pp
The macro
+.Nm LIST_SPLIT_AFTER
+splits the list referenced by
+.Fa head ,
+making
+.Fa rest
+reference the list formed by elements after
+.Fa elm
+in
+.Fa head .
+.Pp
+The macro
.Nm LIST_SWAP
swaps the contents of
.Fa head1
@@ -1271,6 +1314,17 @@
must not already be on a list.
.Pp
The macro
+.Nm TAILQ_SPLIT_AFTER
+splits the tail queue referenced by
+.Fa head ,
+making
+.Fa rest
+reference the tail queue formed by elements after
+.Fa elm
+in
+.Fa head .
+.Pp
+The macro
.Nm TAILQ_SWAP
swaps the contents of
.Fa head1
diff --git a/sys/sys/queue.h b/sys/sys/queue.h
--- a/sys/sys/queue.h
+++ b/sys/sys/queue.h
@@ -111,6 +111,7 @@
* _REMOVE_HEAD + + + +
* _REMOVE s + s +
* _REPLACE - + - +
+ * _SPLIT_AFTER + + + +
* _SWAP + + + +
*
*/
@@ -202,15 +203,30 @@
* 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)
+
+#define SLIST_ASSERT_EMPTY(head) do { \
+ if (!SLIST_EMPTY((head))) \
+ panic("slist %p is not empty", (head)); \
+} while (0)
+
+#define SLIST_ASSERT_NONEMPTY(head) do { \
+ if (SLIST_EMPTY((head))) \
+ panic("slist %p is empty", (head)); \
+} while (0)
+
#else
#define QMD_SLIST_CHECK_PREVPTR(prevp, elm)
+#define SLIST_ASSERT_EMPTY(head)
+#define SLIST_ASSERT_NONEMPTY(head)
#endif
+
#define SLIST_CONCAT(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *curelm = SLIST_FIRST(head1); \
if (curelm == NULL) { \
@@ -303,6 +319,12 @@
TRASHIT((elm)->field.sle_next); \
} while (0)
+#define SLIST_SPLIT_AFTER(head, elm, rest, field) do { \
+ SLIST_ASSERT_NONEMPTY((head)); \
+ SLIST_FIRST((rest)) = SLIST_NEXT((elm), field); \
+ SLIST_NEXT((elm), field) = NULL; \
+} while (0)
+
#define SLIST_SWAP(head1, head2, type) do { \
QUEUE_TYPEOF(type) *swap_first = SLIST_FIRST(head1); \
SLIST_FIRST(head1) = SLIST_FIRST(head2); \
@@ -577,10 +599,23 @@
if (*(elm)->field.le_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
+
+#define LIST_ASSERT_EMPTY(head) do { \
+ if (!LIST_EMPTY((head))) \
+ panic("list %p is not empty", (head)); \
+} while (0)
+
+#define LIST_ASSERT_NONEMPTY(head) do { \
+ if (LIST_EMPTY((head))) \
+ panic("list %p is empty", (head)); \
+} while (0)
+
#else
#define QMD_LIST_CHECK_HEAD(head, field)
#define QMD_LIST_CHECK_NEXT(elm, field)
#define QMD_LIST_CHECK_PREV(elm, field)
+#define LIST_ASSERT_EMPTY(head)
+#define LIST_ASSERT_NONEMPTY(head)
#endif /* (_KERNEL && INVARIANTS) */
#define LIST_CONCAT(head1, head2, type, field) do { \
@@ -694,6 +729,19 @@
TRASHIT(*oldprev); \
} while (0)
+#define LIST_SPLIT_AFTER(head, elm, rest, field) do { \
+ LIST_ASSERT_NONEMPTY((head)); \
+ if (LIST_NEXT((elm), field) == NULL) \
+ /* 'elm' is the last element in 'head'. */ \
+ LIST_INIT((rest)); \
+ else { \
+ LIST_FIRST((rest)) = LIST_NEXT((elm), field); \
+ LIST_NEXT((elm), field)->field.le_prev = \
+ &LIST_FIRST((rest)); \
+ LIST_NEXT((elm), field) = NULL; \
+ } \
+} while (0)
+
#define LIST_SWAP(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *swap_tmp = LIST_FIRST(head1); \
LIST_FIRST((head1)) = LIST_FIRST((head2)); \
@@ -789,11 +837,24 @@
if (*(elm)->field.tqe_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
+
+#define TAILQ_ASSERT_EMPTY(head) do { \
+ if (!TAILQ_EMPTY((head))) \
+ panic("tailq %p is not empty", (head)); \
+} while (0)
+
+#define TAILQ_ASSERT_NONEMPTY(head) do { \
+ if (TAILQ_EMPTY((head))) \
+ panic("tailq %p is empty", (head)); \
+} while (0)
+
#else
#define QMD_TAILQ_CHECK_HEAD(head, field)
#define QMD_TAILQ_CHECK_TAIL(head, headname)
#define QMD_TAILQ_CHECK_NEXT(elm, field)
#define QMD_TAILQ_CHECK_PREV(elm, field)
+#define TAILQ_ASSERT_EMPTY(head)
+#define TAILQ_ASSERT_NONEMPTY(head)
#endif /* (_KERNEL && INVARIANTS) */
#define TAILQ_CONCAT(head1, head2, field) do { \
@@ -969,6 +1030,23 @@
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
+#define TAILQ_SPLIT_AFTER(head, elm, rest, field) do { \
+ TAILQ_ASSERT_NONEMPTY((head)); \
+ QMD_TAILQ_CHECK_TAIL((head), field); \
+ if (TAILQ_NEXT((elm), field) == NULL) \
+ /* 'elm' is the last element in 'head'. */ \
+ TAILQ_INIT((rest)); \
+ else { \
+ TAILQ_FIRST((rest)) = TAILQ_NEXT((elm), field); \
+ (rest)->tqh_last = (head)->tqh_last; \
+ TAILQ_NEXT((elm), field)->field.tqe_prev = \
+ &TAILQ_FIRST((rest)); \
+ \
+ TAILQ_NEXT((elm), field) = NULL; \
+ (head)->tqh_last = &TAILQ_NEXT((elm), field); \
+ } \
+} while (0)
+
#define TAILQ_SWAP(head1, head2, type, field) do { \
QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \
QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, May 16, 3:40 PM (52 m, 53 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33135327
Default Alt Text
D49969.id154147.diff (8 KB)
Attached To
Mode
D49969: queue: New *_SPLIT_AFTER(), *_ASSERT_EMPTY(), *_ASSERT_NONEMPTY()
Attached
Detach File
Event Timeline
Log In to Comment