Merge branch 'master' into prog-loader
[lunaix-os.git] / lunaix-os / includes / lunaix / ds / llist.h
index effee950b376a16ea01f1626f64684516bf9d405..65ba474d750328d80ff3c08eba0611c9cb076f30 100644 (file)
@@ -1,12 +1,13 @@
 /**
  * @file llist.h
  * @author Lunaixsky
- * @brief This doubly linked cyclic list is adopted from Linux kernel <linux/list.h>
+ * @brief This doubly linked cyclic list is adopted from Linux kernel
+ * <linux/list.h>
  * @version 0.1
  * @date 2022-03-12
- * 
+ *
  * @copyright Copyright (c) 2022
- * 
+ *
  */
 #ifndef __LUNAIX_LLIST_H
 #define __LUNAIX_LLIST_H
@@ -31,7 +32,8 @@ __llist_add(struct llist_header* elem,
 }
 
 static inline void
-llist_init_head(struct llist_header* head) {
+llist_init_head(struct llist_header* head)
+{
     head->next = head;
     head->prev = head;
 }
@@ -39,33 +41,51 @@ llist_init_head(struct llist_header* head) {
 static inline void
 llist_append(struct llist_header* head, struct llist_header* elem)
 {
-    __llist_add(elem, head, head->next);
+    __llist_add(elem, head->prev, head);
 }
 
 static inline void
 llist_prepend(struct llist_header* head, struct llist_header* elem)
 {
-    __llist_add(elem, head->prev, head);
+    __llist_add(elem, head, head->next);
 }
 
 static inline void
-llist_delete(struct llist_header* elem) {
+llist_insert_after(struct llist_header* head, struct llist_header* elem)
+{
+    __llist_add(elem, head, head->next);
+}
+
+static inline void
+llist_delete(struct llist_header* elem)
+{
     elem->prev->next = elem->next;
-    elem->next->prev = elem->next;
-    
+    elem->next->prev = elem->prev;
+
     // make elem orphaned
     elem->prev = elem;
     elem->next = elem;
 }
 
+static inline int
+llist_empty(struct llist_header* elem)
+{
+    return elem->next == elem && elem->prev == elem;
+}
+
+#define DEFINE_LLIST(name)                                                     \
+    struct llist_header name = (struct llist_header)                           \
+    {                                                                          \
+        .prev = &name, .next = &name                                           \
+    }
+
 /**
  * list_entry - get the struct for this entry
  * @ptr:       the &struct list_head pointer.
  * @type:      the type of the struct this is embedded in.
  * @member:    the name of the list_struct within the struct.
  */
-#define list_entry(ptr, type, member) \
-       container_of(ptr, type, member)
+#define list_entry(ptr, type, member) container_of(ptr, type, member)
 
 /**
  * list_for_each_entry -       iterate over list of given type
@@ -73,10 +93,35 @@ llist_delete(struct llist_header* elem) {
  * @head:      the head for your list.
  * @member:    the name of the list_struct within the struct.
  */
-#define llist_for_each(pos, n, head, member)                               \
-       for (pos = list_entry((head)->next, typeof(*pos), member),      \
-               n = list_entry(pos->member.next, typeof(*pos), member); \
-            &pos->member != (head);                                                \
-            pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#define llist_for_each(pos, n, head, member)                                   \
+    for (pos = list_entry((head)->next, typeof(*pos), member),                 \
+        n = list_entry(pos->member.next, typeof(*pos), member);                \
+         &pos->member != (head);                                               \
+         pos = n, n = list_entry(n->member.next, typeof(*n), member))
 
+struct hlist_node
+{
+    struct hlist_node *next, **pprev;
+};
+
+static inline void
+hlist_delete(struct hlist_node* node)
+{
+    if (!node->pprev)
+        return;
+    *node->pprev = node->next;
+    node->next = 0;
+    node->pprev = 0;
+}
+
+static inline void
+hlist_add(struct hlist_node** head, struct hlist_node* node)
+{
+    node->next = *head;
+    if (*head) {
+        (*head)->pprev = &node->next;
+    }
+    node->pprev = head;
+    *head = node;
+}
 #endif /* __LUNAIX_LLIST_H */