bitree的单元测试以及bug修复

This commit is contained in:
fslongjin 2022-07-26 15:44:01 +08:00
parent 992f292f89
commit 494bcc1811
7 changed files with 167 additions and 19 deletions

View File

@ -3,9 +3,9 @@
#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)
#define smaller(root, a, b) (root->cmp((a)->value, (b)->value) == -1)
#define equal(root, a, b) (root->cmp((a)->value, (b)->value) == 0)
#define greater(root, a, b) (root->cmp((a)->value, (b)->value) == 1)
/**
* @brief
@ -15,7 +15,7 @@
* @param release value的函数
* @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), int (*release)(void *value))
struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value))
{
if (node == NULL || cmp == NULL)
return -EINVAL;
@ -109,6 +109,10 @@ int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr)
struct bt_node_t tmp_node = {0};
tmp_node.value = value;
// 如果返回地址为0
if (ret_addr == NULL)
return -EINVAL;
while (this_node != NULL && !equal(root, this_node, &tmp_node))
{
if (smaller(root, &tmp_node, this_node))
@ -117,7 +121,7 @@ int bt_query(struct bt_root_t *root, void *value, uint64_t *ret_addr)
this_node = this_node->right;
}
if (equal(root, this_node, &tmp_node))
if (this_node != NULL && equal(root, this_node, &tmp_node))
{
*ret_addr = (uint64_t)this_node;
return 0;

View File

@ -13,8 +13,8 @@ struct bt_node_t
struct bt_root_t
{
struct bt_node_t *bt_node;
int32_t size; // 树中的元素个数
int (*cmp)(struct bt_node_t *a, struct bt_node_t *b); // 比较函数 a>b 返回1 a==b返回0, a<b返回-1
int32_t size; // 树中的元素个数
int (*cmp)(void *a, void *b); // 比较函数 a>b 返回1 a==b返回0, a<b返回-1
/**
* @brief value的函数
* @param value
@ -30,7 +30,7 @@ struct bt_root_t
* @param release value的函数
* @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), int (*release)(void *value));
struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value));
/**
* @brief

View File

@ -9,7 +9,7 @@
#include <exception/irq.h>
#include <driver/interrupt/apic/apic.h>
spinlock_t xhci_controller_init_lock; // xhci控制器初始化锁(在usb_init中被初始化)
spinlock_t xhci_controller_init_lock = {0}; // xhci控制器初始化锁(在usb_init中被初始化)
static int xhci_ctrl_count = 0; // xhci控制器计数
@ -123,7 +123,6 @@ hardware_intr_controller xhci_hc_intr_controller =
ptr->cycle = 1; \
} while (0)
// Common TRB types
enum
{
@ -381,7 +380,7 @@ static int xhci_hc_pair_ports(int id)
uint32_t next_off = xhci_hc[id].ext_caps_off;
uint32_t offset, cnt;
uint16_t protocol_flags;
uint16_t protocol_flags = 0;
// 寻找所有的usb2端口
while (next_off)
@ -554,12 +553,12 @@ uint64_t xhci_hc_irq_install(uint64_t irq_num, void *arg)
struct msi_desc_t msi_desc;
memset(&msi_desc, 0, sizeof(struct msi_desc_t));
msi_desc.pci_dev = (struct pci_device_structure_header_t*)xhci_hc[cid].pci_dev_hdr;
msi_desc.pci_dev = (struct pci_device_structure_header_t *)xhci_hc[cid].pci_dev_hdr;
msi_desc.assert = info->assert;
msi_desc.edge_trigger = info->edge_trigger;
msi_desc.processor = info->processor;
msi_desc.pci.msi_attribute.is_64 = 1;
// todo: QEMU是使用msix的因此要先在pci中实现msix
// todo: QEMU是使用msix的因此要先在pci中实现msix
int retval = pci_enable_msi(&msi_desc);
kdebug("pci retval = %d", retval);
kdebug("xhci irq %d installed.", irq_num);
@ -637,7 +636,7 @@ static int xhci_reset_port(const int id, const int port)
break;
else if (val & (1 << 21))
break;
--timeout;
usleep(500);
}

132
kernel/ktest/test-bitree.c Normal file
View File

@ -0,0 +1,132 @@
#include "ktest.h"
#include <ktest/ktest_utils.h>
#include <common/unistd.h>
#include <common/kprint.h>
#include <common/bitree.h>
#include <common/errno.h>
#include <mm/slab.h>
struct test_value_t
{
uint64_t tv;
};
static int compare(void *a, void *b)
{
if (((struct test_value_t *)a)->tv > ((struct test_value_t *)b)->tv)
return 1;
else if (((struct test_value_t *)a)->tv == ((struct test_value_t *)b)->tv)
return 0;
else
return -1;
}
static int release(void *value)
{
// kdebug("release");
}
/**
* @brief
*
* @return int
*/
static long ktest_bitree_case1(uint64_t arg0, uint64_t arg1)
{
int val;
// ========== 测试创建树
struct test_value_t *tv1 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
tv1->tv = 20;
struct bt_node_t *rn = bt_create_node(NULL, NULL, NULL, tv1);
assert(rn != NULL);
assert((int64_t)rn != (-EINVAL));
assert(rn->value == tv1);
struct bt_root_t *tree = bt_create_tree(rn, compare, release);
assert(tree != NULL);
assert(tree->bt_node == rn);
assert(tree->cmp == compare);
assert(tree->release == release);
assert(tree->size == 1);
// ========= 向树中插入数据10、30
struct test_value_t *tv2 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
assert(tv2 != NULL);
tv2->tv = 10;
{
int last_size = tree->size;
val = bt_insert(tree, tv2);
assert(val == 0);
assert(last_size + 1 == tree->size);
}
struct test_value_t *tv3 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
assert(tv3 != NULL);
tv3->tv = 30;
{
int last_size = tree->size;
val = bt_insert(tree, tv3);
assert(val == 0);
assert(last_size + 1 == tree->size);
}
// 检测树的形状
assert(((struct test_value_t *)tree->bt_node->left->value)->tv == tv2->tv);
assert(((struct test_value_t *)tree->bt_node->right->value)->tv == tv3->tv);
// ========= 查询结点
// 查询值为tv2的结点
struct bt_node_t *node2;
assert(bt_query(tree, tv2, (uint64_t*)(&node2)) == 0);
assert(node2 != NULL);
assert(node2->value == tv2);
// ========= 插入第4个结点15
struct test_value_t *tv4 = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
assert(tv4 != NULL);
tv4->tv = 15;
{
int last_size = tree->size;
val = bt_insert(tree, tv4);
assert(val == 0);
assert(last_size + 1 == tree->size);
}
assert(((struct test_value_t *)node2->right->value)->tv == tv4->tv);
// ======= 查询不存在的值
struct bt_node_t *node_not_exists;
struct test_value_t *tv_not_exists = (struct test_value_t *)kmalloc(sizeof(struct test_value_t), 0);
assert(tv_not_exists != NULL);
tv_not_exists->tv = 100;
assert(bt_query(tree, tv_not_exists, (uint64_t*)(&node_not_exists)) == -1);
// kdebug("node_not_exists.val=%d", ((struct test_value_t*)node_not_exists->value)->tv);
assert(node_not_exists == NULL);
// 删除根节点
assert(bt_delete(tree, rn->value) == 0);
assert(((struct test_value_t *)tree->bt_node->value)->tv != 20);
assert(tree->bt_node->right == NULL);
// 删除树
assert(bt_destroy_tree(tree) == 0);
return 0;
}
static ktest_case_table kt_bitree_func_table[] = {
ktest_bitree_case1,
};
uint64_t ktest_test_bitree(uint64_t arg)
{
kTEST("Testing bitree...");
for (int i = 0; i < sizeof(kt_bitree_func_table) / sizeof(ktest_case_table); ++i)
{
kTEST("Testing case %d", i);
kt_bitree_func_table[i](0, 0);
}
kdebug("bitree Test done.");
return 0;
}

View File

@ -641,7 +641,7 @@ int mm_map_proc_page_table(ul proc_page_table_addr, bool is_phys, ul virt_addr_s
{
if (unlikely(*pde_ptr != 0 && user))
{
kwarn("page already mapped!");
// kwarn("page already mapped!");
// 如果是用户态可访问的页,则释放当前新获取的物理页
if (likely(((ul)phys_addr_start + length_mapped) < total_2M_pages)) // 校验是否为内存中的物理页
free_pages(Phy_to_2M_Page((ul)phys_addr_start + length_mapped), 1);

View File

@ -15,6 +15,7 @@
#include <syscall/syscall_num.h>
#include <sched/sched.h>
#include <ktest/ktest.h>
spinlock_t process_global_pid_write_lock; // 增加pid的写锁
long process_global_pid = 1; // 系统中最大的pid
@ -385,7 +386,7 @@ ul do_execve(struct pt_regs *regs, char *path, char *argv[], char *envp[])
regs->rdi = argc;
regs->rsi = (uint64_t)dst_argv;
}
kdebug("execve ok");
// kdebug("execve ok");
regs->cs = USER_CS | 3;
regs->ds = USER_DS | 3;
@ -413,7 +414,8 @@ ul initial_kernel_thread(ul arg)
fat32_init();
usb_init();
pid_t test_thread_pid = kernel_thread(ktest_test_bitree, 1, 0);
kdebug("test_thread_pid=%d", test_thread_pid);
// 准备切换到用户态
struct pt_regs *regs;
@ -569,7 +571,7 @@ void process_init()
spin_init(&process_global_pid_write_lock);
// 初始化进程的循环链表
list_init(&initial_proc_union.pcb.list);
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核
kernel_thread(initial_kernel_thread, 10, CLONE_FS | CLONE_SIGNAL); // 初始化内核线
initial_proc_union.pcb.state = PROC_RUNNING;
initial_proc_union.pcb.preempt_count = 0;
initial_proc_union.pcb.cpu_id = 0;
@ -586,7 +588,6 @@ void process_init()
* @param stack_size
* @return unsigned long
*/
unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start, unsigned long stack_size)
{
int retval = 0;
@ -642,6 +643,7 @@ unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned
if (process_copy_flags(clone_flags, tsk))
goto copy_flags_failed;
kdebug("before copy mm");
// 拷贝内存空间分布结构体
if (process_copy_mm(clone_flags, tsk))
goto copy_mm_failed;

View File

@ -326,6 +326,17 @@ ul process_do_exit(ul code);
*/
void process_exit_notify();
/**
* @brief
*
* @param fn
* @param arg
* @param flags
* @return int
*/
int kernel_thread(unsigned long (*fn)(unsigned long), unsigned long arg, unsigned long flags);
/**
* @brief
* @param prev pcb