mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +00:00
暂时解决idr不能跑的问题(目前只能在o1下运行,o0存在栈损坏错误)
This commit is contained in:
parent
d53ddde95d
commit
a274d5a01d
@ -259,7 +259,7 @@
|
|||||||
|
|
||||||
   ida的主要作用是分配+管理id. 它能分配一个最小的, 未被分配出去的id. 当您需要管理某个数据结构时, 可能需要使用id来区分不同的目标. 这个时候, ida将会是很好的选择. 因为ida的十分高效, 运行常数相对数组更小, 而且提供了基本管理id需要用到的功能, 值得您试一试.
|
   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
|
### ida_init
|
||||||
`void ida_init(struct ida *ida_p)`
|
`void ida_init(struct ida *ida_p)`
|
||||||
|
@ -103,7 +103,7 @@ static long ktest_idr_case1(uint64_t arg0, uint64_t arg1)
|
|||||||
assert(idr_find(&k_idr, a[i]) == NULL);
|
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);
|
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);
|
assert(a[i] == i);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 128; i++)
|
for (int i = 0; i < 128; i++)
|
||||||
{
|
{
|
||||||
assert(idr_count(&k_idr, 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 N = 1048576;
|
||||||
const int M = 2e5;
|
const int M = 2e5;
|
||||||
|
|
||||||
int tmp=0;
|
int tmp = 0;
|
||||||
for (int i = 0; i < N; i++)
|
for (int i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
barrier();
|
barrier();
|
||||||
@ -213,7 +213,7 @@ static long ktest_idr_case2(uint64_t arg0, uint64_t arg1)
|
|||||||
assert(idr_count(&k_idr, i));
|
assert(idr_count(&k_idr, i));
|
||||||
barrier();
|
barrier();
|
||||||
}
|
}
|
||||||
// kdebug("111111");
|
// kdebug("111111");
|
||||||
// 正向: M 个ID
|
// 正向: M 个ID
|
||||||
for (int i = 0; i < M; i++)
|
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);
|
idr_remove(&k_idr, i);
|
||||||
assert(idr_find(&k_idr, i) == NULL);
|
assert(idr_find(&k_idr, i) == NULL);
|
||||||
}
|
}
|
||||||
// kdebug("3333333");
|
// kdebug("3333333");
|
||||||
// 重新插入数据
|
// 重新插入数据
|
||||||
for (int i = 0; i < N; i++)
|
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 != NULL);
|
||||||
assert(*ptr == i);
|
assert(*ptr == i);
|
||||||
}
|
}
|
||||||
// kdebug("4444444444");
|
// kdebug("4444444444");
|
||||||
assert(k_idr.top != NULL);
|
assert(k_idr.top != NULL);
|
||||||
|
|
||||||
for (int i = 0; i < M; i++)
|
for (int i = 0; i < M; i++)
|
||||||
{
|
{
|
||||||
assert(idr_replace(&k_idr, NULL, i) == 0);
|
assert(idr_replace(&k_idr, NULL, i) == 0);
|
||||||
}
|
}
|
||||||
// kdebug("555555555555555555");
|
// kdebug("555555555555555555");
|
||||||
// 销毁
|
// 销毁
|
||||||
idr_destroy(&k_idr);
|
idr_destroy(&k_idr);
|
||||||
assert(k_idr.id_free_cnt == 0);
|
assert(k_idr.id_free_cnt == 0);
|
||||||
assert(k_idr.free_list == NULL);
|
assert(k_idr.free_list == NULL);
|
||||||
// kdebug("666666666666");
|
// kdebug("666666666666");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,19 +355,19 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1)
|
|||||||
DECLARE_IDR(k_idr);
|
DECLARE_IDR(k_idr);
|
||||||
idr_init(&k_idr);
|
idr_init(&k_idr);
|
||||||
|
|
||||||
const int N =91173;
|
const int N = 91173;
|
||||||
int tmp;
|
static uint32_t tmp;
|
||||||
|
|
||||||
for (int i = 1; i <= 20; i++)
|
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++)
|
for (int j = 0; j < M; j++)
|
||||||
{
|
{
|
||||||
assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
|
assert(idr_alloc(&k_idr, &tmp, &tmp) == 0);
|
||||||
assert(tmp == j);
|
assert(tmp == j);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = O; j >= T; j--)
|
for (int j = b; j >= T; j--)
|
||||||
{
|
{
|
||||||
int *ptr = idr_find(&k_idr, j);
|
int *ptr = idr_find(&k_idr, j);
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
@ -375,7 +375,7 @@ static long ktest_idr_case4(uint64_t arg0, uint64_t arg1)
|
|||||||
idr_remove(&k_idr, j);
|
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);
|
int *ptr = idr_find(&k_idr, j);
|
||||||
assert(ptr != NULL);
|
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++)
|
for (int i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
int *ptr;
|
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(flags == 0); // 0 是成功
|
||||||
assert(ptr != NULL);
|
assert(ptr != NULL);
|
||||||
assert(*ptr == i);
|
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++)
|
for (int i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
int p_id;io_sfence();
|
int p_id;
|
||||||
assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
|
io_sfence();
|
||||||
assert(p_id == i);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++)
|
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--)
|
for (int i = N - 1; i >= 0; i--)
|
||||||
{
|
{
|
||||||
ida_remove(&k_ida, i);io_sfence();
|
ida_remove(&k_ida, i);
|
||||||
assert(ida_count(&k_ida, i) == 0);io_sfence();
|
io_sfence();
|
||||||
|
assert(ida_count(&k_ida, i) == 0);
|
||||||
|
io_sfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(k_ida.idr.top == NULL);
|
assert(k_ida.idr.top == NULL);
|
||||||
|
|
||||||
for (int i = 0; i < N; i++)
|
for (int i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
int p_id;io_sfence();
|
int p_id;
|
||||||
assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
|
io_sfence();
|
||||||
assert(p_id == i);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();
|
assert(k_ida.idr.top != NULL);
|
||||||
ida_destroy(&k_ida);io_sfence();
|
io_sfence();
|
||||||
assert(k_ida.idr.top == NULL);io_sfence();
|
ida_destroy(&k_ida);
|
||||||
assert(k_ida.free_list == NULL);io_sfence();
|
io_sfence();
|
||||||
assert(ida_empty(&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
|
// 测试destroy之后能否重新获取ID
|
||||||
for (int i = 0; i < N; i++)
|
for (int i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
int p_id;io_sfence();
|
int p_id;
|
||||||
assert(ida_alloc(&k_ida, &p_id) == 0);io_sfence();
|
io_sfence();
|
||||||
assert(p_id == i);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++)
|
for (int i = 0; i < N / 3; i++)
|
||||||
{
|
{
|
||||||
ida_remove(&k_ida, i);io_sfence();
|
ida_remove(&k_ida, i);
|
||||||
assert(ida_count(&k_ida, i) == 0);io_sfence();
|
io_sfence();
|
||||||
|
assert(ida_count(&k_ida, i) == 0);
|
||||||
|
io_sfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 2 * N / 3; i < N; i++)
|
for (int i = 2 * N / 3; i < N; i++)
|
||||||
{
|
{
|
||||||
ida_remove(&k_ida, i);io_sfence();
|
ida_remove(&k_ida, i);
|
||||||
assert(ida_count(&k_ida, i) == 0);io_sfence();
|
io_sfence();
|
||||||
|
assert(ida_count(&k_ida, i) == 0);
|
||||||
|
io_sfence();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(k_ida.idr.top != NULL);io_sfence();
|
assert(k_ida.idr.top != NULL);
|
||||||
ida_destroy(&k_ida);io_sfence();
|
io_sfence();
|
||||||
assert(k_ida.idr.top == NULL);io_sfence();
|
ida_destroy(&k_ida);
|
||||||
assert(k_ida.free_list == NULL);io_sfence();
|
io_sfence();
|
||||||
assert(ida_empty(&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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -551,7 +577,7 @@ static ktest_case_table kt_idr_func_table[] = {
|
|||||||
ktest_idr_case6,
|
ktest_idr_case6,
|
||||||
};
|
};
|
||||||
|
|
||||||
int ktest_test_idr(void* arg)
|
int ktest_test_idr(void *arg)
|
||||||
{
|
{
|
||||||
kTEST("Testing idr...");
|
kTEST("Testing idr...");
|
||||||
unsigned int sz = sizeof(kt_idr_func_table) / sizeof(ktest_case_table);
|
unsigned int sz = sizeof(kt_idr_func_table) / sizeof(ktest_case_table);
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#include <common/idr.h>
|
#include <common/idr.h>
|
||||||
#include <mm/slab.h>
|
#include <mm/slab.h>
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize("O0")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 更换两个idr_layer指针
|
* @brief 更换两个idr_layer指针
|
||||||
@ -222,7 +220,7 @@ static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 处理叶子节点的full/bitmap标记
|
// 处理叶子节点的full/bitmap标记
|
||||||
int layer_id = __id & IDR_MASK;
|
int64_t layer_id = __id & IDR_MASK;
|
||||||
if (mark == 2)
|
if (mark == 2)
|
||||||
stk[0]->full |= (1ull << layer_id);
|
stk[0]->full |= (1ull << layer_id);
|
||||||
if (mark >= 1)
|
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)
|
while (layer >= 0)
|
||||||
{
|
{
|
||||||
stk[layer] = cur_layer;
|
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))
|
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标记
|
// 处理叶子节点的full/bitmap标记
|
||||||
int layer_id = __id & IDR_MASK;
|
int64_t layer_id = __id & IDR_MASK;
|
||||||
if (mark == 0) // 叶子的某个插槽为空
|
if (mark == 0) // 叶子的某个插槽为空
|
||||||
{
|
{
|
||||||
stk[0]->ary[layer_id] = NULL;
|
stk[0]->ary[layer_id] = NULL;
|
||||||
@ -523,18 +521,24 @@ void *idr_find(struct idr *idp, int id)
|
|||||||
int64_t __id = (int64_t)id;
|
int64_t __id = (int64_t)id;
|
||||||
if (unlikely(idp->top == NULL || __id < 0))
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct idr_layer *cur_layer = idp->top;
|
struct idr_layer *cur_layer = idp->top;
|
||||||
int layer = cur_layer->layer; // 特判NULL
|
int layer = cur_layer->layer; // 特判NULL
|
||||||
|
barrier();
|
||||||
// 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
|
// 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
|
||||||
if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
|
if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
|
||||||
return NULL;
|
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];
|
cur_layer = cur_layer->ary[layer_id];
|
||||||
--layer;
|
--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]);
|
unsigned long t_bitmap = (cur_layer->bitmap >> pos_i[layer]);
|
||||||
if (t_bitmap) // 进一步递归到儿子下面去
|
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;
|
cur_state = true;
|
||||||
|
|
||||||
pos_i[layer] = layer_id;
|
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)
|
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]))
|
if (unlikely(NULL == cur_layer->ary[layer_id]))
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@ -735,8 +739,6 @@ bool idr_empty(struct idr *idp)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#pragma GCC push_options
|
|
||||||
#pragma GCC optimize("O0")
|
|
||||||
|
|
||||||
static bool __idr_cnt_pd(struct idr_layer *cur_layer, int layer_id)
|
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();
|
barrier();
|
||||||
|
|
||||||
int layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
|
int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
|
||||||
|
|
||||||
barrier();
|
barrier();
|
||||||
|
|
||||||
@ -774,7 +776,6 @@ static bool __idr_cnt(int layer, int id, struct idr_layer *cur_layer)
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#pragma GCC pop_options
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 这个函数是可以用于判断一个ID是否已经被分配的。
|
* @brief 这个函数是可以用于判断一个ID是否已经被分配的。
|
||||||
@ -934,7 +935,7 @@ int ida_alloc(struct ida *ida_p, int *p_id)
|
|||||||
if (unlikely(idr_id < 0))
|
if (unlikely(idr_id < 0))
|
||||||
return idr_id;
|
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])
|
if (NULL == stk[0]->ary[layer_id])
|
||||||
stk[0]->ary[layer_id] = __get_ida_bitmap(ida_p, 0);
|
stk[0]->ary[layer_id] = __get_ida_bitmap(ida_p, 0);
|
||||||
@ -1051,5 +1052,3 @@ bool ida_empty(struct ida *ida_p)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma GCC pop_options
|
|
Loading…
x
Reference in New Issue
Block a user