diff --git a/docs/kernel/core_api/data_structures.md b/docs/kernel/core_api/data_structures.md index 1d8aa519..daf9cbc2 100644 --- a/docs/kernel/core_api/data_structures.md +++ b/docs/kernel/core_api/data_structures.md @@ -259,7 +259,7 @@    ida的主要作用是分配+管理id. 它能分配一个最小的, 未被分配出去的id. 当您需要管理某个数据结构时, 可能需要使用id来区分不同的目标. 这个时候, ida将会是很好的选择. 因为ida的十分高效, 运行常数相对数组更小, 而且提供了基本管理id需要用到的功能, 值得您试一试. -  IDA定义于`idr.h`文件中. 您通过`DECLARE_IDA(my_ida)`来创建一个ida对象, 或者`struct ida my_ida; ida_init(my_ida);`来初始化一个ida. +  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)` diff --git a/kernel/ktest/test-idr.c b/kernel/ktest/test-idr.c index e4d579f0..f01cdaaa 100644 --- a/kernel/ktest/test-idr.c +++ b/kernel/ktest/test-idr.c @@ -103,7 +103,7 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1) assert(idr_find(&k_idr, a[i]) == NULL); } - for (int i = 0; i < 128; i++) + for (int i = 0; i < 128; i++) { assert(idr_count(&k_idr, i) == 0); } @@ -115,7 +115,7 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1) assert(a[i] == i); } - for (int i = 0; i < 128; i++) + for (int i = 0; i < 128; i++) { assert(idr_count(&k_idr, i)); } @@ -194,7 +194,7 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1) // const int N = 1048576; const int M = 2e5; - int tmp=0; + int tmp = 0; for (int i = 0; i < N; i++) { barrier(); @@ -213,7 +213,7 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1) assert(idr_count(&k_idr, i)); barrier(); } -// kdebug("111111"); + // kdebug("111111"); // 正向: M 个ID for (int i = 0; i < M; i++) { @@ -233,7 +233,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("3333333"); + // kdebug("3333333"); // 重新插入数据 for (int i = 0; i < N; i++) { @@ -245,19 +245,19 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1) assert(ptr != NULL); assert(*ptr == i); } -// kdebug("4444444444"); + // kdebug("4444444444"); assert(k_idr.top != NULL); for (int i = 0; i < M; i++) { assert(idr_replace(&k_idr, NULL, i) == 0); } -// kdebug("555555555555555555"); + // kdebug("555555555555555555"); // 销毁 idr_destroy(&k_idr); assert(k_idr.id_free_cnt == 0); assert(k_idr.free_list == NULL); -// kdebug("666666666666"); + // kdebug("666666666666"); return 0; } @@ -355,19 +355,19 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1) DECLARE_IDR(k_idr); idr_init(&k_idr); - const int N =91173; - int tmp; + const int N = 91173; + static uint32_t tmp; for (int i = 1; i <= 20; i++) { - int M = N / i, T = M / 3, O = 2 * T; + int M = N / i, T = M / 3, b = 2 * T; for (int j = 0; j < M; j++) { assert(idr_alloc(&k_idr, &tmp, &tmp) == 0); assert(tmp == j); } - for (int j = O; j >= T; j--) + for (int j = b; j >= T; j--) { int *ptr = idr_find(&k_idr, j); assert(ptr != NULL); @@ -375,7 +375,7 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1) idr_remove(&k_idr, j); } - for (int j = O + 1; j < M; j++) + for (int j = b + 1; j < M; j++) { int *ptr = idr_find(&k_idr, j); assert(ptr != NULL); @@ -427,7 +427,7 @@ static long ktest_idr_case5(uint64_t arg0, uint64_t arg1) for (int i = 0; i < N; i++) { int *ptr; - int flags = idr_replace_get_old(&k_idr, &a[(i + 1) % N], i, (void*)&ptr); + int flags = idr_replace_get_old(&k_idr, &a[(i + 1) % N], i, (void *)&ptr); assert(flags == 0); // 0 是成功 assert(ptr != NULL); assert(*ptr == i); @@ -481,62 +481,88 @@ static long ktest_idr_case6(uint64_t arg0, uint64_t arg1) for (int i = 0; i < N; i++) { - int p_id;io_sfence(); - assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence(); - assert(p_id == i);io_sfence(); + 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);io_sfence(); + assert(ida_count(&k_ida, i) == 1); + io_sfence(); } for (int i = N - 1; i >= 0; i--) { - ida_remove(&k_ida, i);io_sfence(); - assert(ida_count(&k_ida, i) == 0);io_sfence(); + 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;io_sfence(); - assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence(); - assert(p_id == i);io_sfence(); + 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);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(); + 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;io_sfence(); - assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence(); - assert(p_id == i);io_sfence(); + 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);io_sfence(); - assert(ida_count(&k_ida, i) == 0);io_sfence(); + 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);io_sfence(); - assert(ida_count(&k_ida, i) == 0);io_sfence(); + ida_remove(&k_ida, i); + io_sfence(); + assert(ida_count(&k_ida, i) == 0); + io_sfence(); } - 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(); + 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; } @@ -551,7 +577,7 @@ static ktest_case_table kt_idr_func_table[] = { ktest_idr_case6, }; -int ktest_test_idr(void* arg) +int ktest_test_idr(void *arg) { kTEST("Testing idr..."); unsigned int sz = sizeof(kt_idr_func_table) / sizeof(ktest_case_table); diff --git a/kernel/lib/idr.c b/kernel/lib/idr.c index 71705d24..54a585b9 100644 --- a/kernel/lib/idr.c +++ b/kernel/lib/idr.c @@ -1,7 +1,5 @@ #include #include -#pragma GCC push_options -#pragma GCC optimize("O0") /** * @brief 更换两个idr_layer指针 @@ -222,7 +220,7 @@ static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_ } // 处理叶子节点的full/bitmap标记 - int layer_id = __id & IDR_MASK; + int64_t layer_id = __id & IDR_MASK; if (mark == 2) stk[0]->full |= (1ull << layer_id); if (mark >= 1) @@ -270,7 +268,7 @@ static __always_inline int __idr_get_path(struct idr *idp, int id, struct idr_la while (layer >= 0) { stk[layer] = cur_layer; - int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; + int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; if (unlikely(((cur_layer->bitmap >> layer_id) & 1) == 0)) { @@ -303,7 +301,7 @@ static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr } // 处理叶子节点的full/bitmap标记 - int layer_id = __id & IDR_MASK; + int64_t layer_id = __id & IDR_MASK; if (mark == 0) // 叶子的某个插槽为空 { stk[0]->ary[layer_id] = NULL; @@ -523,18 +521,24 @@ void *idr_find(struct idr *idp, int id) int64_t __id = (int64_t)id; if (unlikely(idp->top == NULL || __id < 0)) { - kwarn("idr-find: 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 + barrier(); // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL if ((__id >> ((layer + 1) * IDR_BITS)) > 0) return NULL; - while (layer >= 0 && cur_layer) + barrier(); + barrier(); + int64_t layer_id = 0; + while (layer >= 0 && cur_layer != NULL) { - int layer_id = (__id >> (IDR_BITS * layer)) & IDR_MASK; + barrier(); + layer_id = (__id >> (IDR_BITS * layer)) & IDR_MASK; + barrier(); cur_layer = cur_layer->ary[layer_id]; --layer; } @@ -606,10 +610,10 @@ void *idr_find_next_getid(struct idr *idp, int64_t start_id, int *nextid) unsigned long t_bitmap = (cur_layer->bitmap >> pos_i[layer]); if (t_bitmap) // 进一步递归到儿子下面去 { - int layer_id = __lowbit_id(t_bitmap) + pos_i[layer]; + int64_t layer_id = __lowbit_id(t_bitmap) + pos_i[layer]; // 特别情况 - if ((cur_state == false) && layer_id > pos_i[layer] > 0) + if ((cur_state == false) && (layer_id > pos_i[layer] > 0)) cur_state = true; pos_i[layer] = layer_id; @@ -685,7 +689,7 @@ int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **old_ptr) while (layer > 0) { - int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; + int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; if (unlikely(NULL == cur_layer->ary[layer_id])) return -ENOMEM; @@ -735,8 +739,6 @@ bool idr_empty(struct idr *idp) return false; } -#pragma GCC push_options -#pragma GCC optimize("O0") static bool __idr_cnt_pd(struct idr_layer *cur_layer, int layer_id) { @@ -757,7 +759,7 @@ static bool __idr_cnt(int layer, int id, struct idr_layer *cur_layer) { barrier(); - int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; + int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK; barrier(); @@ -774,7 +776,6 @@ static bool __idr_cnt(int layer, int id, struct idr_layer *cur_layer) } return true; } -#pragma GCC pop_options /** * @brief 这个函数是可以用于判断一个ID是否已经被分配的。 @@ -934,7 +935,7 @@ int ida_alloc(struct ida *ida_p, int *p_id) if (unlikely(idr_id < 0)) return idr_id; - int layer_id = idr_id & IDR_MASK; + int64_t layer_id = idr_id & IDR_MASK; if (NULL == stk[0]->ary[layer_id]) stk[0]->ary[layer_id] = __get_ida_bitmap(ida_p, 0); @@ -1051,5 +1052,3 @@ bool ida_empty(struct ida *ida_p) return false; } - -#pragma GCC pop_options \ No newline at end of file