Browse Source

Patch add idr (#56)

* 增加了idr模块

* 增加了IDR模块,并尝试覆盖上一个错误版本.

* 增加了IDR模块

* 修改了test-idr.c文件

* 进一步完善函数注释

* 更新idr文档同时修改了test-idr的错误


* 将lz4库改为使用系统的clz函数

* idr和test-idr O1

* bugfix: 修复测试用例中的移位问题

* 修正问题

Signed-off-by: guanjinquan <[email protected]>
Co-authored-by: fslongjin <[email protected]>
guanjinquan 2 years ago
parent
commit
d53ddde95d

+ 432 - 0
docs/kernel/core_api/data_structures.md

@@ -2,6 +2,7 @@
 
 &emsp;&emsp;内核中实现了常用的几种数据结构,这里是他们的api文档。
 
+--------------
 ## kfifo先进先出缓冲区
 
 &emsp;&emsp;kfifo先进先出缓冲区定义于`common/kfifo.h`中。您可以使用它,创建指定大小的fifo缓冲区(最大大小为4GB)
@@ -252,3 +253,434 @@
 | 满 | 1   |
 | 不满  | 0   |
 
+------------------
+
+## ID Allocation
+
+&emsp;&emsp; ida的主要作用是分配+管理id. 它能分配一个最小的, 未被分配出去的id. 当您需要管理某个数据结构时, 可能需要使用id来区分不同的目标. 这个时候, ida将会是很好的选择. 因为ida的十分高效, 运行常数相对数组更小, 而且提供了基本管理id需要用到的功能, 值得您试一试.
+
+&emsp;&emsp;IDA定义于`idr.h`文件中. 您通过`DECLARE_IDA(my_ida)`来创建一个ida对象, 或者`struct ida my_ida; ida_init(my_ida);`来初始化一个ida. 
+
+### ida_init
+`void ida_init(struct ida *ida_p)`
+
+#### 描述
+
+&emsp;&emsp;通初始化IDA, 你需要保证调用函数之前, ida的free_list为空, 否则会导致内存泄漏. 
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+#### 返回值
+
+&emsp;&emsp;无返回值
+
+### ida_preload
+`int ida_preload(struct ida *ida_p, gfp_t gfp_mask)`
+
+#### 描述
+
+&emsp;&emsp;为ida预分配空间.您可以不自行调用, 因为当ida需要空间的时候, 内部会自行使用`kmalloc`函数获取空间. 当然, 设计这个函数的目的是为了让您有更多的选择. 当您提前调用这个函数, 可以避免之后在开辟空间上的时间开销.
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+**gfp_mask**
+
+&emsp;&emsp; 保留参数, 目前尚未使用.
+
+#### 返回值
+
+&emsp;&emsp;如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够.
+
+
+### ida_alloc
+`int ida_alloc(struct ida *ida_p, int *p_id)`
+
+#### 描述
+
+&emsp;&emsp;获取一个空闲ID. 您需要注意, 返回值是成功/错误码.
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+**p_id**
+
+&emsp;&emsp; 您需要传入一个int变量的指针, 如果成功分配ID, ID将会存储在该指针所指向的地址.
+
+#### 返回值
+
+&emsp;&emsp;如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够.
+
+
+### ida_count
+`bool ida_count(struct ida *ida_p, int id)`
+
+#### 描述
+
+&emsp;&emsp;查询一个ID是否被分配.
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+**id**
+
+&emsp;&emsp; 您查询该ID是否被分配.
+
+#### 返回值
+
+&emsp;&emsp;如果分配,将返回true; 否则返回false.
+
+
+
+### ida_remove
+`void ida_remove(struct ida *ida_p, int id)`
+
+#### 描述
+
+&emsp;&emsp;删除一个已经分配的ID. 如果该ID不存在, 该函数不会产生异常错误, 因为在检测到该ID不存在的时候, 函数将会自动退出.
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+**id**
+
+&emsp;&emsp; 您要删除的id.
+
+#### 返回值
+
+&emsp;&emsp;无返回值. 
+
+### ida_destroy
+`void ida_destroy(struct ida *ida_p)`
+
+#### 描述
+
+&emsp;&emsp;释放一个IDA所有的空间, 同时删除ida的所有已经分配的id.(所以您不用担心删除id之后, ida还会占用大量空间.)
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+#### 返回值
+
+&emsp;&emsp;无返回值
+
+### ida_empty
+`void ida_empty(struct ida *ida_p)`
+
+#### 描述
+
+&emsp;&emsp; 查询一个ida是否为空
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向ida的指针
+
+#### 返回值
+
+&emsp;&emsp;ida为空则返回true,否则返回false。
+
+
+--------------------
+
+
+## IDR
+
+&emsp;&emsp; idr是一个基于radix-tree的ID-pointer的数据结构. 该数据结构提供了建id与数据指针绑定的功能, 它的主要功能有以下4个:
+1. 获取一个ID, 并且将该ID与一个指针绑定  
+2. 删除一个已分配的ID                
+3. 根据ID查找对应的指针             
+4. 根据ID使用新的ptr替换旧的ptr     
+&emsp;&emsp; 您可以使用`DECLARE_idr(my_idr)`来创建一个idr。或者您也可以使用`struct idr my_idr; idr_init(my_idr);`这两句话创建一个idr。
+&emsp;&emsp; 至于什么是radix-tree,您可以把他简单理解为一个向上生长的多叉树,在实现中,我们选取了64叉树。
+
+### idr_init
+`void idr_init(struct idr *idp)`
+
+#### 描述
+
+&emsp;&emsp;通初始化IDR, 你需要保证调用函数之前, idr的free_list为空, 否则会导致内存泄漏. 
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+#### 返回值
+
+&emsp;&emsp;无返回值
+
+### idr_preload
+`int idr_preload(struct idr *idp, gfp_t gfp_mask)`
+
+#### 描述
+
+&emsp;&emsp;为idr预分配空间.您可以不自行调用, 因为当idr需要空间的时候, 内部会自行使用`kmalloc`函数获取空间. 当然, 设计这个函数的目的是为了让您有更多的选择. 当您提前调用这个函数, 可以避免之后在开辟空间上的时间开销.
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**gfp_mask**
+
+&emsp;&emsp; 保留参数, 目前尚未使用.
+
+#### 返回值
+
+&emsp;&emsp;如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够.
+
+
+### idr_alloc
+`int idr_alloc(struct idr *idp, void *ptr, int *id)`
+
+#### 描述
+
+&emsp;&emsp; 获取一个空闲ID. 您需要注意, 返回值是成功/错误码.
+&emsp;&emsp; 调用这个函数,需要您保证ptr是非空的,即: `ptr != NULL`, 否则将会影响 `idr_find/idr_find_next/idr_find_next_getid/...`等函数的使用。(具体请看这三个函数的说明,当然,只会影响到您的使用体验,并不会影响到idr内部函数的决策和逻辑)
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向ida的指针
+
+**ptr**
+
+&emsp;&emsp; 指向数据的指针
+
+**id**
+
+&emsp;&emsp; 您需要传入一个int变量的指针, 如果成功分配ID, ID将会存储在该指针所指向的地址.
+
+#### 返回值
+
+&emsp;&emsp;如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够.
+
+
+### idr_remove
+`void* idr_remove(struct idr *idp, int id)`
+
+#### 描述
+
+&emsp;&emsp;删除一个id, 但是不释放对应的ptr指向的空间, 同时返回这个被删除id所对应的ptr。
+&emsp;&emsp; 如果该ID不存在, 该函数不会产生异常错误, 因为在检测到该ID不存在的时候, 函数将会自动退出,并返回NULL。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**id**
+
+&emsp;&emsp; 您要删除的id.
+
+#### 返回值
+
+&emsp;&emsp;如果删除成功,就返回被删除id所对应的ptr;否则返回NULL。注意:如果这个id本来就和NULL绑定,那么也会返回NULL
+
+
+### idr_remove_all
+`void idr_remove_all(struct idr *idp)`
+
+#### 描述
+
+&emsp;&emsp;删除idr的所有已经分配的id.(所以您不用担心删除id之后, idr还会占用大量空间。) 
+
+&emsp;&emsp; 但是你需要注意的是,调用这个函数是不会释放数据指针指向的空间的。 所以您调用该函数之前, 确保IDR内部的数据指针被保存。否则当IDR删除所有ID之后, 将会造成内存泄漏。
+
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+#### 返回值
+
+&emsp;&emsp;无返回值
+
+
+### idr_destroy
+`void idr_destroy(struct idr *idp)`
+
+#### 描述
+
+&emsp;&emsp;释放一个IDR所有的空间, 同时删除idr的所有已经分配的id.(所以您不用担心删除id之后, ida还会占用大量空间.) - 和`idr_remove_all`的区别是, 释放掉所有的空间(包括free_list的预分配空间)。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+#### 返回值
+
+&emsp;&emsp;无返回值
+
+
+### idr_find
+`void *idr_find(struct idr *idp, int id)`
+
+#### 描述
+
+&emsp;&emsp;查询一个ID所绑定的数据指针
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**id**
+
+&emsp;&emsp; 您查询该ID的数据指针
+
+#### 返回值
+
+&emsp;&emsp; 如果分配,将返回该ID对应的数据指针; 否则返回NULL.(注意, 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
+&emsp;&emsp; 当然,我们也提供了`idr_count`函数来判断id是否被分配,具体请查看idr_count介绍。
+
+### idr_find_next
+`void *idr_find_next(struct idr *idp, int start_id)`
+
+#### 描述
+
+&emsp;&emsp;传进一个start_id,返回满足 "id大于start_id的最小id" 所对应的数据指针。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**start_id**
+
+&emsp;&emsp;您提供的ID限制
+
+#### 返回值
+
+&emsp;&emsp; 如果分配,将返回该ID对应的数据指针; 否则返回NULL.(注意, 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
+&emsp;&emsp; 当然,我们也提供了`idr_count`函数来判断id是否被分配,具体请查看idr_count介绍。
+
+
+### idr_find_next_getid
+`void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)`
+
+#### 描述
+
+&emsp;&emsp;传进一个start_id,返回满足 "id大于start_id的最小id" 所对应的数据指针。同时,你获取到这个满足条件的最小id, 即参数中的 *nextid。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**start_id**
+
+&emsp;&emsp; 您提供的ID限制
+
+#### 返回值
+
+&emsp;&emsp; 如果分配,将返回该ID对应的数据指针; 否则返回NULL.(注意, 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
+&emsp;&emsp; 当然,我们也提供了`idr_count`函数来判断id是否被分配,具体请查看idr_count介绍。
+
+
+### idr_replace
+`int idr_replace(struct idr *idp, void *ptr, int id)`
+
+#### 描述
+
+&emsp;&emsp;传进一个ptr,使用该ptr替换掉id所对应的Old_ptr。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**ptr**
+
+&emsp;&emsp;您要替换原来的old_ptr的新指针
+
+**id**
+
+&emsp;&emsp; 您要替换的指针所对应的id
+
+#### 返回值
+
+&emsp;&emsp; 0代表成功,否则就是错误码 - 代表错误。 
+
+
+### idr_replace_get_old
+`int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **oldptr)`
+
+#### 描述
+
+&emsp;&emsp;传进一个ptr,使用该ptr替换掉id所对应的Old_ptr,同时你可以获取到old_ptr。
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+**ptr**
+
+&emsp;&emsp;您要替换原来的old_ptr的新指针
+
+**id**
+
+&emsp;&emsp; 您要替换的指针所对应的id
+
+
+**old_ptr**
+
+&emsp;&emsp; 您需要传进该(void**)指针,old_ptr将会存放在该指针所指向的地址。
+
+
+#### 返回值
+
+&emsp;&emsp; 0代表成功,否则就是错误码 - 代表错误。 
+
+### idr_empty
+`void idr_empty(struct idr *idp)`
+
+#### 描述
+
+&emsp;&emsp; 查询一个idr是否为空
+#### 参数
+
+**idp**
+
+&emsp;&emsp; 指向idr的指针
+
+#### 返回值
+
+&emsp;&emsp;idr为空则返回true,否则返回false。
+
+### idr_count
+`bool idr_count(struct idr *idp, int id)`
+
+#### 描述
+
+&emsp;&emsp;查询一个ID是否被分配.
+#### 参数
+
+**ida_p**
+
+&emsp;&emsp; 指向idr的指针
+
+**id**
+
+&emsp;&emsp; 您查询该ID是否被分配.
+
+#### 返回值
+
+&emsp;&emsp;如果分配,将返回true; 否则返回false.

+ 15 - 1
kernel/arch/x86_64/math/bitcount.h

@@ -52,4 +52,18 @@ static __always_inline int __clzll(unsigned long long x)
                  : "a"(x)
                  : "memory");
     return res;
-}
+}
+
+static __always_inline int __ctz(uint32_t x)
+{
+    asm volatile("tzcnt %%eax, %%eax":"=a"(x):"a"(x):"memory");
+    return x;
+}
+
+static __always_inline int __ctzl(unsigned long x)
+{
+    asm volatile("tzcnt %%rax, %%rax":"=a"(x):"a"(x):"memory");
+    return x;
+}
+
+#define __ctzll __ctzl

+ 0 - 1
kernel/common/glib.h

@@ -68,7 +68,6 @@ static __always_inline ul ALIGN(const ul addr, const ul _align)
 }
 
 
-
 void *memset(void *dst, unsigned char C, ul size)
 {
 

+ 50 - 16
kernel/common/idr.h

@@ -1,8 +1,16 @@
-
+#pragma GCC push_options
+#pragma GCC optimize("O1")
 
 #include <common/errno.h>
 #include <common/spinlock.h>
 
+#if ARCH(I386) || ARCH(X86_64)
+#include <arch/x86_64/math/bitcount.h>
+#else
+#error Arch not supported.
+#endif
+
+
 /**
  * idr: 基于radix-tree的ID-pointer的数据结构
  * 主要功能:
@@ -33,17 +41,17 @@
 #define MAX_ID_MASK (MAX_ID_BIT - 1)
 
 // IDR可能最大的层次 以及 IDR预分配空间的最大限制
-#define MAX_LEVEL (MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS
+#define MAX_LEVEL ((MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS)
 #define IDR_FREE_MAX (MAX_LEVEL << 1)
 
 // 给定layer, 计算完全64叉树的大小
 #define TREE_SIZE(layer) ((layer >= 0) ? (1ull << ((layer + 1) * IDR_BITS)) : 1)
 
 // 计算最后(最低位)一个1的位置 (注意使用64位的版本)
-#define __lowbit_id(x) ((x) ? (__builtin_ctzll(x)) : -1)
+#define __lowbit_id(x) ((x) ? (__ctzll(x)) : -1)
 
 // 计算最前(最高位)一个1的位置 (注意使用64位的版本)
-#define __mostbit_id(x) ((x) ? (__builtin_clzll(x)) : -1)
+#define __mostbit_id(x) ((x) ? (63 - __clzll(x)) : -1)
 
 // radix-tree 节点定义
 struct idr_layer
@@ -61,14 +69,11 @@ struct idr
     struct idr_layer *free_list;
     int id_free_cnt;
     spinlock_t lock;
-};
+}__attribute__((aligned(8)));
 
 #define DECLARE_IDR(name)    \
     struct idr name = {0};   \
-    name.top = (NULL);       \
-    name.free_list = (NULL); \
-    name.id_free_cnt = (0);  \
-    spin_init(&name.lock);
+    idr_init(&(name));
 
 #define DECLARE_IDR_LAYER(name)  \
     struct idr_layer name = {0}; \
@@ -77,17 +82,43 @@ struct idr
 /**
  * 对外函数声明
  **/
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask);
-int idr_get_new(struct idr *idp, void *ptr, int *id);
-void idr_remove(struct idr *idp, int id);
+int idr_preload(struct idr *idp, gfp_t gfp_mask);
+int idr_alloc(struct idr *idp, void *ptr, int *id);
+void *idr_remove(struct idr *idp, int id);
 void idr_remove_all(struct idr *idp);
 void idr_destroy(struct idr *idp);
 void *idr_find(struct idr *idp, int id);
 void *idr_find_next(struct idr *idp, int start_id);
-void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid);
+void *idr_find_next_getid(struct idr *idp, int64_t start_id, int *nextid);
 int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **oldptr);
 int idr_replace(struct idr *idp, void *ptr, int id);
 void idr_init(struct idr *idp);
+bool idr_empty(struct idr *idp);
+bool idr_count(struct idr *idp, int id);
+
+/**
+ * 对外宏:遍历idr两种方式:
+ *     1. 从第一个元素开始遍历
+ *     2. 从某一个id开始遍历
+ */
+
+/**
+ * @brief 第一种遍历方式: 从第一个元素开始遍历
+ * @param idp idr指针
+ * @param id  遍历的id,你不需要初始化这个id,因为它每一次都是从最小已分配的id开始遍历
+ * @param ptr 数据指针(entry),你不需要初始化这个指针
+ */
+#define for_each_idr_entry(idp, id, ptr) \
+    for (id = -1, ptr = idr_find_next_getid(idp, id, &id); ptr != NULL || !idr_count(idp, id); ptr = idr_find_next_getid(idp, id, &id))
+
+/**
+ * @brief 第二种遍历方式: 从某一个id开始遍历
+ * @param idp idr指针
+ * @param id  遍历的id,你需要初始化这个id(请你设置为你要从哪一个id开始遍历,遍历过程将会包括这个id)
+ * @param ptr 数据指针(entry),你不需要初始化这个指针
+ */
+#define for_each_idr_entry_continue(idp, id, ptr) \
+    for (ptr = idr_find_next_getid(idp, id - 1, &id); ptr != NULL || !idr_count(idp, id); ptr = idr_find_next_getid(idp, id, &id))
 
 /**
  * ida: 基于IDR实现的ID分配器
@@ -132,8 +163,11 @@ struct ida
  * 对外函数声明
  */
 void ida_init(struct ida *ida_p);
-int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask);
-int ida_get_new(struct ida *ida_p, int *p_id);
+bool ida_empty(struct ida *ida_p);
+int ida_preload(struct ida *ida_p, gfp_t gfp_mask);
+int ida_alloc(struct ida *ida_p, int *p_id);
 bool ida_count(struct ida *ida_p, int id);
 void ida_remove(struct ida *ida_p, int id);
-void ida_destroy(struct ida *ida_p);
+void ida_destroy(struct ida *ida_p);
+
+#pragma GCC pop_options

+ 87 - 49
kernel/ktest/test-idr.c

@@ -1,5 +1,6 @@
 
-
+#pragma GCC push_options
+#pragma GCC optimize("O1")
 #include "ktest.h"
 #include "ktest_utils.h"
 #include <common/idr.h>
@@ -8,7 +9,7 @@
  * @brief 测试idr的构建,预获取空间是否成功
  *
  * 以下函数将被测试:
- * 1. idr_pre_get
+ * 1. idr_preload
  * 2. DECLARE_IDR
  * 3. idr_init
  * 4. idr_destroy
@@ -33,7 +34,7 @@ static long ktest_idr_case0(uint64_t arg0, uint64_t arg1)
     idr_init(&k_idr);
     assert(k_idr.id_free_cnt == 0);
 
-    assert(idr_pre_get(&k_idr, 0) == 0);
+    assert(idr_preload(&k_idr, 0) == 0);
     assert(k_idr.id_free_cnt == IDR_FREE_MAX);
 
     for (uint64_t i = 1; i < 64; i++)
@@ -71,7 +72,7 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1)
     // 获取128个id
     for (int i = 0; i < 128; i++)
     {
-        assert(idr_get_new(&k_idr, &a[i], &a[i]) == 0);
+        assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
         assert(a[i] == i);
     }
 
@@ -87,35 +88,53 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1)
     // 倒序:删除64个id
     for (int i = 127; i >= 64; i--)
     {
-        idr_remove(&k_idr, a[i]);
+        int *id = idr_remove(&k_idr, a[i]);
+        assert(id != NULL);
+        assert(*id == i);
         assert(idr_find(&k_idr, a[i]) == NULL);
     }
 
     // 正序:删除64个id
     for (int i = 0; i <= 63; i++)
     {
-        idr_remove(&k_idr, a[i]);
+        int *id = idr_remove(&k_idr, a[i]);
+        assert(id != NULL);
+        assert(*id == i);
         assert(idr_find(&k_idr, a[i]) == NULL);
     }
 
+    for (int i = 0; i < 128; i++) 
+    {
+        assert(idr_count(&k_idr, i) == 0);
+    }
+
     // 重新申请128个id, 值域范围应该仍然是[0,127]
     for (int i = 0; i < 128; i++)
     {
-        assert(idr_get_new(&k_idr, &a[i], &a[i]) == 0);
+        assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
         assert(a[i] == i);
     }
 
+    for (int i = 0; i < 128; i++) 
+    {
+        assert(idr_count(&k_idr, i));
+    }
+
     // 正序:删除32个id
     for (int i = 0; i <= 31; i++)
     {
-        idr_remove(&k_idr, a[i]);
+        int *id = idr_remove(&k_idr, a[i]);
+        assert(id != NULL);
+        assert(*id == i);
         assert(idr_find(&k_idr, a[i]) == NULL);
     }
 
     // 倒序:删除32个id
     for (int i = 127; i >= 96; i--)
     {
-        idr_remove(&k_idr, a[i]);
+        int *id = idr_remove(&k_idr, a[i]);
+        assert(id != NULL);
+        assert(*id == i);
         assert(idr_find(&k_idr, a[i]) == NULL);
     }
 
@@ -126,7 +145,7 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1)
     // 获取128个id
     for (int i = 0; i < 128; i++)
     {
-        assert(idr_get_new(&k_idr, &a[i], &a[i]) == 0);
+        assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
         assert(a[i] == i);
     }
 
@@ -171,20 +190,30 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
     DECLARE_IDR(k_idr);
 
     // 获取 1000‘000 个ID
-    const int N = 1e7;
-    const int M = 3e6;
+    const int N = 1e6;
+    // const int N = 1048576;
+    const int M = 2e5;
 
-    int tmp;
+    int tmp=0;
     for (int i = 0; i < N; i++)
     {
-        assert(idr_get_new(&k_idr, &tmp, &tmp) == 0);
+        barrier();
+        assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
+        barrier();
         assert(tmp == i);
 
+        barrier();
         int *ptr = idr_find(&k_idr, i);
+        barrier();
         assert(ptr != NULL);
         assert(*ptr == i);
-    }
 
+        barrier();
+        // if (i >= 7255) kdebug("1e6 !!!!!!! : %d", i);
+        assert(idr_count(&k_idr, i));
+        barrier();
+    }
+// kdebug("111111");
     // 正向: M 个ID
     for (int i = 0; i < M; i++)
     {
@@ -194,6 +223,7 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
         idr_remove(&k_idr, i);
         assert(idr_find(&k_idr, i) == NULL);
     }
+    // kdebug("22222");
 
     // 倒序: N-M 个ID
     for (int i = (N)-1; i >= M; i--)
@@ -203,11 +233,11 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
         idr_remove(&k_idr, i);
         assert(idr_find(&k_idr, i) == NULL);
     }
-
+// kdebug("3333333");
     // 重新插入数据
     for (int i = 0; i < N; i++)
     {
-        assert(idr_get_new(&k_idr, &tmp, &tmp) == 0);
+        assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
         assert(tmp == i);
         assert(k_idr.top != NULL);
 
@@ -215,19 +245,19 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
         assert(ptr != NULL);
         assert(*ptr == i);
     }
-
+// kdebug("4444444444");
     assert(k_idr.top != NULL);
 
     for (int i = 0; i < M; i++)
     {
         assert(idr_replace(&k_idr, NULL, i) == 0);
     }
-
+// kdebug("555555555555555555");
     // 销毁
     idr_destroy(&k_idr);
     assert(k_idr.id_free_cnt == 0);
     assert(k_idr.free_list == NULL);
-
+// kdebug("666666666666");
     return 0;
 }
 
@@ -247,7 +277,7 @@ static long ktest_idr_case3(uint64_t arg0, uint64_t arg1)
     // 获取ID
     for (int i = 0; i < N; i++)
     {
-        assert(idr_get_new(&k_idr, &tmp, &tmp) == 0);
+        assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
         assert(tmp == i);
 
         int *ptr = idr_find(&k_idr, i);
@@ -333,7 +363,7 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1)
         int M = N / i, T = M / 3, O = 2 * T;
         for (int j = 0; j < M; j++)
         {
-            assert(idr_get_new(&k_idr, &tmp, &tmp) == 0);
+            assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
             assert(tmp == j);
         }
 
@@ -362,12 +392,14 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1)
         }
 
         assert(k_idr.top == NULL);
+        assert(idr_empty(&k_idr));
     }
 
     // 销毁
     idr_destroy(&k_idr);
     assert(k_idr.id_free_cnt == 0);
     assert(k_idr.free_list == NULL);
+    assert(idr_empty(&k_idr));
 
     return 0;
 }
@@ -387,7 +419,7 @@ static long ktest_idr_case5(uint64_t arg0, uint64_t arg1)
     // 获取128个id
     for (int i = 0; i < N; i++)
     {
-        assert(idr_get_new(&k_idr, &a[i], &a[i]) == 0);
+        assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
         assert(a[i] == i);
     }
 
@@ -414,12 +446,13 @@ static long ktest_idr_case5(uint64_t arg0, uint64_t arg1)
     // destroy之后,再获取128个id
     for (int i = 0; i < N; i++)
     {
-        assert(idr_get_new(&k_idr, &a[i], &a[i]) == 0);
+        assert(idr_alloc(&k_idr, &a[i], &a[i]) == 0);
         assert(a[i] == i);
     }
 
     // 销毁
     idr_destroy(&k_idr);
+    assert(idr_empty(&k_idr));
     assert(k_idr.id_free_cnt == 0);
     assert(k_idr.free_list == NULL);
 
@@ -442,65 +475,68 @@ static long ktest_idr_case6(uint64_t arg0, uint64_t arg1)
 
     DECLARE_IDA(k_ida);
     ida_init(&k_ida);
+    io_sfence();
 
     const int N = IDA_FULL * IDR_SIZE + 1;
 
     for (int i = 0; i < N; i++)
     {
-        int p_id;
-        assert(ida_get_new(&k_ida, &p_id) == 0);
-        assert(p_id == i);
+        int p_id;io_sfence();
+        assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
+        assert(p_id == i);io_sfence();
     }
 
     for (int i = 0; i < N; i++)
     {
-        assert(ida_count(&k_ida, i) == 1);
+        assert(ida_count(&k_ida, i) == 1);io_sfence();
     }
 
     for (int i = N - 1; i >= 0; i--)
     {
-        ida_remove(&k_ida, i);
-        assert(ida_count(&k_ida, i) == 0);
+        ida_remove(&k_ida, i);io_sfence();
+        assert(ida_count(&k_ida, i) == 0);io_sfence();
     }
 
     assert(k_ida.idr.top == NULL);
 
     for (int i = 0; i < N; i++)
     {
-        int p_id;
-        assert(ida_get_new(&k_ida, &p_id) == 0);
-        assert(p_id == i);
+        int p_id;io_sfence();
+        assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
+        assert(p_id == i);io_sfence();
     }
 
-    assert(k_ida.idr.top != NULL);
-    ida_destroy(&k_ida);
-    assert(k_ida.idr.top == NULL);
-    assert(k_ida.free_list == NULL);
+    assert(k_ida.idr.top != NULL);io_sfence();
+    ida_destroy(&k_ida);io_sfence();
+    assert(k_ida.idr.top == NULL);io_sfence();
+    assert(k_ida.free_list == NULL);io_sfence();
+    assert(ida_empty(&k_ida));io_sfence();
 
     // 测试destroy之后能否重新获取ID
     for (int i = 0; i < N; i++)
     {
-        int p_id;
-        assert(ida_get_new(&k_ida, &p_id) == 0);
-        assert(p_id == i);
+        int p_id;io_sfence();
+        assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
+        assert(p_id == i);io_sfence();
     }
 
     for (int i = 0; i < N / 3; i++)
     {
-        ida_remove(&k_ida, i);
-        assert(ida_count(&k_ida, i) == 0);
+        ida_remove(&k_ida, i);io_sfence();
+        assert(ida_count(&k_ida, i) == 0);io_sfence();
     }
 
     for (int i = 2 * N / 3; i < N; i++)
     {
-        ida_remove(&k_ida, i);
-        assert(ida_count(&k_ida, i) == 0);
+        ida_remove(&k_ida, i);io_sfence();
+        assert(ida_count(&k_ida, i) == 0);io_sfence();
     }
 
-    assert(k_ida.idr.top != NULL);
-    ida_destroy(&k_ida);
-    assert(k_ida.idr.top == NULL);
-    assert(k_ida.free_list == NULL);
+    assert(k_ida.idr.top != NULL);io_sfence();
+    ida_destroy(&k_ida);io_sfence();
+    assert(k_ida.idr.top == NULL);io_sfence();
+    assert(k_ida.free_list == NULL);io_sfence();
+    assert(ida_empty(&k_ida));io_sfence();
 
     return 0;
 }
@@ -526,4 +562,6 @@ int ktest_test_idr(void* arg)
     }
     kTEST("idr Test done.");
     return 0;
-}
+}
+
+#pragma GCC pop_options

+ 246 - 71
kernel/lib/idr.c

@@ -1,5 +1,7 @@
 #include <common/idr.h>
 #include <mm/slab.h>
+#pragma GCC push_options
+#pragma GCC optimize("O0")
 
 /**
  * @brief 更换两个idr_layer指针
@@ -32,14 +34,17 @@ void idr_init(struct idr *idp)
  */
 static void __move_to_free_list(struct idr *idp, struct idr_layer *p)
 {
-    spin_lock(&idp->lock);
+    unsigned long flags;
+    spin_lock_irqsave(&idp->lock, flags);
 
     // 插入free_list
     p->ary[0] = idp->free_list;
+    io_sfence();
     idp->free_list = p;
+    io_sfence();
     ++(idp->id_free_cnt);
 
-    spin_unlock(&idp->lock);
+    spin_unlock_irqrestore(&idp->lock, flags);
 }
 
 /**
@@ -52,22 +57,32 @@ static void *__get_from_free_list(struct idr *idp)
 {
     if (idp->id_free_cnt == 0)
     {
-        if (idr_pre_get(idp, 0) != 0)
+        if (idr_preload(idp, 0) != 0)
         {
             kBUG("idr-module find a BUG: get free node fail.(Possible ENOMEM error)");
             return NULL;
         }
     }
 
-    spin_lock(&idp->lock);
+    unsigned long flags;
+    spin_lock_irqsave(&idp->lock, flags);
 
     // free_list还有节点
     struct idr_layer *item = idp->free_list;
+
+    if (item == NULL)
+    {
+        BUG_ON(1);
+    }
+
+    io_sfence();
     idp->free_list = idp->free_list->ary[0];
+    io_sfence();
     item->ary[0] = NULL; // 记得清空原来的数据
+    io_sfence();
     --(idp->id_free_cnt);
 
-    spin_unlock(&idp->lock);
+    spin_unlock_irqrestore(&idp->lock, flags);
 
     return item;
 }
@@ -79,15 +94,16 @@ static void *__get_from_free_list(struct idr *idp)
  * @param gfp_mask
  * @return int (如果分配成功,将返回0; 否则返回负数 -ENOMEM, 有可能是内存空间不够)
  */
-int idr_pre_get(struct idr *idp, gfp_t gfp_mask)
+int idr_preload(struct idr *idp, gfp_t gfp_mask)
 {
     int timer = 0;
     while (idp->id_free_cnt < IDR_FREE_MAX)
     {
         struct idr_layer *new_one;
         new_one = kzalloc(sizeof(struct idr_layer), gfp_mask); // 默认清空?
-        if (NULL == new_one)
+        if (unlikely(new_one == NULL))
             return -ENOMEM;
+
         __move_to_free_list(idp, new_one);
         timer++;
     }
@@ -149,9 +165,9 @@ static int __idr_get_empty_slot(struct idr *idp, struct idr_layer **stk)
         if (__idr_grow(idp) != 0)
             return -ENOMEM;
 
-    int id = 0;
+    int64_t id = 0;
     int layer = idp->top->layer;
-
+    BUG_ON(layer + 1 >= 7);
     stk[layer + 1] = NULL; // 标志为数组末尾
 
     struct idr_layer *cur_layer = idp->top;
@@ -198,6 +214,7 @@ static int __idr_get_empty_slot(struct idr *idp, struct idr_layer **stk)
  */
 static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_layer **stk, int mark)
 {
+    int64_t __id = (int64_t)id;
     if (unlikely(NULL == stk[0] || NULL == idp->top))
     {
         kBUG("idr-module find a BUG: idp->top can't be NULL.");
@@ -205,7 +222,7 @@ static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_
     }
 
     // 处理叶子节点的full/bitmap标记
-    int layer_id = id & IDR_MASK;
+    int layer_id = __id & IDR_MASK;
     if (mark == 2)
         stk[0]->full |= (1ull << layer_id);
     if (mark >= 1)
@@ -213,8 +230,8 @@ static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_
 
     for (int i = 1; stk[i]; ++i)
     {
-        id >>= IDR_BITS;
-        layer_id = id & IDR_MASK;
+        __id >>= IDR_BITS;
+        layer_id = __id & IDR_MASK;
 
         stk[i]->bitmap |= (1ull << layer_id);
         if (stk[i - 1]->full == IDR_FULL)
@@ -232,7 +249,8 @@ static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_
  */
 static __always_inline int __idr_get_path(struct idr *idp, int id, struct idr_layer **stk)
 {
-    if (unlikely(idp->top == NULL || id < 0))
+    int64_t __id = (int64_t)id;
+    if (unlikely(idp->top == NULL || __id < 0))
     {
         kBUG("idr-module find a BUG: idp->top can't be NULL and id must be non-negative.");
         return 0;
@@ -242,11 +260,17 @@ static __always_inline int __idr_get_path(struct idr *idp, int id, struct idr_la
     int layer = cur_layer->layer;
     stk[layer + 1] = NULL; // 标志数组结尾
 
+    if (unlikely((__id >> ((layer + 1ull) * IDR_BITS)) > 0))
+    {
+        kBUG("idr-module find a BUG: id is invalid.");
+        return 0;
+    }
+
     // 提取路径
     while (layer >= 0)
     {
         stk[layer] = cur_layer;
-        int layer_id = (id >> (layer * IDR_BITS)) & IDR_MASK;
+        int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
 
         if (unlikely(((cur_layer->bitmap >> layer_id) & 1) == 0))
         {
@@ -271,6 +295,7 @@ static __always_inline int __idr_get_path(struct idr *idp, int id, struct idr_la
  */
 static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr_layer **stk, int mark)
 {
+    int64_t __id = (int64_t)id;
     if (unlikely(NULL == stk[0] || NULL == idp->top))
     {
         kBUG("idr-module find a BUG: idp->top can't be NULL.");
@@ -278,7 +303,7 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr
     }
 
     // 处理叶子节点的full/bitmap标记
-    int layer_id = id & IDR_MASK;
+    int layer_id = __id & IDR_MASK;
     if (mark == 0) // 叶子的某个插槽为空
     {
         stk[0]->ary[layer_id] = NULL;
@@ -290,8 +315,8 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr
     // 删除节点
     for (int layer = 1; stk[layer]; ++layer)
     {
-        id >>= IDR_BITS;
-        layer_id = id & IDR_MASK;
+        __id >>= IDR_BITS;
+        layer_id = __id & IDR_MASK;
 
         if (NULL == stk[layer - 1]->bitmap) // 儿子是空节点
         {
@@ -333,8 +358,12 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr
  */
 static int __idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
 {
-    struct idr_layer *stk[MAX_LEVEL + 1]; // 你可以选择memset(0)
-    int id = __idr_get_empty_slot(idp, stk);
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0};
+
+    // kdebug("stk=%#018lx, sizeof_stk=%d", stk, sizeof(stk));
+    // memset(stk, 0, sizeof(stk));
+    // 你可以选择 memset(stk, 0, sizeof(stk));
+    int64_t id = __idr_get_empty_slot(idp, stk);
 
     if (id >= 0)
     {
@@ -353,7 +382,7 @@ static int __idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
  * @param int* id - 传入int指针,获取到的NEW_ID存在id里
  * @return int (0表示获取id成功, 负数代表错误 - 可能是内存空间不够)
  */
-int idr_get_new(struct idr *idp, void *ptr, int *id)
+int idr_alloc(struct idr *idp, void *ptr, int *id)
 {
     int rv = __idr_get_new_above_int(idp, ptr, 0);
     if (rv < 0)
@@ -363,21 +392,28 @@ int idr_get_new(struct idr *idp, void *ptr, int *id)
 }
 
 /**
- * @brief 删除一个id,但是不释放对应的ptr指向的空间
+ * @brief 删除一个id, 但是不释放对应的ptr指向的空间, 同时返回这个被删除id所对应的ptr
  *
  * @param idp
  * @param id
+ * @return void*
+ * (如果删除成功,就返回被删除id所对应的ptr;否则返回NULL。注意:如果这个id本来就和NULL绑定,那么也会返回NULL)
  */
-void idr_remove(struct idr *idp, int id)
+void *idr_remove(struct idr *idp, int id)
 {
-    if (unlikely(idp->top == NULL || id < 0))
-        return;
+    int64_t __id = (int64_t)id;
+    if (unlikely(idp->top == NULL || __id < 0))
+        return NULL;
+
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0};
 
-    struct idr_layer *stk[MAX_LEVEL + 1];
-    if (0 == __idr_get_path(idp, id, stk))
-        return; // 找不到路径
+    if (0 == __idr_get_path(idp, __id, stk))
+        return NULL; // 找不到路径
 
-    __idr_erase_full(idp, id, stk, 0);
+    void *ret = stk[0]->ary[__id & IDR_MASK];
+    __idr_erase_full(idp, __id, stk, 0);
+
+    return ret;
 }
 
 /**
@@ -395,9 +431,11 @@ static void __idr_remove_all_with_free(struct idr *idp, bool free)
     }
 
     int sz = sizeof(struct idr_layer);
-    struct idr_layer *stk[MAX_LEVEL + 1];
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0};
+
     struct idr_layer *cur_layer = idp->top;
     int layer = cur_layer->layer;
+    BUG_ON(layer + 1 >= 7);
     stk[layer + 1] = NULL; // 标记数组结尾
 
     while (cur_layer != NULL)
@@ -405,7 +443,7 @@ static void __idr_remove_all_with_free(struct idr *idp, bool free)
         if (layer > 0 && cur_layer->bitmap) // 非叶子节点
         {
             stk[layer] = cur_layer; // 入栈
-            int id = __lowbit_id(cur_layer->bitmap);
+            int64_t id = __lowbit_id(cur_layer->bitmap);
 
             cur_layer->bitmap ^= (1ull << id);
             cur_layer = cur_layer->ary[id];
@@ -482,19 +520,21 @@ void idr_destroy(struct idr *idp)
  */
 void *idr_find(struct idr *idp, int id)
 {
-    if (unlikely(idp->top == NULL || id < 0))
+    int64_t __id = (int64_t)id;
+    if (unlikely(idp->top == NULL || __id < 0))
+    {
+        kwarn("idr-find: idp->top == NULL || id < 0.");
         return NULL;
+    }
 
     struct idr_layer *cur_layer = idp->top;
     int layer = cur_layer->layer; // 特判NULL
-
     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
-    if ((id >> ((layer + 1) * IDR_BITS)) > 0)
+    if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
         return NULL;
-
     while (layer >= 0 && cur_layer)
     {
-        int layer_id = (id >> (IDR_BITS * layer)) & IDR_MASK;
+        int layer_id = (__id >> (IDR_BITS * layer)) & IDR_MASK;
         cur_layer = cur_layer->ary[layer_id];
         --layer;
     }
@@ -508,10 +548,12 @@ void *idr_find(struct idr *idp, int id)
  * @param idp
  * @param start_id
  * @param nextid
- * @return void*
+ * @return void* (如果分配,将返回该ID对应的数据指针; 否则返回NULL。注意,
+ * 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
  */
-void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)
+void *idr_find_next_getid(struct idr *idp, int64_t start_id, int *nextid)
 {
+    BUG_ON(nextid == NULL);
     if (unlikely(idp->top == NULL))
     {
         *nextid = -1;
@@ -522,16 +564,20 @@ void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)
     start_id = max(0, start_id); // 特判负数
     *nextid = 0;
 
-    struct idr_layer *stk[MAX_LEVEL + 1];
-    bool state[MAX_LEVEL + 1]; // 标记是否大于等于]
-    int pos_i[MAX_LEVEL + 1];
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0};
+
+    // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
+    bool state[MAX_LEVEL + 1] = {0}; // 标记是否大于等于]
+    int pos_i[MAX_LEVEL + 1] = {0};
 
-    memset(pos_i, 0, sizeof(pos_i)); // 必须清空
+    // memset(state, 0, sizeof(state));
+    // memset(pos_i, 0, sizeof(pos_i)); // 必须清空
 
     struct idr_layer *cur_layer = idp->top;
     bool cur_state = false;
     bool init_flag = true;
     int layer = cur_layer->layer;
+    BUG_ON(layer + 1 >= 7);
     stk[layer + 1] = NULL; // 标记数组结尾
 
     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
@@ -543,6 +589,7 @@ void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)
 
     while (cur_layer) // layer < top->layer + 1
     {
+        BUG_ON(layer < 0);
         if (init_flag) // 第一次入栈
         {
             stk[layer] = cur_layer;
@@ -555,13 +602,14 @@ void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)
             state[layer] = cur_state = true;
         }
 
+        BUG_ON(pos_i[layer] >= 64);
         unsigned long t_bitmap = (cur_layer->bitmap >> pos_i[layer]);
         if (t_bitmap) // 进一步递归到儿子下面去
         {
             int layer_id = __lowbit_id(t_bitmap) + pos_i[layer];
 
             // 特别情况
-            if (NULL == cur_state && layer_id > pos_i[layer] > 0)
+            if ((cur_state == false) && layer_id > pos_i[layer] > 0)
                 cur_state = true;
 
             pos_i[layer] = layer_id;
@@ -596,7 +644,8 @@ void *idr_find_next_getid(struct idr *idp, int start_id, int *nextid)
  *
  * @param idp
  * @param start_id
- * @return void*
+ * @return void* (如果分配,将返回该ID对应的数据指针; 否则返回NULL。注意,
+ * 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
  */
 void *idr_find_next(struct idr *idp, int start_id)
 {
@@ -617,21 +666,26 @@ void *idr_find_next(struct idr *idp, int start_id)
  */
 int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **old_ptr)
 {
+    int64_t __id = (int64_t)id;
+    if (unlikely(old_ptr == NULL))
+    {
+        BUG_ON(1);
+        return -EINVAL;
+    }
     *old_ptr = NULL;
 
-    if (unlikely(idp->top == NULL || id < 0))
+    if (unlikely(idp->top == NULL || __id < 0))
         return -EDOM; // 参数错误
 
     struct idr_layer *cur_layer = idp->top;
-    int layer = cur_layer->layer;
-
+    int64_t layer = cur_layer->layer;
     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
-    if ((id >> ((layer + 1) * IDR_BITS)) > 0)
+    if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
         return -EDOM;
 
     while (layer > 0)
     {
-        int layer_id = (id >> (layer * IDR_BITS)) & IDR_MASK;
+        int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
 
         if (unlikely(NULL == cur_layer->ary[layer_id]))
             return -ENOMEM;
@@ -640,9 +694,9 @@ int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **old_ptr)
         layer--;
     }
 
-    id &= IDR_MASK;
-    *old_ptr = cur_layer->ary[id];
-    cur_layer->ary[id] = ptr;
+    __id &= IDR_MASK;
+    *old_ptr = cur_layer->ary[__id];
+    cur_layer->ary[__id] = ptr;
 
     return 0;
 }
@@ -657,15 +711,105 @@ int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **old_ptr)
  */
 int idr_replace(struct idr *idp, void *ptr, int id)
 {
-    if (id < 0)
+    int64_t __id = (int64_t)id;
+    if (__id < 0)
         return -EDOM;
 
     void *old_ptr;
-    int flags = idr_replace_get_old(idp, ptr, id, &old_ptr);
+    int flags = idr_replace_get_old(idp, ptr, __id, &old_ptr);
 
     return flags;
 }
 
+/**
+ * @brief 判断一个idr是否为空
+ *
+ * @param idp
+ * @return true
+ * @return false
+ */
+bool idr_empty(struct idr *idp)
+{
+    if (idp == NULL || idp->top == NULL || !idp->top->bitmap)
+        return true;
+
+    return false;
+}
+#pragma GCC push_options
+#pragma GCC optimize("O0")
+
+static bool __idr_cnt_pd(struct idr_layer *cur_layer, int layer_id)
+{
+    // if(layer_id)
+    unsigned long flags = ((cur_layer->bitmap) >> layer_id);
+    if ((flags % 2) == 0)
+    {
+        barrier();
+        return false; // 没有这一个儿子
+    }
+    return true;
+}
+
+static bool __idr_cnt(int layer, int id, struct idr_layer *cur_layer)
+{
+    int64_t __id = (int64_t)id;
+    while (layer >= 0) // 提取路径
+    {
+        barrier();
+
+        int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
+
+        barrier();
+
+        if (__idr_cnt_pd(cur_layer, layer_id) == false)
+            return false;
+
+        barrier();
+
+        barrier();
+        cur_layer = cur_layer->ary[layer_id];
+
+        barrier();
+        --layer;
+    }
+    return true;
+}
+#pragma GCC pop_options
+
+/**
+ * @brief 这个函数是可以用于判断一个ID是否已经被分配的。
+ *
+ * @param idp
+ * @param id
+ * @return true
+ * @return false
+ */
+bool idr_count(struct idr *idp, int id)
+{
+    int64_t __id = (int64_t)id;
+    barrier();
+    if (unlikely(idp == NULL || idp->top == NULL || __id < 0))
+        return false;
+
+    barrier();
+    struct idr_layer *cur_layer = idp->top;
+    barrier();
+    int layer = cur_layer->layer;
+
+    // 如果查询的ID的bit数量比 layer*IDR_BITS 还大, 直接返回false
+    if (unlikely((__id >> ((layer + 1ull) * IDR_BITS)) > 0))
+    {
+        BUG_ON(1);
+        return false;
+    }
+    barrier();
+
+    return __idr_cnt(layer, id, cur_layer);
+}
+
+/********* ****************************************** ida - idr 函数实现分割线
+ * **********************************************************/
+
 /**
  * @brief 初始化IDA, 你需要保证调用函数之前, ida的free_list为空, 否则会导致内存泄漏
  * @param ida_p
@@ -692,9 +836,9 @@ static void __ida_bitmap_free(struct ida_bitmap *bitmap)
  * @param gfp_mask
  * @return int (如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够)
  */
-int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask)
+int ida_preload(struct ida *ida_p, gfp_t gfp_mask)
 {
-    if (idr_pre_get(&ida_p->idr, gfp_mask) != 0)
+    if (idr_preload(&ida_p->idr, gfp_mask) != 0)
         return -ENOMEM;
 
     spin_lock(&ida_p->idr.lock);
@@ -724,8 +868,11 @@ int ida_pre_get(struct ida *ida_p, gfp_t gfp_mask)
 static void *__get_ida_bitmap(struct ida *ida_p, gfp_t gfp_mask)
 {
     if (NULL == ida_p->free_list)
-        if (ida_pre_get(ida_p, gfp_mask) < 0)
+        if (ida_preload(ida_p, gfp_mask) < 0)
+        {
+            kBUG("error : no memory.");
             return NULL;
+        }
 
     struct ida_bitmap *tmp = ida_p->free_list;
     ida_p->free_list = NULL;
@@ -749,7 +896,8 @@ static int __get_id_from_bitmap(struct ida_bitmap *bmp)
 
             if (unlikely((unsigned long long)ary_id * IDA_BMP_SIZE + bmp_id > INT32_MAX))
             {
-                kBUG("ida设置id范围为[0, INT32_MAX], 但ida获取的id数值超过INT32_MAX.");
+                BUG_ON(1);
+                // kBUG("ida设置id范围为[0, INT32_MAX], 但ida获取的id数值超过INT32_MAX.");
                 return -EDOM;
             }
 
@@ -767,13 +915,17 @@ static int __get_id_from_bitmap(struct ida_bitmap *bmp)
  * @param p_id
  * @return int (0表示获取ID成功, 否则是负数 - 错误码)
  */
-int ida_get_new(struct ida *ida_p, int *p_id)
+int ida_alloc(struct ida *ida_p, int *p_id)
 {
+    BUG_ON(p_id == NULL);
     *p_id = -1;
 
-    struct idr_layer *stk[MAX_LEVEL + 1]; // 你可以选择memset(0)
-    memset(stk, 0, sizeof(stk));
-    int idr_id = __idr_get_empty_slot(&ida_p->idr, stk);
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0}; // 你可以选择memset(0)
+
+    // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
+
+    io_sfence();
+    int64_t idr_id = __idr_get_empty_slot(&ida_p->idr, stk);
 
     // 如果stk[0]=NULL,可能是idr内部出错/内存空间不够
     if (unlikely(NULL == stk[0]))
@@ -812,12 +964,13 @@ int ida_get_new(struct ida *ida_p, int *p_id)
  */
 bool ida_count(struct ida *ida_p, int id)
 {
+    int64_t __id = (int64_t)id;
     if (unlikely(NULL == ida_p || NULL == ida_p->idr.top || id < 0))
         return false;
 
-    int idr_id = id / IDA_BITMAP_BITS;
-    int ary_id = (id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
-    int bmp_id = (id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
+    int idr_id = __id / IDA_BITMAP_BITS;
+    int ary_id = (__id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
+    int bmp_id = (__id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
 
     struct ida_bitmap *bmp = idr_find(&ida_p->idr, idr_id);
     if (NULL == bmp)
@@ -834,19 +987,21 @@ bool ida_count(struct ida *ida_p, int id)
  */
 void ida_remove(struct ida *ida_p, int id)
 {
+    int64_t __id = (int64_t)id;
     if (unlikely(NULL == ida_p || NULL == ida_p->idr.top || id < 0))
         return;
 
-    int idr_id = id / IDA_BITMAP_BITS;
-    int ary_id = (id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
-    int bmp_id = (id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
+    int64_t idr_id = __id / IDA_BITMAP_BITS;
+    int64_t ary_id = (__id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
+    int64_t bmp_id = (__id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
+
+    struct idr_layer *stk[MAX_LEVEL + 1] = {0};
+    // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
 
-    struct idr_layer *stk[MAX_LEVEL + 1];
-    memset(stk, 0, sizeof(stk));
     if (0 == __idr_get_path(&ida_p->idr, idr_id, stk))
         return;
 
-    struct ida_bitmap *b_p = (struct ida_bitmap *)stk[0]->ary[idr_id & IDR_MASK];
+    struct ida_bitmap *b_p = (struct ida_bitmap *)(stk[0]->ary[idr_id & IDR_MASK]);
 
     // 不存在这个ID 或者 b_p == NULL
     if (unlikely(NULL == b_p || 0 == ((b_p->bitmap[ary_id] >> bmp_id) & 1)))
@@ -871,10 +1026,30 @@ void ida_remove(struct ida *ida_p, int id)
 void ida_destroy(struct ida *ida_p)
 {
     if (unlikely(ida_p == NULL))
+    {
+        BUG_ON(1);
         return;
+    }
 
     __idr_destroy_with_free(&ida_p->idr);
     ida_p->idr.top = NULL;
     __ida_bitmap_free(ida_p->free_list);
     ida_p->free_list = NULL;
-}
+}
+
+/**
+ * @brief 判断一个ida是否为空
+ *
+ * @param ida_p
+ * @return true
+ * @return false
+ */
+bool ida_empty(struct ida *ida_p)
+{
+    if (ida_p == NULL || ida_p->idr.top == NULL || !ida_p->idr.top->bitmap)
+        return true;
+
+    return false;
+}
+
+#pragma GCC pop_options

+ 10 - 2
kernel/lib/lz4.c

@@ -40,6 +40,14 @@
  * Select how default compression functions will allocate memory for their hash table,
  * in memory stack (0:default, fastest), or in memory heap (1:requires malloc()).
  */
+#include<arch/arch.h>
+
+#if ARCH(I386) || ARCH(X86_64)
+#include <arch/x86_64/math/bitcount.h>
+#else
+#error Arch not supported.
+#endif
+
 #ifndef LZ4_HEAPMODE
 #define LZ4_HEAPMODE 0
 #endif
@@ -589,7 +597,7 @@ static unsigned LZ4_NbCommonBytes(reg_t val)
 #if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) ||                                \
                                                   ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \
     !defined(__TINYC__) && !defined(LZ4_FORCE_SW_BITCOUNT)
-            return (unsigned)__builtin_clzll((U64)val) >> 3;
+            return (unsigned)__clzll((U64)val) >> 3;
 #else
 #if 1
             /* this method is probably faster,
@@ -763,7 +771,7 @@ static unsigned LZ4_NbCommonBytes(reg_t val)
 #if (defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 3) ||                                \
                                                   ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 4))))) && \
     !defined(LZ4_FORCE_SW_BITCOUNT)
-            return (unsigned)__builtin_clz((U32)val) >> 3;
+            return (unsigned)__clz((U32)val) >> 3;
 #else
             val >>= 8;
             val = ((((val + 0x00FFFF00) | 0x00FFFFFF) + val) |

+ 46 - 35
kernel/process/process.c

@@ -42,18 +42,19 @@ extern void kernel_thread_func(void);
 
 ul _stack_start; // initial proc的栈基地址(虚拟地址)
 extern struct mm_struct initial_mm;
-struct thread_struct initial_thread =
-    {
-        .rbp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
-        .rsp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
-        .fs = KERNEL_DS,
-        .gs = KERNEL_DS,
-        .cr2 = 0,
-        .trap_num = 0,
-        .err_code = 0};
+struct thread_struct initial_thread = {
+    .rbp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
+    .rsp = (ul)(initial_proc_union.stack + STACK_SIZE / sizeof(ul)),
+    .fs = KERNEL_DS,
+    .gs = KERNEL_DS,
+    .cr2 = 0,
+    .trap_num = 0,
+    .err_code = 0,
+};
 
 // 初始化 初始进程的union ,并将其链接到.data.init_proc段内
-union proc_union initial_proc_union __attribute__((__section__(".data.init_proc_union"))) = {INITIAL_PROC(initial_proc_union.pcb)};
+union proc_union initial_proc_union
+    __attribute__((__section__(".data.init_proc_union"))) = {INITIAL_PROC(initial_proc_union.pcb)};
 
 struct process_control_block *initial_proc[MAX_CPU_NUM] = {&initial_proc_union.pcb, 0};
 
@@ -110,7 +111,8 @@ uint64_t process_exit_mm(struct process_control_block *pcb);
  * @param pcb 新的进程的pcb
  * @return uint64_t
  */
-uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start, uint64_t stack_size, struct pt_regs *current_regs);
+uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
+                             uint64_t stack_size, struct pt_regs *current_regs);
 
 void process_exit_thread(struct process_control_block *pcb);
 
@@ -128,13 +130,13 @@ void __switch_to(struct process_control_block *prev, struct process_control_bloc
 {
     initial_tss[proc_current_cpu_id].rsp0 = next->thread->rbp;
     // kdebug("next_rsp = %#018lx   ", next->thread->rsp);
-    //  set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2, initial_tss[0].ist1,
-    //           initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5, initial_tss[0].ist6, initial_tss[0].ist7);
+    //  set_tss64((uint *)phys_2_virt(TSS64_Table), initial_tss[0].rsp0, initial_tss[0].rsp1, initial_tss[0].rsp2,
+    //  initial_tss[0].ist1,
+    //           initial_tss[0].ist2, initial_tss[0].ist3, initial_tss[0].ist4, initial_tss[0].ist5,
+    //           initial_tss[0].ist6, initial_tss[0].ist7);
 
-    __asm__ __volatile__("movq	%%fs,	%0 \n\t"
-                         : "=a"(prev->thread->fs));
-    __asm__ __volatile__("movq	%%gs,	%0 \n\t"
-                         : "=a"(prev->thread->gs));
+    __asm__ __volatile__("movq	%%fs,	%0 \n\t" : "=a"(prev->thread->fs));
+    __asm__ __volatile__("movq	%%gs,	%0 \n\t" : "=a"(prev->thread->gs));
 
     __asm__ __volatile__("movq	%0,	%%fs \n\t" ::"a"(next->thread->fs));
     __asm__ __volatile__("movq	%0,	%%gs \n\t" ::"a"(next->thread->gs));
@@ -233,8 +235,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
     regs->rip = ehdr.e_entry;
     current_pcb->mm->code_addr_start = ehdr.e_entry;
 
-    // kdebug("ehdr.e_phoff=%#018lx\t ehdr.e_phentsize=%d, ehdr.e_phnum=%d", ehdr.e_phoff, ehdr.e_phentsize, ehdr.e_phnum);
-    // 将指针移动到program header处
+    // kdebug("ehdr.e_phoff=%#018lx\t ehdr.e_phentsize=%d, ehdr.e_phnum=%d", ehdr.e_phoff, ehdr.e_phentsize,
+    // ehdr.e_phnum); 将指针移动到program header处
     pos = ehdr.e_phoff;
     // 读取所有的phdr
     pos = filp->file_ops->lseek(filp, pos, SEEK_SET);
@@ -250,7 +252,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
     // 将程序加载到内存中
     for (int i = 0; i < ehdr.e_phnum; ++i, ++phdr)
     {
-        // kdebug("phdr[%d] phdr->p_offset=%#018lx phdr->p_vaddr=%#018lx phdr->p_memsz=%ld phdr->p_filesz=%ld  phdr->p_type=%d", i, phdr->p_offset, phdr->p_vaddr, phdr->p_memsz, phdr->p_filesz, phdr->p_type);
+        // kdebug("phdr[%d] phdr->p_offset=%#018lx phdr->p_vaddr=%#018lx phdr->p_memsz=%ld phdr->p_filesz=%ld
+        // phdr->p_type=%d", i, phdr->p_offset, phdr->p_vaddr, phdr->p_memsz, phdr->p_filesz, phdr->p_type);
 
         // 不是可加载的段
         if (phdr->p_type != PT_LOAD)
@@ -279,7 +282,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
             {
                 uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
                 struct vm_area_struct *vma = NULL;
-                int ret = mm_create_vma(current_pcb->mm, virt_base, PAGE_2M_SIZE, VM_USER | VM_ACCESS_FLAGS, NULL, &vma);
+                int ret =
+                    mm_create_vma(current_pcb->mm, virt_base, PAGE_2M_SIZE, VM_USER | VM_ACCESS_FLAGS, NULL, &vma);
 
                 // 防止内存泄露
                 if (ret == -EEXIST)
@@ -301,7 +305,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
                     uint64_t paddr = virt_2_phys((uint64_t)kmalloc(PAGE_4K_SIZE, 0));
 
                     struct vm_area_struct *vma = NULL;
-                    int val = mm_create_vma(current_pcb->mm, virt_base + off, PAGE_4K_SIZE, VM_USER | VM_ACCESS_FLAGS, NULL, &vma);
+                    int val = mm_create_vma(current_pcb->mm, virt_base + off, PAGE_4K_SIZE, VM_USER | VM_ACCESS_FLAGS,
+                                            NULL, &vma);
                     // kdebug("virt_base=%#018lx", virt_base + off);
                     if (val == -EEXIST)
                         kfree(phys_2_virt(paddr));
@@ -337,7 +342,8 @@ static int process_load_elf_file(struct pt_regs *regs, char *path)
     {
         struct vm_area_struct *vma = NULL;
         uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
-        int val = mm_create_vma(current_pcb->mm, current_pcb->mm->stack_start - PAGE_2M_SIZE, PAGE_2M_SIZE, VM_USER | VM_ACCESS_FLAGS, NULL, &vma);
+        int val = mm_create_vma(current_pcb->mm, current_pcb->mm->stack_start - PAGE_2M_SIZE, PAGE_2M_SIZE,
+                                VM_USER | VM_ACCESS_FLAGS, NULL, &vma);
         if (val == -EEXIST)
             free_pages(Phy_to_2M_Page(pa), 1);
         else
@@ -495,9 +501,7 @@ ul initial_kernel_thread(ul arg)
 
     // 对一些组件进行单元测试
     uint64_t tpid[] = {
-        ktest_start(ktest_test_bitree, 0),
-        ktest_start(ktest_test_kfifo, 0),
-        ktest_start(ktest_test_mutex, 0),
+        ktest_start(ktest_test_bitree, 0), ktest_start(ktest_test_kfifo, 0), ktest_start(ktest_test_mutex, 0),
         ktest_start(ktest_test_idr, 0),
         // usb_pid,
     };
@@ -525,14 +529,15 @@ ul initial_kernel_thread(ul arg)
     regs = (struct pt_regs *)current_pcb->thread->rsp;
     // kdebug("current_pcb->thread->rsp=%#018lx", current_pcb->thread->rsp);
     current_pcb->flags = 0;
-    // 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数  这里的设计思路和switch_proc类似
-    // 加载用户态程序:shell.elf
+    // 将返回用户层的代码压入堆栈,向rdx传入regs的地址,然后jmp到do_execve这个系统调用api的处理函数
+    // 这里的设计思路和switch_proc类似 加载用户态程序:shell.elf
     char init_path[] = "/shell.elf";
     uint64_t addr = (uint64_t)&init_path;
     __asm__ __volatile__("movq %1, %%rsp   \n\t"
                          "pushq %2    \n\t"
                          "jmp do_execve  \n\t" ::"D"(current_pcb->thread->rsp),
-                         "m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/shell.elf"), "c"(NULL), "d"(NULL)
+                         "m"(current_pcb->thread->rsp), "m"(current_pcb->thread->rip), "S"("/shell.elf"), "c"(NULL),
+                         "d"(NULL)
                          : "memory");
 
     return 1;
@@ -662,7 +667,8 @@ 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)
+unsigned long do_fork(struct pt_regs *regs, unsigned long clone_flags, unsigned long stack_start,
+                      unsigned long stack_size)
 {
     int retval = 0;
     struct process_control_block *tsk = NULL;
@@ -922,7 +928,8 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
     memset(phys_2_virt(new_mms->pgd), 0, PAGE_4K_SIZE / 2);
 
     // 拷贝内核空间的页表指针
-    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]->mm->pgd) + 256, PAGE_4K_SIZE / 2);
+    memcpy(phys_2_virt(new_mms->pgd) + 256, phys_2_virt(initial_proc[proc_current_cpu_id]->mm->pgd) + 256,
+           PAGE_4K_SIZE / 2);
 
     uint64_t *current_pgd = (uint64_t *)phys_2_virt(current_pcb->mm->pgd);
 
@@ -948,14 +955,16 @@ uint64_t process_copy_mm(uint64_t clone_flags, struct process_control_block *pcb
                 uint64_t pa = alloc_pages(ZONE_NORMAL, 1, PAGE_PGT_MAPPED)->addr_phys;
 
                 struct vm_area_struct *new_vma = NULL;
-                int ret = mm_create_vma(new_mms, vma->vm_start + i * PAGE_2M_SIZE, PAGE_2M_SIZE, vma->vm_flags, vma->vm_ops, &new_vma);
+                int ret = mm_create_vma(new_mms, vma->vm_start + i * PAGE_2M_SIZE, PAGE_2M_SIZE, vma->vm_flags,
+                                        vma->vm_ops, &new_vma);
                 // 防止内存泄露
                 if (unlikely(ret == -EEXIST))
                     free_pages(Phy_to_2M_Page(pa), 1);
                 else
                     mm_map_vma(new_vma, pa, 0, PAGE_2M_SIZE);
 
-                memcpy((void *)phys_2_virt(pa), (void *)(vma->vm_start + i * PAGE_2M_SIZE), (vma_size >= PAGE_2M_SIZE) ? PAGE_2M_SIZE : vma_size);
+                memcpy((void *)phys_2_virt(pa), (void *)(vma->vm_start + i * PAGE_2M_SIZE),
+                       (vma_size >= PAGE_2M_SIZE) ? PAGE_2M_SIZE : vma_size);
                 vma_size -= PAGE_2M_SIZE;
             }
         }
@@ -1091,7 +1100,8 @@ static int process_rewrite_rbp(struct pt_regs *new_regs, struct process_control_
  * @param pcb 新的进程的pcb
  * @return uint64_t
  */
-uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start, uint64_t stack_size, struct pt_regs *current_regs)
+uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block *pcb, uint64_t stack_start,
+                             uint64_t stack_size, struct pt_regs *current_regs)
 {
     // 将线程结构体放置在pcb后方
     struct thread_struct *thd = (struct thread_struct *)(pcb + 1);
@@ -1122,7 +1132,8 @@ uint64_t process_copy_thread(uint64_t clone_flags, struct process_control_block
     // 设置子进程的返回值为0
     child_regs->rax = 0;
     if (pcb->flags & PF_KFORK)
-        thd->rbp = (uint64_t)(child_regs + 1); // 设置新的内核线程开始执行时的rbp(也就是进入ret_from_system_call时的rbp)
+        thd->rbp =
+            (uint64_t)(child_regs + 1); // 设置新的内核线程开始执行时的rbp(也就是进入ret_from_system_call时的rbp)
     else
         thd->rbp = (uint64_t)pcb + STACK_SIZE;