1 #include <common/idr.h>
2 #include <mm/slab.h>
3 
4 /**
5  * @brief 更换两个idr_layer指针
6  *
7  * @param a
8  * @param b
9  */
__swap(struct idr_layer ** a,struct idr_layer ** b)10 static void __swap(struct idr_layer **a, struct idr_layer **b)
11 {
12     struct idr_layer *t = *a;
13     *a = *b, *b = t;
14 }
15 
16 /**
17  * @brief 初始化idr - 你需要保证函数调用之前 free_list指针 为空
18  *
19  * @param idp
20  */
idr_init(struct idr * idp)21 void idr_init(struct idr *idp)
22 {
23     memset(idp, 0, sizeof(struct idr));
24     spin_init(&idp->lock);
25 }
26 
27 /**
28  * @brief 向idr的free_list中添加一个节点(空节点)
29  *
30  * @param idp
31  * @param p
32  */
__move_to_free_list(struct idr * idp,struct idr_layer * p)33 static void __move_to_free_list(struct idr *idp, struct idr_layer *p)
34 {
35     unsigned long flags;
36     spin_lock_irqsave(&idp->lock, flags);
37 
38     // 插入free_list
39     p->ary[0] = idp->free_list;
40     io_sfence();
41     idp->free_list = p;
42     io_sfence();
43     ++(idp->id_free_cnt);
44 
45     spin_unlock_irqrestore(&idp->lock, flags);
46 }
47 
48 /**
49  * @brief Get the free_idr_layer from free list object
50  *
51  * @param idp
52  * @return void*
53  */
__get_from_free_list(struct idr * idp)54 static void *__get_from_free_list(struct idr *idp)
55 {
56     if (idp->id_free_cnt == 0)
57     {
58         if (idr_preload(idp, 0) != 0)
59         {
60             kBUG("idr-module find a BUG: get free node fail.(Possible ENOMEM error)");
61             return NULL;
62         }
63     }
64 
65     unsigned long flags;
66     spin_lock_irqsave(&idp->lock, flags);
67 
68     // free_list还有节点
69     struct idr_layer *item = idp->free_list;
70 
71     if (item == NULL)
72     {
73         BUG_ON(1);
74     }
75 
76     io_sfence();
77     idp->free_list = idp->free_list->ary[0];
78     io_sfence();
79     item->ary[0] = NULL; // 记得清空原来的数据
80     io_sfence();
81     --(idp->id_free_cnt);
82 
83     spin_unlock_irqrestore(&idp->lock, flags);
84 
85     return item;
86 }
87 
88 /**
89  * @brief 为idr预分配空间
90  *
91  * @param idp
92  * @param gfp_mask
93  * @return int (如果分配成功,将返回0; 否则返回负数 -ENOMEM, 有可能是内存空间不够)
94  */
idr_preload(struct idr * idp,gfp_t gfp_mask)95 int idr_preload(struct idr *idp, gfp_t gfp_mask)
96 {
97     int timer = 0;
98     while (idp->id_free_cnt < IDR_FREE_MAX)
99     {
100         struct idr_layer *new_one;
101         new_one = kzalloc(sizeof(struct idr_layer), gfp_mask); // 默认清空?
102         if (unlikely(new_one == NULL))
103             return -ENOMEM;
104 
105         __move_to_free_list(idp, new_one);
106         timer++;
107     }
108     return 0;
109 }
110 
111 /**
112  * @brief 释放一个layer的空间
113  *
114  * @param p
115  */
__idr_layer_free(struct idr_layer * p)116 static void __idr_layer_free(struct idr_layer *p)
117 {
118     kfree(p);
119 }
120 
121 /**
122  * @brief 向上生长一层idr_layer
123  *
124  * @param idp
125  * @return int (0生长成功, 否则返回错误码)
126  */
__idr_grow(struct idr * idp)127 static int __idr_grow(struct idr *idp)
128 {
129     struct idr_layer *new_node = __get_from_free_list(idp);
130     if (NULL == new_node)
131         return -ENOMEM;
132 
133     __swap(&new_node, &idp->top);
134 
135     idp->top->ary[0] = new_node;
136     idp->top->layer = new_node ? (new_node->layer + 1) : 0; // 注意特判空指针
137     idp->top->bitmap = 0;
138     idp->top->full = 0; // clear
139 
140     if (new_node != NULL) // 设置第0位 = 1, 同时维护树的大小
141     {
142         idp->top->bitmap = 1;
143     }
144     if (new_node != NULL && new_node->full == IDR_FULL)
145     {
146         idp->top->full = 1; // 别忘了初始化 full
147     }
148 
149     return 0;
150 }
151 
152 /**
153  * @brief 获取一个没有被占领的ID
154  *
155  * @param idp
156  * @param stk  栈空间
157  * @return int (负数表示获取ID失败, [0 <= id && id <= INT_MAX] 则获取ID成功)
158  */
__idr_get_empty_slot(struct idr * idp,struct idr_layer ** stk)159 static int __idr_get_empty_slot(struct idr *idp, struct idr_layer **stk)
160 {
161     // 注意特判 idp->top == NULL
162     while (NULL == idp->top || idp->top->full == IDR_FULL)
163         if (__idr_grow(idp) != 0)
164             return -ENOMEM;
165 
166     int64_t id = 0;
167     int layer = idp->top->layer;
168     BUG_ON(layer + 1 >= 7);
169     stk[layer + 1] = NULL; // 标志为数组末尾
170 
171     struct idr_layer *cur_layer = idp->top;
172     while (layer >= 0)
173     {
174         stk[layer] = cur_layer;
175         int pos = __lowbit_id(~cur_layer->full);
176 
177         if (unlikely(pos < 0))
178         {
179             kBUG("Value 'cur_layer->full' had been full;"
180                  "but __idr_get_empty_slot still try to insert a value.");
181         }
182 
183         id = (id << IDR_BITS) | pos;
184         cur_layer = cur_layer->ary[pos];
185 
186         if (layer > 0 && NULL == cur_layer) // 只有非叶子节点才需要开辟儿子节点
187         {
188             // 初始化儿子节点
189             cur_layer = __get_from_free_list(idp);
190             if (NULL == cur_layer)
191                 return -ENOMEM;
192             cur_layer->layer = layer - 1; // 儿子节点的layer
193             cur_layer->full = 0;
194             cur_layer->bitmap = 0;
195 
196             stk[layer]->ary[pos] = cur_layer; // 最后别忘了记录儿子节点
197         }
198 
199         --layer;
200     }
201 
202     return id;
203 }
204 
205 /**
206  * @brief 更新full对象 (辅助函数,内部没有边界特判)
207  *
208  * @param idp
209  * @param id
210  * @param stk  需要保证stk数组末尾是NULL
211  * @param mark 0代表叶子空, 1代表叶子非空但未满, 2代表满
212  */
__idr_mark_full(struct idr * idp,int id,struct idr_layer ** stk,int mark)213 static __always_inline void __idr_mark_full(struct idr *idp, int id, struct idr_layer **stk, int mark)
214 {
215     int64_t __id = (int64_t)id;
216     if (unlikely(NULL == stk[0] || NULL == idp->top))
217     {
218         kBUG("idr-module find a BUG: idp->top can't be NULL.");
219         return;
220     }
221 
222     // 处理叶子节点的full/bitmap标记
223     int64_t layer_id = __id & IDR_MASK;
224     if (mark == 2)
225         stk[0]->full |= (1ull << layer_id);
226     if (mark >= 1)
227         stk[0]->bitmap |= (1ull << layer_id);
228 
229     for (int i = 1; stk[i]; ++i)
230     {
231         __id >>= IDR_BITS;
232         layer_id = __id & IDR_MASK;
233 
234         stk[i]->bitmap |= (1ull << layer_id);
235         if (stk[i - 1]->full == IDR_FULL)
236             stk[i]->full |= (1ull << layer_id);
237     }
238 }
239 
240 /**
241  * @brief 提取一条已存在的路径
242  *
243  * @param idp
244  * @param id
245  * @param stk
246  * @return int (0表示没有这条路径, 1表示找到这条路径)
247  */
__idr_get_path(struct idr * idp,int id,struct idr_layer ** stk)248 static __always_inline int __idr_get_path(struct idr *idp, int id, struct idr_layer **stk)
249 {
250     int64_t __id = (int64_t)id;
251     if (unlikely(idp->top == NULL || __id < 0))
252     {
253         kBUG("idr-module find a BUG: idp->top can't be NULL and id must be non-negative.");
254         return 0;
255     }
256 
257     struct idr_layer *cur_layer = idp->top;
258     int layer = cur_layer->layer;
259     stk[layer + 1] = NULL; // 标志数组结尾
260 
261     if (unlikely((__id >> ((layer + 1ull) * IDR_BITS)) > 0))
262     {
263         kBUG("idr-module find a BUG: id is invalid.");
264         return 0;
265     }
266 
267     // 提取路径
268     while (layer >= 0)
269     {
270         stk[layer] = cur_layer;
271         int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
272 
273         if (unlikely(((cur_layer->bitmap >> layer_id) & 1) == 0))
274         {
275             kBUG("idr-module find a BUG: no-such son.");
276             return 0; // 没有这一个儿子
277         }
278 
279         cur_layer = cur_layer->ary[layer_id];
280         --layer;
281     }
282 
283     return 1;
284 }
285 
286 /**
287  * @brief 更新full对象 (辅助函数,内部没有边界特判)
288  *
289  * @param idp
290  * @param id
291  * @param stk 需要保证stk数组末尾是NULL
292  * @param mark 0代表叶子空, 1代表叶子非空但未满, 2代表满
293  */
__idr_erase_full(struct idr * idp,int id,struct idr_layer ** stk,int mark)294 static __always_inline void __idr_erase_full(struct idr *idp, int id, struct idr_layer **stk, int mark)
295 {
296     int64_t __id = (int64_t)id;
297     if (unlikely(NULL == stk[0] || NULL == idp->top))
298     {
299         kBUG("idr-module find a BUG: idp->top can't be NULL.");
300         return;
301     }
302 
303     // 处理叶子节点的full/bitmap标记
304     int64_t layer_id = __id & IDR_MASK;
305     if (mark == 0) // 叶子的某个插槽为空
306     {
307         stk[0]->ary[layer_id] = NULL;
308         stk[0]->bitmap ^= (1ull << layer_id);
309     }
310     if (mark != 2 && ((stk[0]->full >> layer_id) & 1))
311         stk[0]->full ^= (1ull << layer_id);
312 
313     // 删除节点
314     for (int layer = 1; stk[layer]; ++layer)
315     {
316         __id >>= IDR_BITS;
317         layer_id = __id & IDR_MASK;
318 
319         if (NULL == stk[layer - 1]->bitmap) // 儿子是空节点
320         {
321             stk[layer]->ary[layer_id] = NULL;
322             stk[layer]->bitmap ^= (1ull << layer_id);
323 
324             if ((stk[layer]->full >> layer_id) & 1)
325                 stk[layer]->full ^= (1ull << layer_id);
326 
327             __idr_layer_free(stk[layer - 1]);
328             stk[layer - 1] = NULL; // 释放空间记得设置为 NULL
329         }
330         else if (stk[layer - 1]->full != IDR_FULL)
331         {
332             if ((stk[layer]->full >> layer_id) & 1)
333                 stk[layer]->full ^= (1ull << layer_id);
334         }
335     }
336 
337     // 特判根节点是否只剩0号儿子节点 (注意还要layer > 0)
338     // (注意,有可能出现idp->top=NULL)
339     // bitmap: 1000...000/00.....000
340     while (idp->top != NULL && ((idp->top->bitmap <= 1 && idp->top->layer > 0) || // 一条链的情况
341                                 (idp->top->layer == 0 && idp->top->bitmap == 0))) // 最后一个点的情况
342     {
343         struct idr_layer *t = idp->top->layer ? idp->top->ary[0] : NULL;
344         __idr_layer_free(idp->top);
345         idp->top = t;
346     }
347 }
348 
349 /**
350  * @brief 内部的分配ID函数 (辅助函数)
351  *
352  * @param idp
353  * @param ptr
354  * @param starting_id 暂时没用
355  * @return (0 <= id <= INT_MAX 表示申请的ID;否则是负数错误码, 可能是内存空间不够或者程序逻辑有误);
356  */
__idr_get_new_above_int(struct idr * idp,void * ptr,int starting_id)357 static int __idr_get_new_above_int(struct idr *idp, void *ptr, int starting_id)
358 {
359     struct idr_layer *stk[MAX_LEVEL + 1] = {0};
360 
361     // kdebug("stk=%#018lx, sizeof_stk=%d", stk, sizeof(stk));
362     // memset(stk, 0, sizeof(stk));
363     // 你可以选择 memset(stk, 0, sizeof(stk));
364     int64_t id = __idr_get_empty_slot(idp, stk);
365 
366     if (id >= 0)
367     {
368         stk[0]->ary[IDR_MASK & id] = ptr;
369         __idr_mark_full(idp, id, stk, 2);
370     }
371 
372     return id;
373 }
374 
375 /**
376  * @brief 从[0,INT_MAX]区间内返回一个最小的空闲ID
377  *
378  * @param idp
379  * @param ptr     - id 所对应的指针
380  * @param int* id - 传入int指针,获取到的NEW_ID存在id里
381  * @return int (0表示获取id成功, 负数代表错误 - 可能是内存空间不够)
382  */
idr_alloc(struct idr * idp,void * ptr,int * id)383 int idr_alloc(struct idr *idp, void *ptr, int *id)
384 {
385     int rv = __idr_get_new_above_int(idp, ptr, 0);
386     if (rv < 0)
387         return rv; // error
388     *id = rv;
389     return 0;
390 }
391 
392 /**
393  * @brief 删除一个id, 但是不释放对应的ptr指向的空间, 同时返回这个被删除id所对应的ptr
394  *
395  * @param idp
396  * @param id
397  * @return void*
398  * (如果删除成功,就返回被删除id所对应的ptr;否则返回NULL。注意:如果这个id本来就和NULL绑定,那么也会返回NULL)
399  */
idr_remove(struct idr * idp,int id)400 void *idr_remove(struct idr *idp, int id)
401 {
402     int64_t __id = (int64_t)id;
403     if (unlikely(idp->top == NULL || __id < 0))
404         return NULL;
405 
406     struct idr_layer *stk[MAX_LEVEL + 1] = {0};
407 
408     if (0 == __idr_get_path(idp, __id, stk))
409         return NULL; // 找不到路径
410 
411     void *ret = stk[0]->ary[__id & IDR_MASK];
412     __idr_erase_full(idp, __id, stk, 0);
413 
414     return ret;
415 }
416 
417 /**
418  * @brief 移除IDR中所有的节点,如果free=true,则同时释放所有数据指针的空间(kfree)
419  *
420  * @param idp
421  * @param free
422  */
__idr_remove_all_with_free(struct idr * idp,bool free)423 static void __idr_remove_all_with_free(struct idr *idp, bool free)
424 {
425     if (unlikely(NULL == idp->top))
426     {
427         kBUG("idr-module find a BUG: idp->top can't be NULL.");
428         return;
429     }
430 
431     int sz = sizeof(struct idr_layer);
432     struct idr_layer *stk[MAX_LEVEL + 1] = {0};
433 
434     struct idr_layer *cur_layer = idp->top;
435     int layer = cur_layer->layer;
436     BUG_ON(layer + 1 >= 7);
437     stk[layer + 1] = NULL; // 标记数组结尾
438 
439     while (cur_layer != NULL)
440     {
441         if (layer > 0 && cur_layer->bitmap) // 非叶子节点
442         {
443             stk[layer] = cur_layer; // 入栈
444             int64_t id = __lowbit_id(cur_layer->bitmap);
445 
446             cur_layer->bitmap ^= (1ull << id);
447             cur_layer = cur_layer->ary[id];
448             stk[layer]->ary[id] = NULL;
449             --layer;
450         }
451         else
452         {
453             if (free)
454             {
455                 for (int i = 0; i < IDR_SIZE; i++) // 释放数据指针的空间
456                 {
457                     kfree(cur_layer->ary[i]);
458                     cur_layer->ary[i] = NULL;
459                 }
460             }
461 
462             __idr_layer_free(cur_layer); //  释放空间记得设置为NULL
463             ++layer;
464 
465             cur_layer = stk[layer]; // 出栈
466         }
467     }
468     idp->top = NULL;
469 }
470 
471 /**
472  * @brief 删除idr的所有节点,同时释放数据指针的空间,回收free_list的所有空间 - (数据指针指ID所绑定的pointer)
473  * @param idp
474  */
__idr_destroy_with_free(struct idr * idp)475 static void __idr_destroy_with_free(struct idr *idp)
476 {
477     if (likely(idp->top))
478         __idr_remove_all_with_free(idp, 1);
479     idp->top = NULL;
480     while (idp->id_free_cnt)
481         __idr_layer_free(__get_from_free_list(idp));
482     idp->free_list = NULL;
483 }
484 
485 /**
486  * @brief 删除所有的ID
487  *
488  * @param idp
489  */
idr_remove_all(struct idr * idp)490 void idr_remove_all(struct idr *idp)
491 {
492     if (unlikely(NULL == idp->top))
493         return;
494 
495     __idr_remove_all_with_free(idp, 0);
496 }
497 
498 /**
499  * @brief 释放一个idr占用的所有空间
500  *
501  * @param idp
502  */
idr_destroy(struct idr * idp)503 void idr_destroy(struct idr *idp)
504 {
505     idr_remove_all(idp);
506     idp->top = NULL;
507     while (idp->id_free_cnt)
508         __idr_layer_free(__get_from_free_list(idp));
509     idp->free_list = NULL;
510 }
511 
512 /**
513  * @brief 返回id对应的数据指针
514  *
515  * @param idp
516  * @param id
517  * @return void* (如果id不存在返回NULL;否则返回对应的指针ptr; 注意: 有可能用户的数据本来就是NULL)
518  */
idr_find(struct idr * idp,int id)519 void *idr_find(struct idr *idp, int id)
520 {
521     int64_t __id = (int64_t)id;
522     if (unlikely(idp->top == NULL || __id < 0))
523     {
524         // kwarn("idr-find: idp->top == NULL || id < 0.");
525         return NULL;
526     }
527 
528     struct idr_layer *cur_layer = idp->top;
529     int layer = cur_layer->layer; // 特判NULL
530     barrier();
531     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
532     if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
533         return NULL;
534     barrier();
535     barrier();
536     int64_t layer_id = 0;
537     while (layer >= 0 && cur_layer != NULL)
538     {
539         barrier();
540         layer_id = (__id >> (IDR_BITS * layer)) & IDR_MASK;
541         barrier();
542         cur_layer = cur_layer->ary[layer_id];
543         --layer;
544     }
545     return cur_layer;
546 }
547 
548 /**
549  * @brief  返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL; 可以传入nextid指针,获取下一个id;
550  * 时间复杂度O(log_64(n)), 空间复杂度O(log_64(n)) 约为 6;
551  *
552  * @param idp
553  * @param start_id
554  * @param nextid
555  * @return void* (如果分配,将返回该ID对应的数据指针; 否则返回NULL。注意,
556  * 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
557  */
idr_find_next_getid(struct idr * idp,int64_t start_id,int * nextid)558 void *idr_find_next_getid(struct idr *idp, int64_t start_id, int *nextid)
559 {
560     BUG_ON(nextid == NULL);
561     if (unlikely(idp->top == NULL))
562     {
563         *nextid = -1;
564         return NULL;
565     }
566 
567     ++start_id;
568     start_id = max(0, start_id); // 特判负数
569     *nextid = 0;
570 
571     struct idr_layer *stk[MAX_LEVEL + 1] = {0};
572 
573     // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
574     bool state[MAX_LEVEL + 1] = {0}; // 标记是否大于等于]
575     int pos_i[MAX_LEVEL + 1] = {0};
576 
577     // memset(state, 0, sizeof(state));
578     // memset(pos_i, 0, sizeof(pos_i)); // 必须清空
579 
580     struct idr_layer *cur_layer = idp->top;
581     bool cur_state = false;
582     bool init_flag = true;
583     int layer = cur_layer->layer;
584     BUG_ON(layer + 1 >= 7);
585     stk[layer + 1] = NULL; // 标记数组结尾
586 
587     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
588     if ((start_id >> ((layer + 1) * IDR_BITS)) > 0)
589     {
590         *nextid = -1;
591         return NULL;
592     }
593 
594     while (cur_layer) // layer < top->layer + 1
595     {
596         BUG_ON(layer < 0);
597         if (init_flag) // 第一次入栈
598         {
599             stk[layer] = cur_layer;
600             state[layer] = cur_state;
601             pos_i[layer] = cur_state ? 0 : ((start_id >> (layer * IDR_BITS)) & IDR_MASK);
602         }
603         else
604         {
605             pos_i[layer]++;
606             state[layer] = cur_state = true;
607         }
608 
609         BUG_ON(pos_i[layer] >= 64);
610         unsigned long t_bitmap = (cur_layer->bitmap >> pos_i[layer]);
611         if (t_bitmap) // 进一步递归到儿子下面去
612         {
613             int64_t layer_id = __lowbit_id(t_bitmap) + pos_i[layer];
614 
615             // 特别情况
616             if ((cur_state == false) && (layer_id > pos_i[layer] > 0))
617                 cur_state = true;
618 
619             pos_i[layer] = layer_id;
620 
621             *nextid = (((uint64_t)*nextid) << IDR_BITS) | layer_id; // 更新答案
622             if (layer == 0)
623             {
624                 //  找到下一个id: nextid
625                 return cur_layer->ary[layer_id];
626             }
627 
628             cur_layer = cur_layer->ary[layer_id];
629             init_flag = true; // 儿子节点第一次入栈, 需要init
630             --layer;
631         }
632         else // 子树搜索完毕,向上回溯
633         {
634             (*nextid) >>= IDR_BITS; // 维护答案
635 
636             ++layer;
637             cur_layer = stk[layer];
638             init_flag = false; // 不是第一次入栈, 不需要init
639         }
640     }
641 
642     *nextid = -1;
643     return NULL; // 找不到
644 }
645 
646 /**
647  * @brief 返回id大于 start_id 的数据指针(即非空闲id对应的指针), 如果没有则返回NULL
648  *
649  * @param idp
650  * @param start_id
651  * @return void* (如果分配,将返回该ID对应的数据指针; 否则返回NULL。注意,
652  * 返回NULL不一定代表这ID不存在,有可能该ID就是与空指针绑定。)
653  */
idr_find_next(struct idr * idp,int start_id)654 void *idr_find_next(struct idr *idp, int start_id)
655 {
656     int nextid;
657     void *ptr = idr_find_next_getid(idp, start_id, &nextid);
658 
659     return ptr; // 当 nextid == -1 时, 出现错误
660 }
661 
662 /**
663  * @brief 根据id替换指针,你需要保证这个id存在于idr中,否则将会出现错误
664  *
665  * @param idp
666  * @param ptr (要替换旧指针的新指针 - new_ptr)
667  * @param id
668  * @param old_ptr (返回旧指针, 注意NULL不一定是出现错误,有可能是数据本来就是NULL)
669  * @return int (0代表成功,否则就是负数 - 代表错误)
670  */
idr_replace_get_old(struct idr * idp,void * ptr,int id,void ** old_ptr)671 int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **old_ptr)
672 {
673     int64_t __id = (int64_t)id;
674     if (unlikely(old_ptr == NULL))
675     {
676         BUG_ON(1);
677         return -EINVAL;
678     }
679     *old_ptr = NULL;
680 
681     if (unlikely(idp->top == NULL || __id < 0))
682         return -EDOM; // 参数错误
683 
684     struct idr_layer *cur_layer = idp->top;
685     int64_t layer = cur_layer->layer;
686     // 如果查询的ID的bit数量比layer*IDR_BITS还大, 直接返回NULL
687     if ((__id >> ((layer + 1) * IDR_BITS)) > 0)
688         return -EDOM;
689 
690     while (layer > 0)
691     {
692         int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
693 
694         if (unlikely(NULL == cur_layer->ary[layer_id]))
695             return -ENOMEM;
696 
697         cur_layer = cur_layer->ary[layer_id];
698         layer--;
699     }
700 
701     __id &= IDR_MASK;
702     *old_ptr = cur_layer->ary[__id];
703     cur_layer->ary[__id] = ptr;
704 
705     return 0;
706 }
707 
708 /**
709  * @brief 根据id替换指针,你需要保证这个id存在于idr中,否则将会出现错误
710  *
711  * @param idp
712  * @param ptr (要替换 '旧数据指针' 的 '新数据指针' - new_ptr)
713  * @param id
714  * @return int (0代表成功,否则就是错误码 - 代表错误)
715  */
idr_replace(struct idr * idp,void * ptr,int id)716 int idr_replace(struct idr *idp, void *ptr, int id)
717 {
718     int64_t __id = (int64_t)id;
719     if (__id < 0)
720         return -EDOM;
721 
722     void *old_ptr;
723     int flags = idr_replace_get_old(idp, ptr, __id, &old_ptr);
724 
725     return flags;
726 }
727 
728 /**
729  * @brief 判断一个idr是否为空
730  *
731  * @param idp
732  * @return true
733  * @return false
734  */
idr_empty(struct idr * idp)735 bool idr_empty(struct idr *idp)
736 {
737     if (idp == NULL || idp->top == NULL || !idp->top->bitmap)
738         return true;
739 
740     return false;
741 }
742 
__idr_cnt_pd(struct idr_layer * cur_layer,int layer_id)743 static bool __idr_cnt_pd(struct idr_layer *cur_layer, int layer_id)
744 {
745     // if(layer_id)
746     unsigned long flags = ((cur_layer->bitmap) >> layer_id);
747     if ((flags % 2) == 0)
748     {
749         barrier();
750         return false; // 没有这一个儿子
751     }
752     return true;
753 }
754 
__idr_cnt(int layer,int id,struct idr_layer * cur_layer)755 static bool __idr_cnt(int layer, int id, struct idr_layer *cur_layer)
756 {
757     int64_t __id = (int64_t)id;
758     while (layer >= 0) // 提取路径
759     {
760         barrier();
761 
762         int64_t layer_id = (__id >> (layer * IDR_BITS)) & IDR_MASK;
763 
764         barrier();
765 
766         if (__idr_cnt_pd(cur_layer, layer_id) == false)
767             return false;
768 
769         barrier();
770 
771         barrier();
772         cur_layer = cur_layer->ary[layer_id];
773 
774         barrier();
775         --layer;
776     }
777     return true;
778 }
779 
780 /**
781  * @brief 这个函数是可以用于判断一个ID是否已经被分配的。
782  *
783  * @param idp
784  * @param id
785  * @return true
786  * @return false
787  */
idr_count(struct idr * idp,int id)788 bool idr_count(struct idr *idp, int id)
789 {
790     int64_t __id = (int64_t)id;
791     barrier();
792     if (unlikely(idp == NULL || idp->top == NULL || __id < 0))
793         return false;
794 
795     barrier();
796     struct idr_layer *cur_layer = idp->top;
797     barrier();
798     int layer = cur_layer->layer;
799 
800     // 如果查询的ID的bit数量比 layer*IDR_BITS 还大, 直接返回false
801     if (unlikely((__id >> ((layer + 1ull) * IDR_BITS)) > 0))
802     {
803         BUG_ON(1);
804         return false;
805     }
806     barrier();
807 
808     return __idr_cnt(layer, id, cur_layer);
809 }
810 
811 /********* ****************************************** ida - idr 函数实现分割线
812  * **********************************************************/
813 
814 /**
815  * @brief 初始化IDA, 你需要保证调用函数之前, ida的free_list为空, 否则会导致内存泄漏
816  * @param ida_p
817  */
ida_init(struct ida * ida_p)818 void ida_init(struct ida *ida_p)
819 {
820     memset(ida_p, 0, sizeof(struct ida));
821     idr_init(&ida_p->idr);
822 }
823 
824 /**
825  * @brief 释放bitmap空间
826  *
827  */
__ida_bitmap_free(struct ida_bitmap * bitmap)828 static void __ida_bitmap_free(struct ida_bitmap *bitmap)
829 {
830     kfree(bitmap);
831 }
832 
833 /**
834  * @brief 为ida预分配空间
835  *
836  * @param ida_p
837  * @param gfp_mask
838  * @return int (如果分配成功,将返回0; 否则返回负数错误码, 有可能是内存空间不够)
839  */
ida_preload(struct ida * ida_p,gfp_t gfp_mask)840 int ida_preload(struct ida *ida_p, gfp_t gfp_mask)
841 {
842     if (idr_preload(&ida_p->idr, gfp_mask) != 0)
843         return -ENOMEM;
844 
845     spin_lock(&ida_p->idr.lock);
846 
847     if (NULL == ida_p->free_list)
848     {
849         struct ida_bitmap *bitmap;
850         bitmap = kzalloc(sizeof(struct ida_bitmap), gfp_mask);
851         if (NULL == bitmap)
852         {
853             spin_unlock(&ida_p->idr.lock);
854             return -ENOMEM;
855         }
856         ida_p->free_list = bitmap;
857     }
858 
859     spin_unlock(&ida_p->idr.lock);
860     return 0;
861 }
862 
863 /**
864  * @brief Get the ida bitmap object
865  *
866  * @param ida_p
867  * @return void*
868  */
__get_ida_bitmap(struct ida * ida_p,gfp_t gfp_mask)869 static void *__get_ida_bitmap(struct ida *ida_p, gfp_t gfp_mask)
870 {
871     if (NULL == ida_p->free_list)
872         if (ida_preload(ida_p, gfp_mask) < 0)
873         {
874             kBUG("error : no memory.");
875             return NULL;
876         }
877 
878     struct ida_bitmap *tmp = ida_p->free_list;
879     ida_p->free_list = NULL;
880     return tmp;
881 }
882 
883 /**
884  * @brief 从bitmap中获取id, 并且标记这个ID已经被使用
885  * @return int
886  */
__get_id_from_bitmap(struct ida_bitmap * bmp)887 static int __get_id_from_bitmap(struct ida_bitmap *bmp)
888 {
889     int ret = 0;
890     for (int ary_id = 0; ary_id < IDA_BITMAP_LONGS; ary_id++)
891     {
892         if (bmp->bitmap[ary_id] != IDR_FULL)
893         {
894             int bmp_id = __lowbit_id(~bmp->bitmap[ary_id]);
895             bmp->bitmap[ary_id] |= (1ull << bmp_id);
896             bmp->count++; // 注意, 这里已经标记这一位已经使用, 同时更新了ida_count
897 
898             if (unlikely((unsigned long long)ary_id * IDA_BMP_SIZE + bmp_id > INT32_MAX))
899             {
900                 BUG_ON(1);
901                 // kBUG("ida设置id范围为[0, INT32_MAX], 但ida获取的id数值超过INT32_MAX.");
902                 return -EDOM;
903             }
904 
905             return ary_id * IDA_BMP_SIZE + bmp_id;
906         }
907     }
908 
909     return -EDOM; // 不合法
910 }
911 
912 /**
913  * @brief 获取一个ID
914  *
915  * @param ida_p
916  * @param p_id
917  * @return int (0表示获取ID成功, 否则是负数 - 错误码)
918  */
ida_alloc(struct ida * ida_p,int * p_id)919 int ida_alloc(struct ida *ida_p, int *p_id)
920 {
921     BUG_ON(p_id == NULL);
922     *p_id = -1;
923 
924     struct idr_layer *stk[MAX_LEVEL + 1] = {0}; // 你可以选择memset(0)
925 
926     // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
927 
928     io_sfence();
929     int64_t idr_id = __idr_get_empty_slot(&ida_p->idr, stk);
930 
931     // 如果stk[0]=NULL,可能是idr内部出错/内存空间不够
932     if (unlikely(NULL == stk[0]))
933         return -ENOMEM;
934 
935     if (unlikely(idr_id < 0))
936         return idr_id;
937 
938     int64_t layer_id = idr_id & IDR_MASK;
939 
940     if (NULL == stk[0]->ary[layer_id])
941         stk[0]->ary[layer_id] = __get_ida_bitmap(ida_p, 0);
942 
943     if (unlikely(NULL == stk[0]->ary[layer_id]))
944         return -ENOMEM;
945 
946     struct ida_bitmap *bmp = (struct ida_bitmap *)stk[0]->ary[layer_id];
947     int low_id = __get_id_from_bitmap(bmp);
948 
949     if (unlikely(low_id < 0))
950         return low_id;
951 
952     *p_id = idr_id * IDA_BITMAP_BITS + low_id;
953     __idr_mark_full(&ida_p->idr, idr_id, stk, (bmp->count == IDA_FULL ? 2 : 1));
954 
955     return 0;
956 }
957 
958 /**
959  * @brief 查询ID是否已经被分配
960  *
961  * @param ida_p
962  * @param id
963  * @return true
964  * @return false
965  */
ida_count(struct ida * ida_p,int id)966 bool ida_count(struct ida *ida_p, int id)
967 {
968     int64_t __id = (int64_t)id;
969     if (unlikely(NULL == ida_p || NULL == ida_p->idr.top || id < 0))
970         return false;
971 
972     int idr_id = __id / IDA_BITMAP_BITS;
973     int ary_id = (__id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
974     int bmp_id = (__id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
975 
976     struct ida_bitmap *bmp = idr_find(&ida_p->idr, idr_id);
977     if (NULL == bmp)
978         return false;
979 
980     return ((bmp->bitmap[ary_id] >> bmp_id) & 1);
981 }
982 
983 /**
984  * @brief 删除一个ID
985  *
986  * @param ida_p
987  * @param id
988  */
ida_remove(struct ida * ida_p,int id)989 void ida_remove(struct ida *ida_p, int id)
990 {
991     int64_t __id = (int64_t)id;
992     if (unlikely(NULL == ida_p || NULL == ida_p->idr.top || id < 0))
993         return;
994 
995     int64_t idr_id = __id / IDA_BITMAP_BITS;
996     int64_t ary_id = (__id % IDA_BITMAP_BITS) / IDA_BMP_SIZE;
997     int64_t bmp_id = (__id % IDA_BITMAP_BITS) % IDA_BMP_SIZE;
998 
999     struct idr_layer *stk[MAX_LEVEL + 1] = {0};
1000     // memset(stk, 0, sizeof(struct idr_layer *) * (MAX_LEVEL + 1));
1001 
1002     if (0 == __idr_get_path(&ida_p->idr, idr_id, stk))
1003         return;
1004 
1005     struct ida_bitmap *b_p = (struct ida_bitmap *)(stk[0]->ary[idr_id & IDR_MASK]);
1006 
1007     // 不存在这个ID 或者 b_p == NULL
1008     if (unlikely(NULL == b_p || 0 == ((b_p->bitmap[ary_id] >> bmp_id) & 1)))
1009         return;
1010 
1011     b_p->count--; // 更新了ida_count
1012     b_p->bitmap[ary_id] ^= (1ull << bmp_id);
1013 
1014     __idr_erase_full(&ida_p->idr, idr_id, stk, (b_p->count > 0 ? 1 : 0));
1015     if (0 == b_p->count)
1016     {
1017         __ida_bitmap_free(b_p);
1018         if (stk[0])                                // stk[0] 有可能在 __idr_erase_full 里面已经kfree了
1019             stk[0]->ary[idr_id & IDR_MASK] = NULL; // 记得设置为空
1020     }
1021 }
1022 
1023 /**
1024  * @brief 释放所有空间(包括: idr + ida_bitmap + free_list)
1025  * @param ida_p
1026  */
ida_destroy(struct ida * ida_p)1027 void ida_destroy(struct ida *ida_p)
1028 {
1029     if (unlikely(ida_p == NULL))
1030     {
1031         BUG_ON(1);
1032         return;
1033     }
1034 
1035     __idr_destroy_with_free(&ida_p->idr);
1036     ida_p->idr.top = NULL;
1037     __ida_bitmap_free(ida_p->free_list);
1038     ida_p->free_list = NULL;
1039 }
1040 
1041 /**
1042  * @brief 判断一个ida是否为空
1043  *
1044  * @param ida_p
1045  * @return true
1046  * @return false
1047  */
ida_empty(struct ida * ida_p)1048 bool ida_empty(struct ida *ida_p)
1049 {
1050     if (ida_p == NULL || ida_p->idr.top == NULL || !ida_p->idr.top->bitmap)
1051         return true;
1052 
1053     return false;
1054 }
1055