ソースを参照

二叉搜索树: create、 insert

fslongjin 2 年 前
コミット
eead936244
5 ファイル変更188 行追加12 行削除
  1. 5 2
      kernel/common/Makefile
  2. 118 0
      kernel/common/bitree.c
  3. 54 0
      kernel/common/bitree.h
  4. 7 0
      kernel/debug/bug.h
  5. 4 10
      kernel/driver/usb/xhci/xhci.c

+ 5 - 2
kernel/common/Makefile

@@ -3,7 +3,7 @@ CFLAGS += -I .
 
 kernel_common_subdirs:=libELF math
 
-all: glib.o printk.o cpu.o
+all: glib.o printk.o cpu.o bitree.o
 	@list='$(kernel_common_subdirs)'; for subdir in $$list; do \
     		echo "make all in $$subdir";\
     		cd $$subdir;\
@@ -18,4 +18,7 @@ printk.o: printk.c
 	gcc $(CFLAGS) -c printk.c -o printk.o
 
 cpu.o: cpu.c
-	gcc $(CFLAGS) -c cpu.c -o cpu.o
+	gcc $(CFLAGS) -c cpu.c -o cpu.o
+
+bitree.o: bitree.c
+	gcc $(CFLAGS) -c bitree.c -o bitree.o

+ 118 - 0
kernel/common/bitree.c

@@ -0,0 +1,118 @@
+#include "bitree.h"
+#include <mm/slab.h>
+#include <common/errno.h>
+#include <debug/bug.h>
+
+#define smaller(root, a, b) (root->cmp(a, b) == -1)
+#define equal(root, a, b) (root->cmp(a, b) == 0)
+#define greater(root, a, b) (root->cmp(a, b) == 1)
+
+/**
+ * @brief 创建二叉搜索树
+ *
+ * @param node 根节点
+ * @param cmp 比较函数
+ * @return struct bt_root_t* 树根结构体
+ */
+struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(struct bt_node_t *a, struct bt_node_t *b))
+{
+    if (node == NULL || cmp == NULL)
+        return -EINVAL;
+
+    struct bt_root_t *root = (struct bt_root_t *)kmalloc(sizeof(struct bt_root_t), 0);
+    memset((void *)root, 0, sizeof(struct bt_root_t));
+    root->bt_node = node;
+    root->cmp = cmp;
+
+    return root;
+}
+
+/**
+ * @brief 创建结点
+ *
+ * @param left 左子节点
+ * @param right 右子节点
+ * @param value 当前节点的值
+ * @return struct bt_node_t*
+ */
+struct bt_node_t *bt_create_node(struct bt_node_t *left, struct bt_node_t *right, struct bt_node_t *parent, void *value)
+{
+    struct bt_node_t *node = (struct bt_node_t *)kmalloc(sizeof(struct bt_node_t), 0);
+    FAIL_ON_TO(node == NULL, nomem);
+    memset((void *)node, 0, sizeof(struct bt_node_t));
+
+    node->left = left;
+    node->right = right;
+    node->value = value;
+    node->parent = parent;
+
+    return node;
+nomem:;
+    return -ENOMEM;
+}
+/**
+ * @brief 插入结点
+ *
+ * @param root 树根结点
+ * @param value 待插入结点的值
+ * @return int 返回码
+ */
+int bt_insert(struct bt_root_t *root, void *value)
+{
+    if (root == NULL)
+        return -EINVAL;
+
+    struct bt_node_t *this_node = root->bt_node;
+    struct bt_node_t *last_node = NULL;
+    struct bt_node_t *insert_node = bt_create_node(NULL, NULL, NULL, value);
+    FAIL_ON_TO((uint64_t)insert_node == (uint64_t)(-ENOMEM), failed);
+
+    while (this_node != NULL)
+    {
+        last_node = this_node;
+        if (smaller(root, insert_node, this_node))
+            this_node = this_node->left;
+        else
+            this_node = this_node->right;
+    }
+
+    insert_node->parent = last_node;
+    if (unlikely(last_node == NULL))
+        root->bt_node = insert_node;
+    else
+    {
+        if (smaller(root, insert_node, last_node))
+            last_node->left = insert_node;
+        else
+            last_node->right = insert_node;
+    }
+
+    return 0;
+
+failed:;
+    return -ENOMEM;
+}
+
+/**
+ * @brief 搜索值为value的结点
+ *
+ * @param value 值
+ * @param ret_addr 返回的结点基地址
+ * @return int 错误码
+ */
+int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr)
+{
+    struct bt_node_t *this_node = root->bt_node;
+    struct bt_node_t tmp_node = {0};
+    tmp_node.value = value;
+    while (this_node != NULL && !equal(root, &this_node, &tmp_node))
+    {
+        if (smaller(root, &tmp_node, this_node))
+            this_node = this_node->left;
+        else
+            this_node = this_node->right;
+    }
+
+    *ret_addr = (uint64_t)ret_addr;
+    return 0;
+}

+ 54 - 0
kernel/common/bitree.h

@@ -0,0 +1,54 @@
+#pragma once
+
+struct bt_node_t
+{
+    struct bt_node_t *left;
+    struct bt_node_t *right;
+    struct bt_node_t *parent;
+    void *value; // 数据
+
+} __attribute__((aligned(sizeof(long))));
+
+struct bt_root_t
+{
+    struct bt_node_t *bt_node;
+    int (*cmp)(struct bt_node_t *a, struct bt_node_t *b); // 比较函数   a>b 返回1, a==b返回0, a<b返回-1
+};
+
+/**
+ * @brief 创建二叉搜索树
+ *
+ * @param node 根节点
+ * @param cmp 比较函数
+ * @return struct bt_root_t* 树根结构体
+ */
+struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(struct bt_node_t *a, struct bt_node_t *b));
+
+/**
+ * @brief 创建结点
+ *
+ * @param left 左子节点
+ * @param right 右子节点
+ * @param value 当前节点的值
+ * @return struct bt_node_t*
+ */
+struct bt_node_t *bt_create_node(struct bt_node_t *left, struct bt_node_t *right, struct bt_node_t *parent, void *value);
+
+/**
+ * @brief 插入结点
+ *
+ * @param root 树根结点
+ * @param value 待插入结点的值
+ * @return int 返回码
+ */
+int bt_insert(struct bt_root_t *root, void *value);
+
+/**
+ * @brief 搜索值为value的结点
+ *
+ * @param root 树根结点
+ * @param value 值
+ * @param ret_addr 返回的结点基地址
+ * @return int 错误码
+ */
+int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr);

+ 7 - 0
kernel/debug/bug.h

@@ -12,3 +12,10 @@
         kwarn("Assertion failed at %s:%d", __FILE__, __LINE__); \
     unlikely(__ret_warn_on);                                    \
 })
+
+#define FAIL_ON_TO(condition, to) ({   \
+    int __ret_warn_on = !!(condition); \
+    if (unlikely(__ret_warn_on))       \
+        goto to;                       \
+    unlikely(__ret_warn_on);           \
+})

+ 4 - 10
kernel/driver/usb/xhci/xhci.c

@@ -123,12 +123,6 @@ hardware_intr_controller xhci_hc_intr_controller =
         ptr->cycle = 1;                                                        \
     } while (0)
 
-#define FAIL_ON(value, to)        \
-    do                            \
-    {                             \
-        if (unlikely(value != 0)) \
-            goto to;              \
-    } while (0)
 
 // Common TRB types
 enum
@@ -854,12 +848,12 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
     }
 
     // 关闭legacy支持
-    FAIL_ON(xhci_hc_stop_legacy(cid), failed);
+    FAIL_ON_TO(xhci_hc_stop_legacy(cid), failed);
 
     // 重置xhci控制器
-    FAIL_ON(xhci_hc_reset(cid), failed);
+    FAIL_ON_TO(xhci_hc_reset(cid), failed);
     // 端口配对
-    FAIL_ON(xhci_hc_pair_ports(cid), failed);
+    FAIL_ON_TO(xhci_hc_pair_ports(cid), failed);
 
     // ========== 设置USB host controller =========
     // 获取页面大小
@@ -900,7 +894,7 @@ void xhci_init(struct pci_device_structure_general_device_t *dev_hdr)
     // 写入设备通知控制寄存器
     xhci_write_op_reg32(cid, XHCI_OPS_DNCTRL, (1 << 1)); // 目前只有N1被支持
 
-    FAIL_ON(xhci_hc_init_intr(cid), failed_free_dyn);
+    FAIL_ON_TO(xhci_hc_init_intr(cid), failed_free_dyn);
     ++xhci_ctrl_count;
     spin_unlock(&xhci_controller_init_lock);
     return;