XWOS API  4.0
XWOS C/C++ API参考手册
载入中...
搜索中...
未找到
page.c
浏览该文件的文档.
1
13#include <xwos/standard.h>
14#include <xwos/lib/rbtree.h>
15#include <xwos/lib/bclst.h>
16#include <xwos/lib/xwbop.h>
18#include <xwos/mm/common.h>
21
22/* #define XWMM_MEMPOOLLOGF */
23#ifdef XWMM_MEMPOOLLOGF
24# define xwmm_mempoollogf(lv, thd, fmt, ...) \
25 xwlogf(lv, "Thd:%s", fmt, thd->stack.name, ##__VA_ARGS__)
26#else
27# define xwmm_mempoollogf(lv, thd, fmt, ...)
28#endif
29
30static __xwos_code
31xwer_t xwmm_mempool_page_i_a_malloc(void * this, xwsz_t size, void ** membuf);
32
33static __xwos_code
34xwer_t xwmm_mempool_page_i_a_free(void * this, void * mem);
35
36static __xwos_code
38 struct xwmm_mempool_page * pg,
39 xwsq_t target_odr,
40 struct xwmm_mempool_page_odrbtree * ot);
41
42static __xwos_code
44 struct xwmm_mempool_page * pg);
45
46static __xwos_code
48 struct xwmm_mempool_page * pg);
49
50static __xwos_code
52 struct xwmm_mempool_page * pg);
53
54static __xwos_code
55struct xwmm_mempool_page *
57
58static __xwos_code
60 struct xwmm_mempool_page * pg);
61
62static __xwos_code
63struct xwmm_mempool_page *
65
66static __xwos_code
67struct xwmm_mempool_page *
69 struct xwmm_mempool_page * pg);
70
87 const char * name,
88 xwptr_t origin, xwsz_t size, xwsz_t pgsize,
89 struct xwmm_mempool_page_odrbtree * odrbtree,
90 struct xwmm_mempool_page * pgarray)
91{
92 xwsz_t i;
94 xwsz_t nr;
95 xwer_t rc;
96
97 if (size < pgsize) {
98 rc = -E2SMALL;
99 goto err_mem2small;
100 }
101 // cppcheck-suppress [misra-c2012-10.8]
102 if ((xwsz_t)0 != (pgsize & (xwsz_t)XWMM_UNALIGNED_MASK)) {
103 rc = -EALIGN;
104 goto err_aligned;
105 }
106 nr = size / pgsize;
107 order = xwbop_fls(xwsz_t, nr);
108 if ((order < 0) || (nr & ((1U << (xwsz_t)order) - 1U))) {
109 rc = -EALIGN;
110 goto err_aligned;
111 }
112
113 pa->zone.origin = origin;
114 pa->zone.size = size;
115 pa->name = name;
116 pa->pgsize = pgsize;
117 pa->max_order = (xwsq_t)order;
118 pa->odrbtree = odrbtree;
119 pa->pgarray = pgarray;
120
121 for (i = 0; i <= pa->max_order; i++) {
123 pa->odrbtree[i].leftmost = NULL;
124 pa->odrbtree[i].owner = pa;
125 pa->odrbtree[i].order = i;
127 }
128 for (i = 0; i < nr; i++) {
131 pa->pgarray[i].attr.free.seq = i;
133 pa->pgarray[i].data.value = 0;
134 }
135 // cppcheck-suppress [misra-c2012-17.7]
137 &pa->pgarray[0]);
138
141
142 return XWOK;
143
144err_aligned:
145err_mem2small:
146 return rc;
147}
148
161 struct xwmm_mempool_page ** pgbuf)
162{
163 xwsq_t odr;
164 struct xwmm_mempool_page_odrbtree * ot;
165 struct xwmm_mempool_page * pg;
166 xwptr_t origin;
167 xwer_t rc;
168
169 rc = -ENOMEM;
170 for (odr = order; odr <= pa->max_order; odr++) {
171 ot = &pa->odrbtree[odr];
173 if (NULL != pg) {
175 origin = pa->zone.origin + (pg->attr.free.seq * pa->pgsize);
176 pg->mapping = origin;
177 *pgbuf = pg;
178 rc = XWOK;
179 break;
180 }
181 }
182 return rc;
183}
184
195 struct xwmm_mempool_page * pg)
196{
197 xwer_t rc;
198
200 rc = -EALREADY;
201 goto err_already;
202 }
206 pg->data.value = 0;
208 return XWOK;
209
210err_already:
211 return rc;
212}
213
221static __xwos_code
223 struct xwmm_mempool_page * pg,
224 xwsq_t target_odr,
225 struct xwmm_mempool_page_odrbtree * ot)
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}
245
251static __xwos_code
253 struct xwmm_mempool_page * pg)
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}
283
292static __xwos_code
294 struct xwmm_mempool_page * pg)
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}
353
363static __xwos_code
365 struct xwmm_mempool_page * pg)
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}
408
414static __xwos_code
415struct xwmm_mempool_page *
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}
451
458static __xwos_code
460 struct xwmm_mempool_page * pg)
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}
468
475static __xwos_code
476struct xwmm_mempool_page *
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}
488
495static __xwos_code
496struct xwmm_mempool_page *
498 struct xwmm_mempool_page * pg)
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}
508
520 struct xwmm_mempool_page ** pgbuf)
521{
522 xwer_t rc;
523 struct xwmm_mempool_page * pg;
524
525 if (((xwptr_t)mem < pa->zone.origin) ||
526 ((xwptr_t)mem >= (pa->zone.origin + pa->zone.size))) {
527 rc = -ERANGE;
528 } else {
529 pg = xwmm_mempool_mem_to_page(pa, mem);
530 while (XWMM_MEMPOOL_PAGE_ORDER_CMB == pg->order) {
531 pg--;
532 }
533 *pgbuf = pg;
534 rc = XWOK;
535 }
536 return rc;
537}
538
548static __xwos_code
549xwer_t xwmm_mempool_page_i_a_malloc(void * this, xwsz_t size, void ** membuf)
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}
570
579static __xwos_code
580xwer_t xwmm_mempool_page_i_a_free(void * this, void * mem)
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}
XWOS通用库:双循环链表
#define XWMM_UNALIGNED_MASK
Definition common.h:30
xwer_t xwmm_mempool_page_free(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
XWMM API:释放一页内存
Definition page.c:194
#define XWMM_MEMPOOL_PAGE_ORDER_CMB
Definition page.h:30
#define XWMM_MEMPOOL_PAGE_MAPPING_FREE
Definition page.h:31
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
#define XWMM_MEMPOOL_PAGE_MAPPING_INVAILD
Definition page.h:32
xwer_t xwmm_mempool_page_find(struct xwmm_mempool_page_allocator *pa, void *mem, struct xwmm_mempool_page **pgbuf)
依据内存地址查找页
Definition page.c:519
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:初始化页分配器
Definition page.c:86
#define __xwos_code
Definition compiler.h:171
#define __xwos_api
Definition compiler.h:175
#define EEXIST
File exists
Definition errno.h:47
#define ESRCH
No such process
Definition errno.h:33
#define E2SMALL
Too small
Definition errno.h:200
#define EALIGN
Not aligned
Definition errno.h:201
#define ENOMEM
Not enough space
Definition errno.h:42
#define XWOK
No error
Definition errno.h:182
#define EBUSY
Device or resource busy
Definition errno.h:46
#define ERANGE
Result too large
Definition errno.h:64
#define EALREADY
Socket already connected
Definition errno.h:133
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_insert_color(struct xwlib_rbtree *tree, struct xwlib_rbtree_node *node)
插入一个红色节点后修正红黑树的颜色
Definition rbtree.c:17
static void xwlib_rbtree_init(struct xwlib_rbtree *rbt)
初始化红黑树
Definition rbtree.h:104
#define xwlib_rbtree_entry(ptr, type, member)
从红黑树节点指针值计算出包含该节点成员的外层结构体的指针值
Definition rbtree.h:236
void xwlib_rbtree_remove(struct xwlib_rbtree *tree, struct xwlib_rbtree_node *node)
删除一个节点,并修正红黑树的颜色
Definition rbtree.c:320
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
signed long xwer_t
Definition type.h:554
#define NULL
Definition type.h:28
unsigned long xwsz_t
Definition type.h:339
unsigned long xwsq_t
Definition type.h:445
signed long xwssq_t
Definition type.h:461
unsigned long xwptr_t
Definition type.h:375
xwptr_t xwreg_t
Definition type.h:409
#define xwbop_fls(type, data)
XWOS BOPLIB:在数据中从最高位起查找第一个被置1的位
Definition xwbop.h:169
static void xwos_sqlk_init(struct xwos_sqlk *sql)
XWOS API:初始化顺序锁
Definition seqlock.h:133
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
XWOS内存管理:内存池:分配器接口
操作系统抽象层:顺序锁
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_i_a_malloc(void *this, xwsz_t size, void **membuf)
i_allocator接口函数:申请内存
Definition page.c:549
static xwer_t xwmm_mempool_page_i_a_free(void *this, void *mem)
i_allocator接口函数:释放内存
Definition page.c:580
static struct xwmm_mempool_page * xwmm_mempool_mem_to_page(struct xwmm_mempool_page_allocator *pa, void *mem)
从页内存地址获得其页控制块的指针
Definition page.c:477
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)
将大的页拆分成小的页
Definition page.c:222
static void xwmm_mempool_page_combine(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
合并空闲的伙伴页
Definition page.c:252
static struct xwmm_mempool_page * xwmm_mempool_page_odrbtree_choose(struct xwmm_mempool_page_odrbtree *ot)
从阶红黑树中选择一页
Definition page.c:416
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
static xwsq_t xwmm_mempool_page_get_seq(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
获取页的序列值
Definition page.c:459
XWOS内存管理:内存池:页分配器
XWOS通用库:红黑树
红黑树节点
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
xwer_t(* free)(void *, void *)
Definition i_allocator.h:31
xwer_t(* malloc)(void *, xwsz_t, void **)
Definition i_allocator.h:29
struct xwmm_mempool_i_allocator i_a
Definition page.h:84
struct xwmm_mempool_page * pgarray
Definition page.h:90
struct xwmm_zone zone
Definition page.h:85
const char * name
Definition page.h:86
struct xwmm_mempool_page_odrbtree * odrbtree
Definition page.h:89
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 xwmm_mempool_page_allocator * owner
Definition page.h:76
内存页
Definition page.h:37
xwsq_t seq
Definition page.h:48
xwsq_t value
Definition page.h:61
struct xwlib_rbtree_node rbnode
Definition page.h:47
union xwmm_mempool_page::@1 attr
xwptr_t mapping
Definition page.h:40
union xwmm_mempool_page::@2 data
struct xwmm_mempool_page::@1::@3 free
xwsq_t order
Definition page.h:38
xwptr_t origin
Definition common.h:41
xwsz_t size
Definition common.h:42
XWOS通用库:位操作
XWOS内存管理:通用定义
XWOS的标准头文件