[virglrenderer-devel] [PATCH 1/5] utils: added intrusive linked-list implem

Nathan Gauer nathan at gauer.org
Tue Jul 24 13:32:09 UTC 2018


Signed-off-by: Nathan Gauer <nathan at gauer.org>
---
 src/util/list.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/list.h | 31 ++++++++++++++++++++
 2 files changed, 106 insertions(+)
 create mode 100644 src/util/list.c
 create mode 100644 src/util/list.h

diff --git a/src/util/list.c b/src/util/list.c
new file mode 100644
index 0000000..d214aef
--- /dev/null
+++ b/src/util/list.c
@@ -0,0 +1,75 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include "list.h"
+
+void list_init(struct list *head)
+{
+    head->next = head;
+    head->prev = head;
+}
+
+size_t list_length(struct list *head)
+{
+    size_t len = 0;
+    struct list *n = head->next;
+
+    for (; n != head; n = n->next) {
+        len += 1;
+    }
+
+    return len;
+}
+
+void list_append(struct list *head, struct list *n)
+{
+    assert(head && "invalid list pointer");
+    assert(n && "invalid elt pointer");
+
+
+    n->next = head;
+    n->prev = head->prev;
+    n->prev->next = n;
+    head->prev = n;
+}
+
+void list_insert(struct list *head, struct list *n, size_t pos)
+{
+    assert(head && "invalid list pointer");
+    assert(n && "invalid elt pointer");
+
+    struct list *it = head->next;
+    for (; pos > 0; pos--) {
+        if (it == head)
+            break;
+
+        it = it->next;
+    }
+
+    n->prev = it->prev;
+    n->next = it;
+    n->prev->next = n;
+    it->prev = n;
+}
+
+int list_remove(struct list *head, size_t pos)
+{
+    assert(head && "invalid list pointer");
+
+    struct list *it = head->next;
+
+    for (; pos > 0; pos--) {
+        it = it->next;
+
+        if (it == head)
+            return 1;
+    }
+
+    it->prev->next = it->next;
+    it->next->prev = it->prev;
+
+    it->next = it;
+    it->prev = it;
+
+    return 0;
+}
diff --git a/src/util/list.h b/src/util/list.h
new file mode 100644
index 0000000..c9269aa
--- /dev/null
+++ b/src/util/list.h
@@ -0,0 +1,31 @@
+#pragma once
+
+#include "stddef.h"
+
+struct list {
+    struct list *next;
+    struct list *prev;
+};
+
+
+#define LIST_FOR_EACH(Var, List, Field) \
+    for (Var = CONTAINER_OF(List.next, typeof(*Var), Field) ; \
+         &(Var->Field) != &List; \
+         Var = CONTAINER_OF(Var->Field.next, typeof(*Var), Field))
+
+#define CONTAINER_OF(List, Type, Field) \
+    (Type*)((char*)List - offsetof(Type, Field))
+
+
+#define LIST_FRONT(Var, List, Field) \
+    it = CONTAINER_OF(List.next, typeof(*Var), Field)
+
+#define LIST_BACK(Var, List, Field) \
+    it = CONTAINER_OF(List.prev, typeof(*Var), Field)
+
+void list_init(struct list *head);
+
+size_t  list_length(struct list *head);
+void    list_append(struct list *head, struct list *n);
+void    list_insert(struct list *head, struct list *n, size_t pos);
+int     list_remove(struct list *head, size_t pos);
-- 
2.18.0



More information about the virglrenderer-devel mailing list