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

XWOS内存管理:内存池:页分配器 更多...

page.c 的引用(Include)关系图:

浏览源代码.

宏定义

#define xwmm_mempoollogf(lv, thd, fmt, ...)
 

函数

static xwer_t xwmm_mempool_page_i_a_malloc (void *this, xwsz_t size, void **membuf)
 i_allocator接口函数:申请内存
 
static xwer_t xwmm_mempool_page_i_a_free (void *this, void *mem)
 i_allocator接口函数:释放内存
 
static void xwmm_mempool_page_divide_page (struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg, xwsq_t target_odr, struct xwmm_mempool_page_odrbtree *ot)
 将大的页拆分成小的页
 
static void xwmm_mempool_page_combine (struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
 合并空闲的伙伴页
 
static xwer_t xwmm_mempool_page_odrbtree_add (struct xwmm_mempool_page_odrbtree *ot, struct xwmm_mempool_page *pg)
 增加页到阶红黑树中
 
static xwer_t xwmm_mempool_page_odrbtree_remove (struct xwmm_mempool_page_odrbtree *ot, struct xwmm_mempool_page *pg)
 从阶红黑树中删除页
 
static struct xwmm_mempool_pagexwmm_mempool_page_odrbtree_choose (struct xwmm_mempool_page_odrbtree *ot)
 从阶红黑树中选择一页
 
static xwsq_t xwmm_mempool_page_get_seq (struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
 获取页的序列值
 
static struct xwmm_mempool_pagexwmm_mempool_mem_to_page (struct xwmm_mempool_page_allocator *pa, void *mem)
 从页内存地址获得其页控制块的指针
 
static struct xwmm_mempool_pagexwmm_mempool_page_get_buddy (struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
 找到页的伙伴页
 
xwer_t xwmm_mempool_page_allocator_init (struct xwmm_mempool_page_allocator *pa, const char *name, xwptr_t origin, xwsz_t size, xwsz_t pgsize, struct xwmm_mempool_page_odrbtree *odrbtree, struct xwmm_mempool_page *pgarray)
 XWMM API:初始化页分配器
 
xwer_t xwmm_mempool_page_allocate (struct xwmm_mempool_page_allocator *pa, xwsq_t order, struct xwmm_mempool_page **pgbuf)
 XWMM API:申请一页内存
 
xwer_t xwmm_mempool_page_free (struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
 XWMM API:释放一页内存
 
xwer_t xwmm_mempool_page_find (struct xwmm_mempool_page_allocator *pa, void *mem, struct xwmm_mempool_page **pgbuf)
 依据内存地址查找页
 

详细描述

XWOS内存管理:内存池:页分配器

作者

在文件 page.c 中定义.

宏定义说明

◆ xwmm_mempoollogf

#define xwmm_mempoollogf (   lv,
  thd,
  fmt,
  ... 
)

< 调试日志开关

在文件 page.c27 行定义.

函数说明

◆ xwmm_mempool_mem_to_page()

static struct xwmm_mempool_page * xwmm_mempool_mem_to_page ( struct xwmm_mempool_page_allocator pa,
void *  mem 
)
static

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

参数
[in]pa页分配器的指针
[in]mem内存块的首地址
返回
页的控制块指针

在文件 page.c477 行定义.

478{
479 xwsq_t seq;
480 xwptr_t offset;
481 struct xwmm_mempool_page * pg;
482
483 offset = (xwptr_t)mem - pa->zone.origin;
484 seq = offset / pa->pgsize;
485 pg = &pa->pgarray[seq];
486 return pg;
487}
unsigned long xwsq_t
Definition type.h:445
unsigned long xwptr_t
Definition type.h:375
struct xwmm_mempool_page * pgarray
Definition page.h:90
struct xwmm_zone zone
Definition page.h:85
内存页
Definition page.h:37
xwsq_t seq
Definition page.h:48
xwptr_t origin
Definition common.h:41
这是这个函数的调用关系图:

◆ xwmm_mempool_page_combine()

static void xwmm_mempool_page_combine ( struct xwmm_mempool_page_allocator pa,
struct xwmm_mempool_page pg 
)
static

合并空闲的伙伴页

参数
[in]pa页分配器的指针
[in]pg页控制块的指针

在文件 page.c252 行定义.

254{
255 struct xwmm_mempool_page * buddy;
256 xwsq_t odr;
257 xwer_t rc;
258
259 odr = pg->order + 1U;
260 while (odr < pa->max_order) {
261 buddy = xwmm_mempool_page_get_buddy(pa, pg);
262 /* `buddy->order` 不能在临界区外使用,
263 因为 `buddy` 在阶红黑树上时,是共享数据。
264 但可以使用 `pg->order` ,因为 `pg` 还未加入到阶红黑树,是本地数据。*/
265 rc = xwmm_mempool_page_odrbtree_remove(&pa->odrbtree[pg->order], buddy);
266 if (rc < 0) {
267 break;
268 }
269 if (buddy > pg) {
271 pg->order = odr;
272 } else {
274 buddy->order = odr;
275 pg = buddy;
276 }
277 odr++;
278 }
279 odr = pg->order;
280 // cppcheck-suppress [misra-c2012-17.7]
282}
#define XWMM_MEMPOOL_PAGE_ORDER_CMB
Definition page.h:30
signed long xwer_t
Definition type.h:554
static xwer_t xwmm_mempool_page_odrbtree_remove(struct xwmm_mempool_page_odrbtree *ot, struct xwmm_mempool_page *pg)
从阶红黑树中删除页
Definition page.c:364
static xwer_t xwmm_mempool_page_odrbtree_add(struct xwmm_mempool_page_odrbtree *ot, struct xwmm_mempool_page *pg)
增加页到阶红黑树中
Definition page.c:293
static struct xwmm_mempool_page * xwmm_mempool_page_get_buddy(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
找到页的伙伴页
Definition page.c:497
struct xwmm_mempool_page_odrbtree * odrbtree
Definition page.h:89
xwsq_t order
Definition page.h:38
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_divide_page()

static void xwmm_mempool_page_divide_page ( struct xwmm_mempool_page_allocator pa,
struct xwmm_mempool_page pg,
xwsq_t  target_odr,
struct xwmm_mempool_page_odrbtree ot 
)
static

将大的页拆分成小的页

参数
[in]pa页分配器的指针
[in]pg被拆分的页控制块的指针
[in]target_odr目标页数量的阶
[in]ot被拆分的页所在的阶红黑树的指针

在文件 page.c222 行定义.

226{
227 xwsq_t pg_odr;
228 xwsq_t pg_seq;
229 xwsq_t pg_offset;
230 struct xwmm_mempool_page * buddy;
231
232 pg_odr = pg->order;
233 pg_seq = pg->attr.free.seq;
234 pg_offset = 1U << pg_odr;
235 while (pg_odr > target_odr) {
236 ot--;
237 pg_odr--;
238 pg_offset >>= 1;
239 buddy = &pa->pgarray[pg_seq + pg_offset];
240 // cppcheck-suppress [misra-c2012-17.7]
242 pg->order = pg_odr;
243 }
244}
union xwmm_mempool_page::@1 attr
struct xwmm_mempool_page::@1::@3 free
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_get_buddy()

static struct xwmm_mempool_page * xwmm_mempool_page_get_buddy ( struct xwmm_mempool_page_allocator pa,
struct xwmm_mempool_page pg 
)
static

找到页的伙伴页

参数
[in]pa页分配器的指针
[in]pg页控制块的指针
返回
伙伴页控制块的指针

在文件 page.c497 行定义.

499{
500 xwsq_t seq;
501 xwsq_t odr;
502
503 seq = pg->attr.free.seq;
504 odr = pg->order;
505 seq ^= (1U << odr);
506 return &pa->pgarray[seq];
507}
这是这个函数的调用关系图:

◆ xwmm_mempool_page_get_seq()

static xwsq_t xwmm_mempool_page_get_seq ( struct xwmm_mempool_page_allocator pa,
struct xwmm_mempool_page pg 
)
static

获取页的序列值

参数
[in]pa页分配器的指针
[in]pg页控制块的指针
返回
序列值

在文件 page.c459 行定义.

461{
462 xwsq_t offset;
463
464 offset = (xwsq_t)((xwptr_t)pg - (xwptr_t)(pa->pgarray));
465 offset /= (xwsq_t)sizeof(struct xwmm_mempool_page);
466 return offset;
467}
这是这个函数的调用关系图:

◆ xwmm_mempool_page_i_a_free()

static xwer_t xwmm_mempool_page_i_a_free ( void *  this,
void *  mem 
)
static

i_allocator接口函数:释放内存

参数
[in]thisthis指针(页分配器)
[in]mem内存的首地址
返回
错误码
返回值
XWOK没有错误
-ENOMEM内存不足

<No error

在文件 page.c580 行定义.

581{
582 struct xwmm_mempool_page_allocator * pa;
583 struct xwmm_mempool_page * pg;
584 xwer_t rc;
585
586 pa = this;
587
588 if (((xwptr_t)mem < pa->zone.origin) ||
589 (((xwptr_t)mem - pa->zone.origin) >= (xwptr_t)pa->zone.size)) {
590 rc = -ERANGE;
591 goto err_range;
592 }
593
594 pg = xwmm_mempool_mem_to_page(pa, mem);
595 rc = xwmm_mempool_page_free(pa, pg);
596 if (rc < 0) {
597 goto err_page_free;
598 }
599 return XWOK;
600
601err_page_free:
602err_range:
603 return rc;
604}
xwer_t xwmm_mempool_page_free(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
XWMM API:释放一页内存
Definition page.c:194
#define XWOK
No error
Definition errno.h:182
#define ERANGE
Result too large
Definition errno.h:64
static struct xwmm_mempool_page * xwmm_mempool_mem_to_page(struct xwmm_mempool_page_allocator *pa, void *mem)
从页内存地址获得其页控制块的指针
Definition page.c:477
xwsz_t size
Definition common.h:42
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_i_a_malloc()

static xwer_t xwmm_mempool_page_i_a_malloc ( void *  this,
xwsz_t  size,
void **  membuf 
)
static

i_allocator接口函数:申请内存

参数
[in]thisthis指针(页分配器)
[in]size申请的大小
[out]membuf指向缓冲区的指针,通过此缓冲区返回申请到的内存的首地址
返回
错误码
返回值
XWOK没有错误
-ENOMEM内存不足

<No error

在文件 page.c549 行定义.

550{
551 struct xwmm_mempool_page_allocator * pa;
552 struct xwmm_mempool_page * pg;
554 xwsz_t nr;
555 xwer_t rc;
556
557 pa = this;
558 nr = size / pa->pgsize;
559 order = xwbop_fls(xwsz_t, nr);
560 if ((order < 0) || ((pa->pgsize << (xwsz_t)order) < size)) {
561 order++;
562 }
564 if (XWOK == rc) {
565 pg->data.value = size;
566 *membuf = (void *)pg->mapping;
567 }
568 return rc;
569}
xwer_t xwmm_mempool_page_allocate(struct xwmm_mempool_page_allocator *pa, xwsq_t order, struct xwmm_mempool_page **pgbuf)
XWMM API:申请一页内存
Definition page.c:159
unsigned long xwsz_t
Definition type.h:339
signed long xwssq_t
Definition type.h:461
#define xwbop_fls(type, data)
XWOS BOPLIB:在数据中从最高位起查找第一个被置1的位
Definition xwbop.h:169
xwsq_t value
Definition page.h:61
xwptr_t mapping
Definition page.h:40
union xwmm_mempool_page::@2 data
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_odrbtree_add()

static xwer_t xwmm_mempool_page_odrbtree_add ( struct xwmm_mempool_page_odrbtree ot,
struct xwmm_mempool_page pg 
)
static

增加页到阶红黑树中

参数
[in]ot阶红黑树的指针
[in]pg页控制块的指针
返回
错误码
返回值
XWOK没有错误
-EEXIST页已在阶红黑树中

< 报告BUG

<No error

在文件 page.c293 行定义.

295{
296 struct xwlib_rbtree * tree;
297 struct xwlib_rbtree_node ** new;
298 xwptr_t lpc;
299 struct xwlib_rbtree_node * rbn;
300 xwsq_t pgseq;
301 struct xwmm_mempool_page * b;
302 struct xwmm_mempool_page * leftmost;
303 xwreg_t flag;
304 xwer_t rc;
305
306 tree = &ot->tree;
307 pgseq = pg->attr.free.seq;
308 /* 即将加入的页不在阶红黑树中,是本地数据,对 `pg->mapping` 的读可在锁外。*/
310 rc = -EEXIST;
311 goto err_exist;
312 }
313
314 pg->order = ot->order;
315 xwos_sqlk_wr_lock_cpuirqsv(&ot->lock, &flag);
316 /* 当页被加入到阶红黑树中,就变成共享数据,对 `pg->mapping` 的写只在锁内。*/
318 new = &tree->root;
319 lpc = (xwptr_t)new;
320 leftmost = ot->leftmost;
321 if (NULL == leftmost) { /* rbtree is empty. */
322 ot->leftmost = pg;
323 } else if (pgseq < leftmost->attr.free.seq) {
324 new = &(leftmost->attr.free.rbnode.left);
325 lpc = (xwptr_t)new;
326 ot->leftmost = pg;
327 } else {
328 rbn = *new;
329 while (NULL != rbn) {
331 attr.free.rbnode);
332 if (pgseq < b->attr.free.seq) {
333 new = &rbn->left;
334 lpc = (xwptr_t)new;
335 rbn = rbn->left;
336 } else if (pgseq > b->attr.free.seq) {
337 new = &rbn->right;
339 rbn = rbn->right;
340 } else {
341 XWOS_BUG();
342 }
343 }
344 }
348 return XWOK;
349
350err_exist:
351 return rc;
352}
#define XWMM_MEMPOOL_PAGE_MAPPING_FREE
Definition page.h:31
#define EEXIST
File exists
Definition errno.h:47
void xwlib_rbtree_insert_color(struct xwlib_rbtree *tree, struct xwlib_rbtree_node *node)
插入一个红色节点后修正红黑树的颜色
Definition rbtree.c:17
#define xwlib_rbtree_entry(ptr, type, member)
从红黑树节点指针值计算出包含该节点成员的外层结构体的指针值
Definition rbtree.h:236
static void xwlib_rbtree_link(struct xwlib_rbtree_node *node, xwptr_t lpc)
链接节点,并设置位置及颜色信息
Definition rbtree.h:350
@ XWLIB_RBTREE_POS_RIGHT
Definition rbtree.h:67
#define NULL
Definition type.h:28
xwptr_t xwreg_t
Definition type.h:409
static void xwos_sqlk_wr_lock_cpuirqsv(struct xwos_sqlk *sql, xwreg_t *cpuirq)
XWOS API:开启写临界区,保存本地CPU的中断标志并关闭
Definition seqlock.h:580
static void xwos_sqlk_wr_unlock_cpuirqrs(struct xwos_sqlk *sql, xwreg_t cpuirq)
XWOS API:关闭写临界区,恢复本地CPU的中断标志
Definition seqlock.h:613
#define XWOS_BUG()
Definition standard.h:53
红黑树节点
Definition rbtree.h:81
struct xwlib_rbtree_node * left
Definition rbtree.h:82
struct xwlib_rbtree_node * right
Definition rbtree.h:83
union xwlib_rbtree_node::@5 lpc
红黑树
Definition rbtree.h:95
struct xwlib_rbtree_node * root
Definition rbtree.h:96
struct xwlib_rbtree tree
Definition page.h:73
struct xwmm_mempool_page * leftmost
Definition page.h:74
struct xwos_sqlk lock
Definition page.h:77
struct xwlib_rbtree_node rbnode
Definition page.h:47
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_odrbtree_choose()

static struct xwmm_mempool_page * xwmm_mempool_page_odrbtree_choose ( struct xwmm_mempool_page_odrbtree ot)
static

从阶红黑树中选择一页

参数
[in]ot阶红黑树的指针
返回
页控制块的指针或空指针

在文件 page.c416 行定义.

417{
418 struct xwmm_mempool_page * leftmost;
419 xwreg_t flag;
420 struct xwlib_rbtree * tree;
421 struct xwlib_rbtree_node * s;
422
423 tree = &ot->tree;
424 xwos_sqlk_wr_lock_cpuirqsv(&ot->lock, &flag);
425 leftmost = ot->leftmost;
426 if (NULL == leftmost) {
428 goto err_empty;
429 }
430 /* 即将被选择的页在阶红黑树中,是共享数据。对 `pg->mapping` 的写只可在锁内。*/
432 s = leftmost->attr.free.rbnode.right;
433 if (NULL == s) {
434 s = xwlib_rbtree_get_parent(&leftmost->attr.free.rbnode);
435 }
436 if (s != (struct xwlib_rbtree_node *)&tree->root) {
438 attr.free.rbnode);
439 } else {
440 ot->leftmost = NULL;
441 }
442 xwlib_rbtree_remove(tree, &leftmost->attr.free.rbnode);
444
446 return leftmost;
447
448err_empty:
449 return NULL;
450}
#define XWMM_MEMPOOL_PAGE_MAPPING_INVAILD
Definition page.h:32
static void xwlib_rbtree_init_node(struct xwlib_rbtree_node *rbn)
初始化红黑树节点
Definition rbtree.h:114
static struct xwlib_rbtree_node * xwlib_rbtree_get_parent(struct xwlib_rbtree_node *node)
返回节点的父节点指针
Definition rbtree.h:253
void xwlib_rbtree_remove(struct xwlib_rbtree *tree, struct xwlib_rbtree_node *node)
删除一个节点,并修正红黑树的颜色
Definition rbtree.c:320
函数调用图:
这是这个函数的调用关系图:

◆ xwmm_mempool_page_odrbtree_remove()

static xwer_t xwmm_mempool_page_odrbtree_remove ( struct xwmm_mempool_page_odrbtree ot,
struct xwmm_mempool_page pg 
)
static

从阶红黑树中删除页

参数
[in]ot阶红黑树的指针
[in]pg页控制块的指针
返回
错误码
返回值
XWOK没有错误
-ESRCH页不在阶红黑树中
-EBUSY页不在阶红黑树中

<No error

在文件 page.c364 行定义.

366{
367 struct xwlib_rbtree * tree;
368 struct xwlib_rbtree_node * s;
369 xwreg_t flag;
370 xwer_t rc;
371
372 tree = &ot->tree;
373 if (pg->order != ot->order) {
374 rc = -ESRCH;
375 goto err_odrerr;
376 }
377
378 xwos_sqlk_wr_lock_cpuirqsv(&ot->lock, &flag);
379 /* 即将被删除的页在阶红黑树中,是共享数据。对 `pg->mapping` 的读只可在锁内。*/
381 rc = -EBUSY;
382 goto err_notfree;
383 }
385 if (pg == ot->leftmost) {
386 s = pg->attr.free.rbnode.right;
387 if (NULL == s) {
389 }
390 if (s != (struct xwlib_rbtree_node *)&tree->root) {
392 struct xwmm_mempool_page,
393 attr.free.rbnode);
394 } else {
395 ot->leftmost = NULL;
396 }
397 }
401 return XWOK;
402
403err_notfree:
405err_odrerr:
406 return rc;
407}
#define ESRCH
No such process
Definition errno.h:33
#define EBUSY
Device or resource busy
Definition errno.h:46
函数调用图:
这是这个函数的调用关系图: