idr.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #pragma GCC push_options
  2. #pragma GCC optimize("O1")
  3. #include <common/errno.h>
  4. #include <common/spinlock.h>
  5. #if ARCH(I386) || ARCH(X86_64)
  6. #include <arch/x86_64/math/bitcount.h>
  7. #else
  8. #error Arch not supported.
  9. #endif
  10. /**
  11. * idr: 基于radix-tree的ID-pointer的数据结构
  12. * 主要功能:
  13. * 1. 获取一个ID, 并且将该ID与一个指针绑定 - 需要外部加锁
  14. * 2. 删除一个已分配的ID - 需要外部加锁
  15. * 3. 根据ID查找对应的指针 (读操作,看情况加锁)
  16. * 4. 根据ID使用新的ptr替换旧的ptr - 需要外部加锁
  17. *
  18. * 附加功能:
  19. * 1. 给定starting_id, 查询下一个已分配的next_id (即:next_id>starting_id)
  20. * 2. 销毁整个idr
  21. *
  22. *
  23. * .... 待实现
  24. */
  25. // 默认64位机器
  26. #define IDR_BITS 6
  27. #define IDR_FULL 0xfffffffffffffffful
  28. // size = 64
  29. #define IDR_SIZE (1 << IDR_BITS)
  30. #define IDR_MASK ((1 << IDR_BITS) - 1)
  31. // 能管理的ID范围[0:1<<31]
  32. #define MAX_ID_SHIFT (sizeof(int) * 8 - 1)
  33. #define MAX_ID_BIT (1U << MAX_ID_SHIFT)
  34. #define MAX_ID_MASK (MAX_ID_BIT - 1)
  35. // IDR可能最大的层次 以及 IDR预分配空间的最大限制
  36. #define MAX_LEVEL ((MAX_ID_SHIFT + IDR_BITS - 1) / IDR_BITS)
  37. #define IDR_FREE_MAX (MAX_LEVEL << 1)
  38. // 给定layer, 计算完全64叉树的大小
  39. #define TREE_SIZE(layer) ((layer >= 0) ? (1ull << ((layer + 1) * IDR_BITS)) : 1)
  40. // 计算最后(最低位)一个1的位置 (注意使用64位的版本)
  41. #define __lowbit_id(x) ((x) ? (__ctzll(x)) : -1)
  42. // 计算最前(最高位)一个1的位置 (注意使用64位的版本)
  43. #define __mostbit_id(x) ((x) ? (63 - __clzll(x)) : -1)
  44. // radix-tree 节点定义
  45. struct idr_layer
  46. {
  47. struct idr_layer *ary[IDR_SIZE]; // IDR_SIZE叉树
  48. unsigned long bitmap; // 每一位表示这个子树是否被使用
  49. unsigned long full; // 64个儿子子树, 每一位代表一个子树是否满了
  50. int layer; // 层数(从底向上)
  51. };
  52. // idr: 将id与pointer绑定的数据结构
  53. struct idr
  54. {
  55. struct idr_layer *top;
  56. struct idr_layer *free_list;
  57. int id_free_cnt;
  58. spinlock_t lock;
  59. }__attribute__((aligned(8)));
  60. #define DECLARE_IDR(name) \
  61. struct idr name = {0}; \
  62. idr_init(&(name));
  63. #define DECLARE_IDR_LAYER(name) \
  64. struct idr_layer name = {0}; \
  65. memset(name, 0, sizeof(struct idr_layer));
  66. /**
  67. * 对外函数声明
  68. **/
  69. int idr_preload(struct idr *idp, gfp_t gfp_mask);
  70. int idr_alloc(struct idr *idp, void *ptr, int *id);
  71. void *idr_remove(struct idr *idp, int id);
  72. void idr_remove_all(struct idr *idp);
  73. void idr_destroy(struct idr *idp);
  74. void *idr_find(struct idr *idp, int id);
  75. void *idr_find_next(struct idr *idp, int start_id);
  76. void *idr_find_next_getid(struct idr *idp, int64_t start_id, int *nextid);
  77. int idr_replace_get_old(struct idr *idp, void *ptr, int id, void **oldptr);
  78. int idr_replace(struct idr *idp, void *ptr, int id);
  79. void idr_init(struct idr *idp);
  80. bool idr_empty(struct idr *idp);
  81. bool idr_count(struct idr *idp, int id);
  82. /**
  83. * 对外宏:遍历idr两种方式:
  84. * 1. 从第一个元素开始遍历
  85. * 2. 从某一个id开始遍历
  86. */
  87. /**
  88. * @brief 第一种遍历方式: 从第一个元素开始遍历
  89. * @param idp idr指针
  90. * @param id 遍历的id,你不需要初始化这个id,因为它每一次都是从最小已分配的id开始遍历
  91. * @param ptr 数据指针(entry),你不需要初始化这个指针
  92. */
  93. #define for_each_idr_entry(idp, id, ptr) \
  94. 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))
  95. /**
  96. * @brief 第二种遍历方式: 从某一个id开始遍历
  97. * @param idp idr指针
  98. * @param id 遍历的id,你需要初始化这个id(请你设置为你要从哪一个id开始遍历,遍历过程将会包括这个id)
  99. * @param ptr 数据指针(entry),你不需要初始化这个指针
  100. */
  101. #define for_each_idr_entry_continue(idp, id, ptr) \
  102. for (ptr = idr_find_next_getid(idp, id - 1, &id); ptr != NULL || !idr_count(idp, id); ptr = idr_find_next_getid(idp, id, &id))
  103. /**
  104. * ida: 基于IDR实现的ID分配器
  105. * 主要功能:
  106. * 1. 获取一个未分配的ID
  107. * 2. 询问一个ID是否被分配
  108. * 3. 删除一个已分配ID
  109. *
  110. * 附加功能:
  111. * 1. 暂定
  112. */
  113. // 一个块的大小 - 即 sizeof(struct ida_bitmap)
  114. #define IDA_CHUNK_SIZE 128
  115. // ida_bitmap的长度
  116. #define IDA_BITMAP_LONGS (IDA_CHUNK_SIZE / sizeof(long) - 1)
  117. // 对应linux的IDA_BITMAP_BITS = 960 = 15 * 64
  118. #define IDA_FULL (IDA_BITMAP_LONGS * sizeof(long) * 8)
  119. #define IDA_BITMAP_BITS IDA_FULL
  120. #define IDA_BMP_SIZE (8 * sizeof(long))
  121. // 自定义bitmap
  122. struct ida_bitmap
  123. {
  124. unsigned long count; // bitmap中已经分配的id数量
  125. unsigned long bitmap[IDA_BITMAP_LONGS]; // bitmap本身, 每一个bit代表一个ID
  126. };
  127. // id-allocater 管理+分配ID的数据结构
  128. struct ida
  129. {
  130. struct idr idr;
  131. struct ida_bitmap *free_list; // 预分配的数据块
  132. };
  133. #define DECLARE_IDA(name) \
  134. struct ida name = {0}; \
  135. idr_init(&name.idr); \
  136. name.free_list = (NULL);
  137. /**
  138. * 对外函数声明
  139. */
  140. void ida_init(struct ida *ida_p);
  141. bool ida_empty(struct ida *ida_p);
  142. int ida_preload(struct ida *ida_p, gfp_t gfp_mask);
  143. int ida_alloc(struct ida *ida_p, int *p_id);
  144. bool ida_count(struct ida *ida_p, int id);
  145. void ida_remove(struct ida *ida_p, int id);
  146. void ida_destroy(struct ida *ida_p);
  147. #pragma GCC pop_options