slab.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590
  1. #include "slab.h"
  2. /**
  3. * @brief 创建一个内存池
  4. *
  5. * @param size 内存池容量大小
  6. * @param constructor 构造函数
  7. * @param destructor 析构函数
  8. * @param arg 参数
  9. * @return struct slab* 构建好的内存池对象
  10. */
  11. struct slab *slab_create(ul size, void *(*constructor)(void *vaddr, ul arg), void *(*destructor)(void *vaddr, ul arg), ul arg)
  12. {
  13. struct slab *slab_pool = (struct slab *)kmalloc(sizeof(struct slab), 0);
  14. // BUG
  15. if (slab_pool == NULL)
  16. {
  17. kBUG("slab_create()->kmalloc()->slab == NULL");
  18. return NULL;
  19. }
  20. memset(slab_pool, 0, sizeof(struct slab));
  21. slab_pool->size = SIZEOF_LONG_ALIGN(size);
  22. slab_pool->count_total_using = 0;
  23. slab_pool->count_total_free = 0;
  24. // 直接分配cache_pool结构体,避免每次访问都要检测是否为NULL,提升效率
  25. slab_pool->cache_pool = (struct slab_obj *)kmalloc(sizeof(struct slab_obj), 0);
  26. // BUG
  27. if (slab_pool->cache_pool == NULL)
  28. {
  29. kBUG("slab_create()->kmalloc()->slab->cache_pool == NULL");
  30. kfree(slab_pool);
  31. return NULL;
  32. }
  33. memset(slab_pool->cache_pool, 0, sizeof(struct slab_obj));
  34. // dma内存池设置为空
  35. slab_pool->cache_dma_pool = NULL;
  36. // 设置构造及析构函数
  37. slab_pool->constructor = constructor;
  38. slab_pool->destructor = destructor;
  39. list_init(&slab_pool->cache_pool->list);
  40. // 分配属于内存池的内存页
  41. slab_pool->cache_pool->page = alloc_pages(ZONE_NORMAL, 1, PAGE_KERNEL);
  42. // BUG
  43. if (slab_pool->cache_pool->page == NULL)
  44. {
  45. kBUG("slab_create()->kmalloc()->slab->cache_pool == NULL");
  46. kfree(slab_pool->cache_pool);
  47. kfree(slab_pool);
  48. return NULL;
  49. }
  50. // page_init(slab_pool->cache_pool->page, PAGE_KERNEL);
  51. slab_pool->cache_pool->count_using = 0;
  52. slab_pool->cache_pool->count_free = PAGE_2M_SIZE / slab_pool->size;
  53. slab_pool->count_total_free = slab_pool->cache_pool->count_free;
  54. slab_pool->cache_pool->vaddr = phys_2_virt(slab_pool->cache_pool->page->addr_phys);
  55. // bitmap有多少有效位
  56. slab_pool->cache_pool->bmp_count = slab_pool->cache_pool->count_free;
  57. // 计算位图所占的空间 占用多少byte(按unsigned long大小的上边缘对齐)
  58. slab_pool->cache_pool->bmp_len = ((slab_pool->cache_pool->bmp_count + sizeof(ul) * 8 - 1) >> 6) << 3;
  59. // 初始化位图
  60. slab_pool->cache_pool->bmp = (ul *)kmalloc(slab_pool->cache_pool->bmp_len, 0);
  61. // BUG
  62. if (slab_pool->cache_pool->bmp == NULL)
  63. {
  64. kBUG("slab_create()->kmalloc()->slab->cache_pool == NULL");
  65. free_pages(slab_pool->cache_pool->page, 1);
  66. kfree(slab_pool->cache_pool);
  67. kfree(slab_pool);
  68. return NULL;
  69. }
  70. // 将位图清空
  71. memset(slab_pool->cache_pool->bmp, 0, slab_pool->cache_pool->bmp_len);
  72. return slab_pool;
  73. }
  74. /**
  75. * @brief 销毁内存池对象
  76. * 只有当slab对象是空的时候才能销毁
  77. * @param slab_pool 要销毁的内存池对象
  78. * @return ul
  79. *
  80. */
  81. ul slab_destroy(struct slab *slab_pool)
  82. {
  83. struct slab_obj *slab_obj_ptr = slab_pool->cache_pool;
  84. if (slab_pool->count_total_using)
  85. {
  86. kBUG("slab_cache->count_total_using != 0");
  87. return ESLAB_NOTNULL;
  88. }
  89. struct slab_obj *tmp_slab_obj = NULL;
  90. while (!list_empty(&slab_obj_ptr->list))
  91. {
  92. tmp_slab_obj = slab_obj_ptr;
  93. // 获取下一个slab_obj的起始地址
  94. slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
  95. list_del(&tmp_slab_obj->list);
  96. kfree(tmp_slab_obj->bmp);
  97. page_clean(tmp_slab_obj->page);
  98. free_pages(tmp_slab_obj->page, 1);
  99. kfree(tmp_slab_obj);
  100. }
  101. kfree(slab_obj_ptr->bmp);
  102. page_clean(slab_obj_ptr->page);
  103. free_pages(slab_obj_ptr->page, 1);
  104. kfree(slab_obj_ptr);
  105. kfree(slab_pool);
  106. return 0;
  107. }
  108. /**
  109. * @brief 分配SLAB内存池中的内存对象
  110. *
  111. * @param slab_pool slab内存池
  112. * @param arg 传递给内存对象构造函数的参数
  113. * @return void* 内存空间的虚拟地址
  114. */
  115. void *slab_malloc(struct slab *slab_pool, ul arg)
  116. {
  117. struct slab_obj *slab_obj_ptr = slab_pool->cache_pool;
  118. struct slab_obj *tmp_slab_obj = NULL;
  119. // slab内存池中已经没有空闲的内存对象,进行扩容
  120. if (slab_pool->count_total_free == 0)
  121. {
  122. tmp_slab_obj = (struct slab_obj *)kmalloc(sizeof(struct slab_obj), 0);
  123. // BUG
  124. if (tmp_slab_obj == NULL)
  125. {
  126. kBUG("slab_malloc()->kmalloc()->slab->tmp_slab_obj == NULL");
  127. return NULL;
  128. }
  129. memset(tmp_slab_obj, 0, sizeof(struct slab_obj));
  130. list_init(&tmp_slab_obj->list);
  131. tmp_slab_obj->page = alloc_pages(ZONE_NORMAL, 1, PAGE_KERNEL);
  132. // BUG
  133. if (tmp_slab_obj->page == NULL)
  134. {
  135. kBUG("slab_malloc()->kmalloc()=>tmp_slab_obj->page == NULL");
  136. kfree(tmp_slab_obj);
  137. return NULL;
  138. }
  139. tmp_slab_obj->count_using = 0;
  140. tmp_slab_obj->count_free = PAGE_2M_SIZE / slab_pool->size;
  141. tmp_slab_obj->vaddr = phys_2_virt(tmp_slab_obj->page->addr_phys);
  142. tmp_slab_obj->bmp_count = tmp_slab_obj->count_free;
  143. // 计算位图所占的空间 占用多少byte(按unsigned long大小的上边缘对齐)
  144. tmp_slab_obj->bmp_len = ((tmp_slab_obj->bmp_count + sizeof(ul) * 8 - 1) >> 6) << 3;
  145. tmp_slab_obj->bmp = (ul *)kmalloc(tmp_slab_obj->bmp_len, 0);
  146. // BUG
  147. if (tmp_slab_obj->bmp == NULL)
  148. {
  149. kBUG("slab_malloc()->kmalloc()=>tmp_slab_obj->bmp == NULL");
  150. free_pages(tmp_slab_obj->page, 1);
  151. kfree(tmp_slab_obj);
  152. return NULL;
  153. }
  154. memset(tmp_slab_obj->bmp, 0, tmp_slab_obj->bmp_len);
  155. list_add(&slab_pool->cache_pool->list, tmp_slab_obj);
  156. slab_pool->count_total_free += tmp_slab_obj->count_free;
  157. slab_obj_ptr = tmp_slab_obj;
  158. }
  159. // 扩容完毕或无需扩容,开始分配内存对象
  160. int tmp_md;
  161. do
  162. {
  163. if (slab_obj_ptr->count_free == 0)
  164. {
  165. slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
  166. continue;
  167. }
  168. for (int i = 0; i < slab_obj_ptr->bmp_count; ++i)
  169. {
  170. // 当前bmp对应的内存对象都已经被分配
  171. if (*(slab_obj_ptr->bmp + (i >> 6)) == 0xffffffffffffffffUL)
  172. {
  173. i += 63;
  174. continue;
  175. }
  176. // 第i个内存对象是空闲的
  177. tmp_md = i % 64;
  178. if ((*(slab_obj_ptr->bmp + (i >> 6)) & (1UL << tmp_md)) == 0)
  179. {
  180. // 置位bmp
  181. *(slab_obj_ptr->bmp + (i >> 6)) |= (1UL << tmp_md);
  182. // 更新当前slab对象的计数器
  183. ++(slab_obj_ptr->count_using);
  184. --(slab_obj_ptr->count_free);
  185. // 更新slab内存池的计数器
  186. ++(slab_pool->count_total_using);
  187. --(slab_pool->count_total_free);
  188. if (slab_pool->constructor != NULL)
  189. {
  190. // 返回内存对象指针(要求构造函数返回内存对象指针)
  191. return slab_pool->constructor((char *)slab_obj_ptr->vaddr + slab_pool->size * i, arg);
  192. }
  193. // 返回内存对象指针
  194. else
  195. return (void *)((char *)slab_obj_ptr->vaddr + slab_pool->size * i);
  196. }
  197. }
  198. } while (slab_obj_ptr != slab_pool->cache_pool);
  199. // should not be here
  200. kBUG("slab_malloc() ERROR: can't malloc");
  201. // 释放内存
  202. if (tmp_slab_obj != NULL)
  203. {
  204. list_del(&tmp_slab_obj->list);
  205. kfree(tmp_slab_obj->bmp);
  206. page_clean(tmp_slab_obj->page);
  207. free_pages(tmp_slab_obj->page, 1);
  208. kfree(tmp_slab_obj);
  209. }
  210. return NULL;
  211. }
  212. /**
  213. * @brief 回收slab内存池中的对象
  214. *
  215. * @param slab_pool 对应的内存池
  216. * @param addr 内存对象的虚拟地址
  217. * @param arg 传递给虚构函数的参数
  218. * @return ul
  219. */
  220. ul slab_free(struct slab *slab_pool, void *addr, ul arg)
  221. {
  222. struct slab_obj *slab_obj_ptr = slab_pool->cache_pool;
  223. do
  224. {
  225. // 虚拟地址不在当前内存池对象的管理范围内
  226. if (!(slab_obj_ptr->vaddr <= addr && addr <= (slab_obj_ptr->vaddr + PAGE_2M_SIZE)))
  227. {
  228. slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
  229. continue;
  230. }
  231. // 计算出给定内存对象是第几个
  232. int index = (addr - slab_obj_ptr->vaddr) / slab_pool->size;
  233. // 复位位图中对应的位
  234. *(slab_obj_ptr->bmp + (index >> 6)) ^= (1UL << index % 64);
  235. ++(slab_obj_ptr->count_free);
  236. --(slab_obj_ptr->count_using);
  237. ++(slab_pool->count_total_free);
  238. --(slab_pool->count_total_using);
  239. // 有对应的析构函数,调用析构函数
  240. if (slab_pool->destructor != NULL)
  241. slab_pool->destructor((char *)slab_obj_ptr->vaddr + slab_pool->size * index, arg);
  242. // 当前内存对象池的正在使用的内存对象为0,且内存池的空闲对象大于当前对象池的2倍,则销毁当前对象池,以减轻系统内存压力
  243. if ((slab_obj_ptr->count_using == 0) && ((slab_pool->count_total_free >> 1) >= slab_obj_ptr->count_free))
  244. {
  245. // 防止删除了slab_pool的cache_pool入口
  246. if (slab_pool->cache_pool == slab_obj_ptr)
  247. slab_pool->cache_pool = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
  248. list_del(&slab_obj_ptr->list);
  249. slab_pool->count_total_free -= slab_obj_ptr->count_free;
  250. kfree(slab_obj_ptr->bmp);
  251. page_clean(slab_obj_ptr->page);
  252. free_pages(slab_obj_ptr->page, 1);
  253. kfree(slab_obj_ptr);
  254. }
  255. return 0;
  256. } while (slab_obj_ptr != slab_pool->cache_pool);
  257. kwarn("slab_free(): address not in current slab");
  258. return ENOT_IN_SLAB;
  259. }
  260. /**
  261. * @brief 初始化内存池组
  262. * 在初始化通用内存管理单元期间,尚无内存空间分配函数,需要我们手动为SLAB内存池指定存储空间
  263. * @return ul
  264. */
  265. ul slab_init()
  266. {
  267. // 将slab的内存池空间放置在mms的后方
  268. ul tmp_addr = memory_management_struct.end_of_struct;
  269. for (int i = 0; i < 16; ++i)
  270. {
  271. // 将slab内存池对象的空间放置在mms的后面,并且预留4个unsigned long 的空间以防止内存越界
  272. kmalloc_cache_group[i].cache_pool = (struct slab_obj *)memory_management_struct.end_of_struct;
  273. memory_management_struct.end_of_struct += sizeof(struct slab_obj) + (sizeof(ul) << 2);
  274. list_init(&(kmalloc_cache_group[i].cache_pool->list));
  275. // 初始化内存池对象
  276. kmalloc_cache_group[i].cache_pool->count_using = 0;
  277. kmalloc_cache_group[i].cache_pool->count_free = PAGE_2M_SIZE / kmalloc_cache_group[i].size;
  278. kmalloc_cache_group[i].cache_pool->bmp_len = (((kmalloc_cache_group[i].cache_pool->count_free + sizeof(ul) * 8 - 1) >> 6) << 3);
  279. kmalloc_cache_group[i].cache_pool->bmp_count = kmalloc_cache_group[i].cache_pool->count_free;
  280. // 在slab对象后方放置bmp
  281. kmalloc_cache_group[i].cache_pool->bmp = (ul *)memory_management_struct.end_of_struct;
  282. // bmp后方预留4个unsigned long的空间防止内存越界,且按照8byte进行对齐
  283. memory_management_struct.end_of_struct += kmalloc_cache_group[i].cache_pool->bmp_len + ((sizeof(ul) << 2) & (~sizeof(ul) - 1));
  284. // @todo:此处可优化,直接把所有位设置为0,然后再对部分不存在对应的内存对象的位设置为1
  285. memset(kmalloc_cache_group[i].cache_pool->bmp, 0xff, kmalloc_cache_group[i].cache_pool->bmp_len);
  286. for (int j = 0; j < kmalloc_cache_group[i].cache_pool->bmp_count; ++j)
  287. *(kmalloc_cache_group[i].cache_pool->bmp + (j >> 6)) ^= 1UL << (j % 64);
  288. kmalloc_cache_group[i].count_total_using = 0;
  289. kmalloc_cache_group[i].count_total_free = kmalloc_cache_group[i].cache_pool->count_free;
  290. }
  291. struct Page *page = NULL;
  292. // 将上面初始化内存池组时,所占用的内存页进行初始化
  293. ul tmp_page_mms_end = virt_2_phys(memory_management_struct.end_of_struct >> PAGE_2M_SHIFT);
  294. for (int i = PAGE_2M_ALIGN(virt_2_phys(tmp_addr)); i < tmp_page_mms_end; ++i)
  295. {
  296. page = memory_management_struct.pages_struct + i;
  297. // 下面注释掉的这部分工作貌似在page_init()里面已经做了
  298. // 在mms的bmp中,置位对应的位
  299. //*(memory_management_struct.bmp + ((page->addr_phys>>PAGE_2M_SHIFT)>>6)) |= 1UL<<((page->addr_phys >> PAGE_2M_SHIFT)%64);
  300. //++(page->zone->count_pages_using);
  301. //--(page->zone->count_pages_free);
  302. page_init(page, PAGE_KERNEL_INIT | PAGE_KERNEL | PAGE_PGT_MAPPED);
  303. }
  304. printk_color(ORANGE, BLACK, "2.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
  305. // 为slab内存池对象分配内存空间
  306. ul *virt = NULL;
  307. for (int i = 0; i < 16; ++i)
  308. {
  309. // 获取一个新的空页并添加到空页表,然后返回其虚拟地址
  310. virt = (ul *)(PAGE_2M_ALIGN(memory_management_struct.end_of_struct + PAGE_2M_SIZE * i));
  311. page = Virt_To_2M_Page(virt);
  312. page_init(page, PAGE_PGT_MAPPED | PAGE_KERNEL | PAGE_KERNEL_INIT);
  313. kmalloc_cache_group[i].cache_pool->page = page;
  314. kmalloc_cache_group[i].cache_pool->vaddr = virt;
  315. }
  316. printk_color(ORANGE, BLACK, "3.memory_management_struct.bmp:%#018lx\tzone_struct->count_pages_using:%d\tzone_struct->count_pages_free:%d\n", *memory_management_struct.bmp, memory_management_struct.zones_struct->count_pages_using, memory_management_struct.zones_struct->count_pages_free);
  317. return 0;
  318. }
  319. /**
  320. * @brief 在kmalloc中创建slab_obj的函数(与slab_malloc()中的类似)
  321. *
  322. * @param size
  323. * @return struct slab_obj* 创建好的slab_obj
  324. */
  325. struct slab_obj *kmalloc_create_slab_obj(ul size)
  326. {
  327. struct Page *page = alloc_pages(ZONE_NORMAL, 1, 0);
  328. // BUG
  329. if (page == NULL)
  330. {
  331. kBUG("kmalloc_create()->alloc_pages()=>page == NULL");
  332. return NULL;
  333. }
  334. page_init(page, PAGE_KERNEL);
  335. ul *vaddr = NULL;
  336. ul struct_size = 0;
  337. struct slab_obj *slab_obj_ptr;
  338. // 根据size大小,选择不同的分支来处理
  339. // 之所以选择512byte为分界点,是因为,此时bmp大小刚好为512byte。显而易见,选择过小的话会导致kmalloc函数与当前函数反复互相调用,最终导致栈溢出
  340. switch (size)
  341. {
  342. // ============ 对于size<=512byte的内存池对象,将slab_obj结构体和bmp放置在物理页的内部 ========
  343. // 由于这些对象的特征是,bmp占的空间大,而内存块的空间小,这样做的目的是避免再去申请一块内存来存储bmp,减少浪费。
  344. case 32:
  345. case 64:
  346. case 128:
  347. case 256:
  348. case 512:
  349. vaddr = phys_2_virt(page->addr_phys);
  350. // slab_obj结构体的大小 (本身的大小+bmp的大小)
  351. struct_size = sizeof(struct slab_obj) + PAGE_2M_SIZE / size / 8;
  352. // 将slab_obj放置到物理页的末尾
  353. slab_obj_ptr = (struct slab_obj *)((unsigned char *)vaddr + PAGE_2M_SIZE - struct_size);
  354. slab_obj_ptr->bmp = (ul *)slab_obj_ptr + sizeof(struct slab_obj);
  355. slab_obj_ptr->count_free = (PAGE_2M_SIZE - struct_size) / size;
  356. slab_obj_ptr->count_using = 0;
  357. slab_obj_ptr->bmp_count = slab_obj_ptr->count_free;
  358. slab_obj_ptr->vaddr = vaddr;
  359. slab_obj_ptr->page = page;
  360. list_init(&slab_obj_ptr->list);
  361. slab_obj_ptr->bmp_len = ((slab_obj_ptr->bmp_count + sizeof(ul) * 8 - 1) >> 6) << 3;
  362. // @todo:此处可优化,直接把所有位设置为0,然后再对部分不存在对应的内存对象的位设置为1
  363. memset(slab_obj_ptr->bmp, 0xff, slab_obj_ptr->bmp_len);
  364. for (int i = 0; i < slab_obj_ptr->bmp_count; ++i)
  365. *(slab_obj_ptr->bmp + (i >> 6)) ^= 1UL << (i % 64);
  366. break;
  367. // ================= 较大的size时,slab_obj和bmp不再放置于当前物理页内部 ============
  368. // 因为在这种情况下,bmp很短,继续放置在当前物理页内部则会造成可分配的对象少,加剧了内存空间的浪费
  369. case 1024: // 1KB
  370. case 2048:
  371. case 4096: // 4KB
  372. case 8192:
  373. case 16384:
  374. case 32768:
  375. case 65536:
  376. case 131072: // 128KB
  377. case 262144:
  378. case 524288:
  379. case 1048576: // 1MB
  380. slab_obj_ptr = (struct Slab *)kmalloc(sizeof(struct slab_obj), 0);
  381. slab_obj_ptr->count_free = PAGE_2M_SIZE / size;
  382. slab_obj_ptr->count_using = 0;
  383. slab_obj_ptr->bmp_count = slab_obj_ptr->count_free;
  384. slab_obj_ptr->bmp_len = ((slab_obj_ptr->bmp_count + sizeof(ul) * 8 - 1) >> 6) << 3;
  385. slab_obj_ptr->bmp = (ul *)kmalloc(slab_obj_ptr->bmp_len, 0);
  386. // @todo:此处可优化,直接把所有位设置为0,然后再对部分不存在对应的内存对象的位设置为1
  387. memset(slab_obj_ptr->bmp, 0xff, slab_obj_ptr->bmp_len);
  388. for (int i = 0; i < slab_obj_ptr->bmp_count; ++i)
  389. *(slab_obj_ptr->bmp + (i >> 6)) ^= 1UL << (i % 64);
  390. slab_obj_ptr->vaddr = phys_2_virt(page->addr_phys);
  391. slab_obj_ptr->page = page;
  392. list_init(&slab_obj_ptr->list);
  393. break;
  394. // size 错误
  395. default:
  396. kerror("kamlloc_create(): Wrong size%d\n", size);
  397. free_pages(page, 1);
  398. return NULL;
  399. break;
  400. }
  401. return slab_obj_ptr;
  402. }
  403. /**
  404. * @brief 通用内存分配函数
  405. *
  406. * @param size 要分配的内存大小
  407. * @param flags 内存的flag
  408. * @return void* 内核内存虚拟地址
  409. */
  410. void *kmalloc(unsigned long size, unsigned long flags)
  411. {
  412. if (size > 1048576)
  413. {
  414. kwarn("kmalloc(): Can't alloc such memory: %ld bytes, because it is too large.", size);
  415. return NULL;
  416. }
  417. int index;
  418. for (int i = 0; i < 16; ++i)
  419. if (kmalloc_cache_group[i].size >= size)
  420. {
  421. index = i;
  422. break;
  423. }
  424. struct slab_obj *slab_obj_ptr = kmalloc_cache_group[index].cache_pool;
  425. // 内存池没有可用的内存对象,需要进行扩容
  426. if (kmalloc_cache_group[index].count_total_free == 0)
  427. {
  428. // 创建slab_obj
  429. slab_obj_ptr = kmalloc_create_slab_obj(kmalloc_cache_group[index].size);
  430. // BUG
  431. if (slab_obj_ptr == NULL)
  432. {
  433. kBUG("kmalloc()->kmalloc_create_slab_obj()=>slab == NULL");
  434. return NULL;
  435. }
  436. kmalloc_cache_group[index].count_total_free += slab_obj_ptr->count_free;
  437. list_add(&kmalloc_cache_group[index].cache_pool->list, &slab_obj_ptr->list);
  438. }
  439. else // 内存对象充足
  440. {
  441. do
  442. {
  443. // 跳转到下一个内存池对象
  444. if (slab_obj_ptr->count_free == 0)
  445. slab_obj_ptr = container_of(list_next(&slab_obj_ptr->list), struct slab_obj, list);
  446. else
  447. break;
  448. } while (slab_obj_ptr != kmalloc_cache_group[index].cache_pool);
  449. }
  450. // 寻找一块可用的内存对象
  451. int md;
  452. for (int i = 0; i < slab_obj_ptr->count_free; ++i)
  453. {
  454. // 当前bmp全部被使用
  455. if (*slab_obj_ptr->bmp + (i >> 6) == 0xffffffffffffffffUL)
  456. {
  457. i += 63;
  458. continue;
  459. }
  460. md = i % 64;
  461. // 找到相应的内存对象
  462. if (*(slab_obj_ptr->bmp + (i >> 6)) & (1UL << md) == 0)
  463. {
  464. *(slab_obj_ptr->bmp + (i >> 6)) |= (1UL << md);
  465. ++(slab_obj_ptr->count_using);
  466. --(slab_obj_ptr->count_free);
  467. --kmalloc_cache_group[index].count_total_free;
  468. ++kmalloc_cache_group[index].count_total_using;
  469. return (void*)((char*)slab_obj_ptr->vaddr+kmalloc_cache_group[index].size*i);
  470. }
  471. }
  472. kerror("kmalloc(): Cannot alloc more memory: %d bytes", size);
  473. return NULL;
  474. }
  475. /**
  476. * @brief 通用内存释放函数
  477. *
  478. * @param address 要释放的内存地址
  479. * @return unsigned long
  480. */
  481. unsigned long kfree(void *address)
  482. {
  483. // @todo: 通用内存释放函数
  484. }