changeset 20688:302d3c7312e1 draft

list: use ilist to implement the list API
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Sun, 22 Mar 2020 10:48:33 -0400
parents ac1492488560
children 35776ed29134
files usr/src/common/list/list.c
diffstat 1 files changed, 50 insertions(+), 75 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/common/list/list.c	Sun Mar 22 10:48:20 2020 -0400
+++ b/usr/src/common/list/list.c	Sun Mar 22 10:48:33 2020 -0400
@@ -28,6 +28,7 @@
 
 #include <sys/list.h>
 #include <sys/list_impl.h>
+#include <sys/ilist.h>
 #include <sys/types.h>
 #include <sys/sysmacros.h>
 #ifdef _KERNEL
@@ -37,31 +38,26 @@
 #define	ASSERT(a)	assert(a)
 #endif
 
-#define	list_d2l(a, obj) ((list_node_t *)(((char *)obj) + (a)->list_offset))
-#define	list_object(a, node) ((void *)(((char *)node) - (a)->list_offset))
-#define	list_empty(a) ((a)->list_head.list_next == &(a)->list_head)
+static inline void *node2object(struct list *list, struct list_node *node)
+{
+	uintptr_t naddr = (uintptr_t)node;
 
-#define	list_insert_after_node(list, node, object) {	\
-	list_node_t *lnew = list_d2l(list, object);	\
-	lnew->list_prev = (node);			\
-	lnew->list_next = (node)->list_next;		\
-	(node)->list_next->list_prev = lnew;		\
-	(node)->list_next = lnew;			\
+	if (naddr == 0)
+		return NULL;
+
+	return (void *)(naddr - list->list_offset);
 }
 
-#define	list_insert_before_node(list, node, object) {	\
-	list_node_t *lnew = list_d2l(list, object);	\
-	lnew->list_next = (node);			\
-	lnew->list_prev = (node)->list_prev;		\
-	(node)->list_prev->list_next = lnew;		\
-	(node)->list_prev = lnew;			\
+static inline struct list_node *object2node(struct list *list, void *obj)
+{
+	uintptr_t oaddr = (uintptr_t)obj;
+
+	if (oaddr == 0)
+		return NULL;
+
+	return (struct list_node *)(oaddr + list->list_offset);
 }
 
-#define	list_remove_node(node)					\
-	(node)->list_prev->list_next = (node)->list_next;	\
-	(node)->list_next->list_prev = (node)->list_prev;	\
-	(node)->list_next = (node)->list_prev = NULL
-
 void
 list_create(list_t *list, size_t size, size_t offset)
 {
@@ -71,8 +67,7 @@
 
 	list->list_size = size;
 	list->list_offset = offset;
-	list->list_head.list_next = list->list_head.list_prev =
-	    &list->list_head;
+	ilist_init(&list->list_head);
 }
 
 void
@@ -81,8 +76,7 @@
 	list_node_t *node = &list->list_head;
 
 	ASSERT(list);
-	ASSERT(list->list_head.list_next == node);
-	ASSERT(list->list_head.list_prev == node);
+	ASSERT(ilist_is_empty(node));
 
 	node->list_next = node->list_prev = NULL;
 }
@@ -90,104 +84,85 @@
 void
 list_insert_after(list_t *list, void *object, void *nobject)
 {
-	if (object == NULL) {
-		list_insert_head(list, nobject);
-	} else {
-		list_node_t *lold = list_d2l(list, object);
-		list_insert_after_node(list, lold, nobject);
-	}
+	if (object == NULL)
+		ilist_insert_head(&list->list_head,
+				  object2node(list, nobject));
+	else
+		ilist_insert_after(object2node(list, object),
+				   object2node(list, nobject));
 }
 
 void
 list_insert_before(list_t *list, void *object, void *nobject)
 {
-	if (object == NULL) {
-		list_insert_tail(list, nobject);
-	} else {
-		list_node_t *lold = list_d2l(list, object);
-		list_insert_before_node(list, lold, nobject);
-	}
+	if (object == NULL)
+		ilist_insert_tail(&list->list_head,
+				  object2node(list, nobject));
+	else
+		ilist_insert_before(object2node(list, object),
+				    object2node(list, nobject));
 }
 
 void
 list_insert_head(list_t *list, void *object)
 {
-	list_node_t *lold = &list->list_head;
-	list_insert_after_node(list, lold, object);
+	ilist_insert_head(&list->list_head,
+			  object2node(list, object));
 }
 
 void
 list_insert_tail(list_t *list, void *object)
 {
-	list_node_t *lold = &list->list_head;
-	list_insert_before_node(list, lold, object);
+	ilist_insert_tail(&list->list_head,
+			  object2node(list, object));
 }
 
 void
 list_remove(list_t *list, void *object)
 {
-	list_node_t *lold = list_d2l(list, object);
-	ASSERT(!list_empty(list));
-	ASSERT(lold->list_next != NULL);
-	list_remove_node(lold);
+	struct list_node *node = object2node(list, object);
+
+	ASSERT(!ilist_is_empty(&list->list_head));
+	ASSERT(ilist_link_active(node));
+	ilist_remove(node);
 }
 
 void *
 list_remove_head(list_t *list)
 {
-	list_node_t *head = list->list_head.list_next;
-	if (head == &list->list_head)
-		return (NULL);
-	list_remove_node(head);
-	return (list_object(list, head));
+	return node2object(list, ilist_remove_head(&list->list_head));
 }
 
 void *
 list_remove_tail(list_t *list)
 {
-	list_node_t *tail = list->list_head.list_prev;
-	if (tail == &list->list_head)
-		return (NULL);
-	list_remove_node(tail);
-	return (list_object(list, tail));
+	return node2object(list, ilist_remove_tail(&list->list_head));
 }
 
 void *
 list_head(list_t *list)
 {
-	if (list_empty(list))
-		return (NULL);
-	return (list_object(list, list->list_head.list_next));
+	return node2object(list, ilist_head(&list->list_head));
 }
 
 void *
 list_tail(list_t *list)
 {
-	if (list_empty(list))
-		return (NULL);
-	return (list_object(list, list->list_head.list_prev));
+	return node2object(list, ilist_tail(&list->list_head));
 }
 
 void *
 list_next(list_t *list, void *object)
 {
-	list_node_t *node = list_d2l(list, object);
-
-	if (node->list_next != &list->list_head)
-		return (list_object(list, node->list_next));
-
-	return (NULL);
+	return node2object(list, ilist_next(&list->list_head,
+					    object2node(list, object)));
 }
 
 void *
 list_prev(list_t *list, void *object)
 {
-	list_node_t *node = list_d2l(list, object);
-
-	if (node->list_prev != &list->list_head)
-		return (list_object(list, node->list_prev));
-
-	return (NULL);
+	return node2object(list, ilist_prev(&list->list_head,
+					    object2node(list, object)));
 }
 
 /*
@@ -202,7 +177,7 @@
 	ASSERT(dst->list_size == src->list_size);
 	ASSERT(dst->list_offset == src->list_offset);
 
-	if (list_empty(src))
+	if (ilist_is_empty(&src->list_head))
 		return;
 
 	dstnode->list_prev->list_next = srcnode->list_next;
@@ -237,11 +212,11 @@
 int
 list_link_active(list_node_t *link)
 {
-	return (link->list_next != NULL);
+	return ilist_link_active(link);
 }
 
 int
 list_is_empty(list_t *list)
 {
-	return (list_empty(list));
+	return ilist_is_empty(&list->list_head);
 }