1 #pragma once
2
3 #include "mm.h"
4 #include <common/glib.h>
5 #include <common/printk.h>
6 #include <common/kprint.h>
7 #include <common/spinlock.h>
8
9 #define SIZEOF_LONG_ALIGN(size) ((size + sizeof(long) - 1) & ~(sizeof(long) - 1))
10 #define SIZEOF_INT_ALIGN(size) ((size + sizeof(int) - 1) & ~(sizeof(int) - 1))
11
12 // SLAB存储池count_using不为空
13 #define ESLAB_NOTNULL 101
14 #define ENOT_IN_SLAB 102 // 地址不在当前slab内存池中
15 #define ECANNOT_FREE_MEM 103 // 无法释放内存
16
17 struct slab_obj
18 {
19 struct List list;
20 // 当前slab对象所使用的内存页
21 struct Page *page;
22
23 ul count_using;
24 ul count_free;
25
26 // 当前页面所在的线性地址
27 void *vaddr;
28
29 // 位图
30 ul bmp_len; // 位图的长度(字节)
31 ul bmp_count; // 位图的有效位数
32 ul *bmp;
33 };
34
35 // slab内存池
36 struct slab
37 {
38 ul size; // 单位:byte
39 ul count_total_using;
40 ul count_total_free;
41 // 内存池对象
42 struct slab_obj *cache_pool_entry;
43 // dma内存池对象
44 struct slab_obj *cache_dma_pool_entry;
45
46 spinlock_t lock; // 当前内存池的操作锁
47
48 // 内存池的构造函数和析构函数
49 void *(*constructor)(void *vaddr, ul arg);
50 void *(*destructor)(void *vaddr, ul arg);
51 };
52
53 /**
54 * @brief 通用内存分配函数
55 *
56 * @param size 要分配的内存大小
57 * @param gfp 内存的flag
58 * @return void* 分配得到的内存的指针
59 */
60 void *kmalloc(unsigned long size, gfp_t gfp);
61
62 /**
63 * @brief 从kmalloc申请一块内存,并将这块内存清空
64 *
65 * @param size 要分配的内存大小
66 * @param gfp 内存的flag
67 * @return void* 分配得到的内存的指针
68 */
kzalloc(size_t size,gfp_t gfp)69 static __always_inline void *kzalloc(size_t size, gfp_t gfp)
70 {
71 return kmalloc(size, gfp | __GFP_ZERO);
72 }
73
74 /**
75 * @brief 通用内存释放函数
76 *
77 * @param address 要释放的内存地址
78 * @return unsigned long
79 */
80 unsigned long kfree(void *address);
81
82 /**
83 * @brief 创建一个内存池
84 *
85 * @param size 内存池容量大小
86 * @param constructor 构造函数
87 * @param destructor 析构函数
88 * @param arg 参数
89 * @return struct slab* 构建好的内存池对象
90 */
91 struct slab *slab_create(ul size, void *(*constructor)(void *vaddr, ul arg), void *(*destructor)(void *vaddr, ul arg), ul arg);
92
93 /**
94 * @brief 销毁内存池对象
95 * 只有当slab对象是空的时候才能销毁
96 * @param slab_pool 要销毁的内存池对象
97 * @return ul
98 *
99 */
100 ul slab_destroy(struct slab *slab_pool);
101
102 /**
103 * @brief 分配SLAB内存池中的内存对象
104 *
105 * @param slab_pool slab内存池
106 * @param arg 传递给内存对象构造函数的参数
107 * @return void* 内存空间的虚拟地址
108 */
109 void *slab_malloc(struct slab *slab_pool, ul arg);
110
111 /**
112 * @brief 回收slab内存池中的对象
113 *
114 * @param slab_pool 对应的内存池
115 * @param addr 内存对象的虚拟地址
116 * @param arg 传递给虚构函数的参数
117 * @return ul
118 */
119 ul slab_free(struct slab *slab_pool, void *addr, ul arg);
120
121 /**
122 * @brief 在kmalloc中创建slab_obj的函数(与slab_malloc()类似)
123 *
124 * @param size
125 * @return struct slab_obj* 创建好的slab_obj
126 */
127 struct slab_obj *kmalloc_create_slab_obj(ul size);
128
129 /**
130 * @brief 初始化内存池组
131 * 在初始化通用内存管理单元期间,尚无内存空间分配函数,需要我们手动为SLAB内存池指定存储空间
132 * @return ul
133 */
134 ul slab_init();
135