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