XWOS API  4.0
XWOS C/C++ API参考手册
载入中...
搜索中...
未找到
bma.c 文件参考

XWOS内存管理:伙伴算法内存块分配器 更多...

#include <xwos/standard.h>
#include <string.h>
#include <xwos/lib/xwlog.h>
#include <xwos/lib/bclst.h>
#include <xwos/lib/xwbop.h>
#include <xwos/osal/lock/spinlock.h>
#include <xwos/mm/common.h>
#include <xwos/mm/bma.h>
bma.c 的引用(Include)关系图:

浏览源代码.

宏定义

#define xwmm_bmalogf(lv, fmt, ...)
 

函数

static struct xwmm_bma_bcbxwmm_bma_mem_to_bcb (struct xwmm_bma *bma, void *mem)
 从内存块首地址获得其控制块的指针
 
static void * xwmm_bma_bcb_to_mem (struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb)
 从内存块的控制块指针获得内存块的首地址
 
static struct xwmm_bma_bcbxwmm_bma_find_buddy (struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb)
 寻找内存块的伙伴
 
static void xwmm_bma_orderlist_add (struct xwmm_bma *bma, struct xwmm_bma_orderlist *ol, xwu8_t odr, struct xwmm_bma_bcb *bcb)
 将一块内存加入到阶链表
 
static xwer_t xwmm_bma_orderlist_remove (struct xwmm_bma *bma, struct xwmm_bma_orderlist *ol, xwu8_t odr, struct xwmm_bma_bcb *bcb)
 从阶链表中删除一块内存
 
static struct xwmm_bma_bcbxwmm_bma_orderlist_choose (struct xwmm_bma *bma, struct xwmm_bma_orderlist *ol)
 从阶链表中选择一块内存,并返回其块控制块
 
static void xwmm_bma_divide_block (struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb, xwsq_t target_odr, struct xwmm_bma_orderlist *curr_ol)
 将大内存块分割成小块
 
static void xwmm_bma_combine (struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb)
 合并内存块
 
xwer_t xwmm_bma_init (struct xwmm_bma *bma, const char *name, xwptr_t origin, xwsz_t size, xwsz_t blksize, xwsz_t blkodr)
 XWMM API:初始化伙伴算法内存块分配器
 
xwer_t xwmm_bma_alloc (struct xwmm_bma *bma, xwsq_t order, void **membuf)
 XWMM API:申请一块连续的内存
 
xwer_t xwmm_bma_free (struct xwmm_bma *bma, void *mem)
 XWMM API:释放内存块
 
xwer_t xwmm_bma_malloc (struct xwmm_bma *bma, xwsz_t size, void **membuf)
 XWMM API:申请指定大小的连续内存
 
xwer_t xwmm_bma_realloc (struct xwmm_bma *bma, xwsz_t size, void **membuf)
 XWMM API:调整内存大小
 
xwer_t xwmm_bma_memalign (struct xwmm_bma *bma, xwsz_t alignment, xwsz_t size, void **membuf)
 XWMM API:申请对齐的内存
 
xwer_t xwmm_bma_malloc_usable_size (struct xwmm_bma *bma, void *mem, xwsz_t *size)
 XWMM API:返回该块内存实际可用字节数
 

详细描述

XWOS内存管理:伙伴算法内存块分配器

作者

在文件 bma.c 中定义.

宏定义说明

◆ xwmm_bmalogf

#define xwmm_bmalogf (   lv,
  fmt,
  ... 
)

< 调试日志开关

在文件 bma.c26 行定义.

函数说明

◆ xwmm_bma_mem_to_bcb()

static struct xwmm_bma_bcb * xwmm_bma_mem_to_bcb ( struct xwmm_bma bma,
void *  mem 
)
static

从内存块首地址获得其控制块的指针

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]mem内存块的首地址
返回
内存块的控制块指针或类型为指针的错误码

在文件 bma.c116 行定义.

117{
118 struct xwmm_bma_bcb * bcb;
119 xwptr_t ofs;
120 xwptr_t idx;
121
122 ofs = (xwptr_t)mem - bma->zone.origin;
123 idx = ofs / (xwptr_t)bma->blksize;
124 if (ofs == (idx * bma->blksize)) {
125 bcb = &bma->bcbs[idx];
126 } else {
127 bcb = err_ptr(-EINVAL);
128 }
129 return bcb;
130}
#define EINVAL
Invalid argument
Definition errno.h:52
static __xwcc_inline void *__xwcc_must_check err_ptr(xwer_t err)
将错误码转换为指针
Definition error.h:42
unsigned long xwptr_t
Definition type.h:375
块控制块
Definition bma.h:72
struct xwmm_zone zone
Definition bma.h:83
struct xwmm_bma_bcb * bcbs
Definition bma.h:89
xwsz_t blksize
Definition bma.h:85
xwptr_t origin
Definition common.h:41
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_bma_bcb_to_mem()

static void * xwmm_bma_bcb_to_mem ( struct xwmm_bma bma,
struct xwmm_bma_bcb bcb 
)
static

从内存块的控制块指针获得内存块的首地址

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]bcb内存块的控制块指针
返回
内存块的首地址

在文件 bma.c139 行定义.

140{
141 xwptr_t idx;
142 xwptr_t mem;
143
144 idx = ((xwptr_t)bcb - (xwptr_t)bma->bcbs) / sizeof(struct xwmm_bma_bcb);
145 mem = (idx * bma->blksize) + bma->zone.origin;
146 return (void *)mem;
147}
这是这个函数的调用关系图:

◆ xwmm_bma_find_buddy()

static struct xwmm_bma_bcb * xwmm_bma_find_buddy ( struct xwmm_bma bma,
struct xwmm_bma_bcb bcb 
)
static

寻找内存块的伙伴

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]bcb内存块的控制块指针
返回
伙伴内存块的控制块指针

< 阶的掩码

在文件 bma.c156 行定义.

158{
159 xwsq_t seq;
160 xwsq_t odr;
161
162 seq = ((xwptr_t)bcb - (xwptr_t)bma->bcbs) / sizeof(struct xwmm_bma_bcb);
163 odr = (xwsq_t)bcb->order & XWMM_BMA_ORDER_MASK;
164 seq ^= (1U << odr);
165 return &bma->bcbs[seq];
166}
#define XWMM_BMA_ORDER_MASK
Definition bma.h:46
unsigned long xwsq_t
Definition type.h:445
xwu8_t order
Definition bma.h:73
这是这个函数的调用关系图:

◆ xwmm_bma_orderlist_add()

static void xwmm_bma_orderlist_add ( struct xwmm_bma bma,
struct xwmm_bma_orderlist ol,
xwu8_t  odr,
struct xwmm_bma_bcb bcb 
)
static

将一块内存加入到阶链表

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]ol阶链表的指针
[in]odr阶链表的阶
[in]bcb内存块的控制块指针

< 块正在被使用

< 阶的掩码

在文件 bma.c176 行定义.

180{
181 struct xwlib_bclst_node * n;
182
183 /* 即将加入的块不在阶链表中,是本地数据。*/
184 if ((XWMM_BMA_INUSED | odr) == bcb->order) {
185 n = xwmm_bma_bcb_to_mem(bma, bcb);
186 xwmm_bmalogf(DEBUG,
187 "[OL:0x%lX][+] bcb(idx:0x%lX,odr:0x%X),mem(0x%lX)\n",
188 (xwptr_t)ol,
189 (((xwptr_t)bcb - (xwptr_t)xwmm_bma->bcbs) /
190 sizeof(struct xwmm_bma_bcb)),
191 bcb->order, (xwptr_t)n);
193 xwlib_bclst_add_head(&ol->head, n);
194 /* 当块被加入到阶链表中,就变成共享数据。*/
196 }
197}
#define xwmm_bmalogf(lv, fmt,...)
Definition bma.c:26
static void * xwmm_bma_bcb_to_mem(struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb)
从内存块的控制块指针获得内存块的首地址
Definition bma.c:139
#define XWMM_BMA_INUSED
Definition bma.h:47
static void xwlib_bclst_init_node(struct xwlib_bclst_node *n)
初始化一个链表节点。
Definition bclst.h:240
static void xwlib_bclst_add_head(struct xwlib_bclst_node *head, struct xwlib_bclst_node *newn)
将一个节点加入链表头部(链表头的后面)
Definition bclst.h:345
双循环链表的节点
Definition bclst.h:27
伙伴算法内存块分配器
Definition bma.h:82
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_bma_orderlist_remove()

static xwer_t xwmm_bma_orderlist_remove ( struct xwmm_bma bma,
struct xwmm_bma_orderlist ol,
xwu8_t  odr,
struct xwmm_bma_bcb bcb 
)
static

从阶链表中删除一块内存

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]ol阶链表的指针
[in]odr阶链表的阶
[in]bcb内存块的控制块指针
返回
错误码
返回值
XWOK删除成功
-ESRCH阶链表中不存在此内存块

< 去除未使用变量的警告

< 块正在被使用

<No error

在文件 bma.c210 行定义.

214{
215 struct xwlib_bclst_node * n;
216 xwer_t rc;
217
218 XWOS_UNUSED(ol);
219 n = xwmm_bma_bcb_to_mem(bma, bcb);
220 xwmm_bmalogf(DEBUG,
221 "[OL:0x%lX][-] bcb(idx:0x%lX,odr:0x%X),mem(0x%lX)\n",
222 (xwptr_t)ol,
223 (((xwptr_t)bcb - (xwptr_t)xwmm_bma->bcbs) /
224 sizeof(struct xwmm_bma_bcb)),
225 bcb->order, (xwptr_t)n);
226 /* 即将被删除的块在阶链表中,是共享数据。*/
227 if (odr != bcb->order) {
228 rc = -ESRCH;
229 } else {
231 bcb->order |= XWMM_BMA_INUSED;
232 rc = XWOK;
233 }
234 return rc;
235}
static void xwlib_bclst_del_init(struct xwlib_bclst_node *node)
删除一个节点,并重新初始化它
Definition bclst.h:391
#define ESRCH
No such process
Definition errno.h:33
#define XWOK
No error
Definition errno.h:182
signed long xwer_t
Definition type.h:554
#define XWOS_UNUSED(x)
Definition standard.h:66
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_bma_orderlist_choose()

static struct xwmm_bma_bcb * xwmm_bma_orderlist_choose ( struct xwmm_bma bma,
struct xwmm_bma_orderlist ol 
)
static

从阶链表中选择一块内存,并返回其块控制块

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]ol阶链表的指针
返回
块控制块指针或类型为指针的错误码
返回值
-ENOENT阶链表为空

< 块正在被使用

在文件 bma.c245 行定义.

247{
248 struct xwlib_bclst_node * n;
249 struct xwmm_bma_bcb * bcb;
250
251 if (xwlib_bclst_tst_empty(&ol->head)) {
252 bcb = err_ptr(-ENOENT);
253 } else {
254 n = ol->head.next;
256 bcb = xwmm_bma_mem_to_bcb(bma, n);
257 xwmm_bmalogf(DEBUG,
258 "[OL:0x%lX][C] bcb(idx:0x%lX,odr:0x%X)\n",
259 (xwptr_t)ol,
260 (((xwptr_t)bcb - (xwptr_t)xwmm_bma->bcbs) /
261 sizeof(struct xwmm_bma_bcb)),
262 bcb->order);
263 /* 即将被选择的块在阶链表中,是共享数据。*/
264 bcb->order |= XWMM_BMA_INUSED;
265 }
266 return bcb;
267}
static struct xwmm_bma_bcb * xwmm_bma_mem_to_bcb(struct xwmm_bma *bma, void *mem)
从内存块首地址获得其控制块的指针
Definition bma.c:116
static bool xwlib_bclst_tst_empty(const struct xwlib_bclst_node *h)
测试链表是否为空。
Definition bclst.h:253
#define ENOENT
No such file or directory
Definition errno.h:32
struct xwlib_bclst_node * next
Definition bclst.h:28
struct xwlib_bclst_node head
Definition bma.h:66
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_bma_divide_block()

static void xwmm_bma_divide_block ( struct xwmm_bma bma,
struct xwmm_bma_bcb bcb,
xwsq_t  target_odr,
struct xwmm_bma_orderlist curr_ol 
)
static

将大内存块分割成小块

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]bcb大块的内存块的控制块的指针
[in]target_odr目标块数量的阶
[in]curr_ol当前被分割的大块所在的阶链表

< 阶的掩码

< 块已被合并

< 块正在被使用

< 报告BUG

< 当条件x成立时报告BUG

< 块正在被使用

< 块正在被使用

在文件 bma.c277 行定义.

279{
280 xwsq_t blk_odr;
281 xwsq_t blk_idx;
282 xwsq_t blk_ofs;
283 struct xwmm_bma_bcb * buddy;
284
285 blk_odr = (xwsq_t)bcb->order & XWMM_BMA_ORDER_MASK;
286 blk_idx = ((xwptr_t)bcb - (xwptr_t)bma->bcbs) / sizeof(struct xwmm_bma_bcb);
287
288 while (blk_odr > target_odr) {
289 curr_ol--;
290 blk_odr--;
291 blk_ofs = 1U << blk_odr;
292 buddy = &bma->bcbs[blk_idx + blk_ofs];
293 /* 加入阶链表之前, `buddy` 是本地数据。*/
294 XWOS_BUG_ON((XWMM_BMA_COMBINED | XWMM_BMA_INUSED) != buddy->order);
295 buddy->order = (xwu8_t)blk_odr | XWMM_BMA_INUSED;
296 xwmm_bma_orderlist_add(bma, curr_ol, blk_odr, buddy);
297 /* `bcb` 是本地数据。*/
298 bcb->order = (xwu8_t)blk_odr | XWMM_BMA_INUSED;
299 xwmm_bmalogf(DEBUG,
300 "[ALLOC][D] bcb(idx:0x%lX,odr:0x%X),"
301 "buddy(idx:0x%lX,odr:0x%X)\n",
302 (((xwptr_t)bcb - (xwptr_t)xwmm_bma->bcbs) /
303 sizeof(struct xwmm_bma_bcb)),
304 bcb->order,
305 (((xwptr_t)buddy - (xwptr_t)xwmm_bma->bcbs) /
306 sizeof(struct xwmm_bma_bcb)),
307 buddy->order);
308 }
309}
static void xwmm_bma_orderlist_add(struct xwmm_bma *bma, struct xwmm_bma_orderlist *ol, xwu8_t odr, struct xwmm_bma_bcb *bcb)
将一块内存加入到阶链表
Definition bma.c:176
#define XWMM_BMA_COMBINED
Definition bma.h:45
uint8_t xwu8_t
Definition type.h:194
#define XWOS_BUG_ON(x)
Definition standard.h:57
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_bma_combine()

static void xwmm_bma_combine ( struct xwmm_bma bma,
struct xwmm_bma_bcb bcb 
)
static

合并内存块

参数
[in]bma伙伴算法内存块分配器对象的指针
[in]bcb内存块的控制块的指针
返回
错误码

< 阶的掩码

< 块已被合并

< 块正在被使用

< 报告BUG

< 当条件x成立时报告BUG

< 块已被合并

< 块正在被使用

< 块正在被使用

< 块已被合并

< 块正在被使用

< 块正在被使用

在文件 bma.c359 行定义.

360{
361 struct xwmm_bma_bcb * buddy;
362 xwsq_t curr_odr;
363 xwsq_t target_odr;
364 xwer_t rc;
365
366 curr_odr = (bcb->order & XWMM_BMA_ORDER_MASK);
367 target_odr = curr_odr + (xwsq_t)1;
368 while (target_odr <= bma->blkodr) {
369 buddy = xwmm_bma_find_buddy(bma, bcb);
370 xwmm_bmalogf(DEBUG,
371 "[FREE][M] bcb(idx:0x%lX,odr:0x%X),"
372 "buddy(idx:0x%lX,odr:0x%X)\n",
373 (((xwptr_t)bcb - (xwptr_t)xwmm_bma->bcbs) /
374 sizeof(struct xwmm_bma_bcb)),
375 bcb->order,
376 (((xwptr_t)buddy - (xwptr_t)xwmm_bma->bcbs) /
377 sizeof(struct xwmm_bma_bcb)),
378 buddy->order);
381 &bma->orderlists[curr_odr],
382 curr_odr,
383 buddy);
384 if (rc < 0) {
385 break;
386 }
387 /* 此时 `buddy->order` 以及 `bcb->order` 都是本地数据。 */
388 if (buddy > bcb) {
390 bcb->order = (xwu8_t)target_odr | XWMM_BMA_INUSED;
391 } else {
393 buddy->order = (xwu8_t)target_odr | XWMM_BMA_INUSED;
394 bcb = buddy;
395 }
396 curr_odr = target_odr;
397 target_odr++;
398 }
399 xwmm_bma_orderlist_add(bma, &bma->orderlists[curr_odr], curr_odr, bcb);
400}
static struct xwmm_bma_bcb * xwmm_bma_find_buddy(struct xwmm_bma *bma, struct xwmm_bma_bcb *bcb)
寻找内存块的伙伴
Definition bma.c:156
static xwer_t xwmm_bma_orderlist_remove(struct xwmm_bma *bma, struct xwmm_bma_orderlist *ol, xwu8_t odr, struct xwmm_bma_bcb *bcb)
从阶链表中删除一块内存
Definition bma.c:210
struct xwmm_bma_orderlist * orderlists
Definition bma.h:88
函数调用图:
这是这个函数的调用关系图: