XWOS API  4.0
XWOS C/C++ API参考手册
载入中...
搜索中...
未找到
objcache.c
浏览该文件的文档.
1
13#include <xwos/standard.h>
14#include <xwos/lib/xwbop.h>
15#include <xwos/lib/xwaop.h>
16#include <xwos/lib/bclst.h>
17#include <xwos/lib/lfq.h>
19#include <xwos/mm/common.h>
22
23/* #define XWMM_MEMPOOLLOGF */
24#ifdef XWMM_MEMPOOLLOGF
25# define xwmm_mempoollogf(lv, thd, fmt, ...) \
26 xwlogf(lv, "Thd:%s", fmt, thd->stack.name, ##__VA_ARGS__)
27#else
28# define xwmm_mempoollogf(lv, thd, fmt, ...)
29#endif
30
31static __xwos_code
33 struct xwmm_mempool_page * pg);
34
35static __xwos_code
37 xwsz_t nr);
38
39static __xwos_code
41 struct xwmm_mempool_page * pg);
42
43static __xwos_code
45 struct xwmm_mempool_page ** pgbuf);
46
47static __xwos_code
48xwer_t xwmm_mempool_objcache_i_a_malloc(void * this, xwsz_t size, void ** membuf);
49
50static __xwos_code
51xwer_t xwmm_mempool_objcache_i_a_free(void * this, void * mem);
52
56 const char * name,
57 xwsz_t objsize, xwsz_t alignment, xwsq_t pg_order,
58 ctor_f ctor, dtor_f dtor)
59{
60 xwsz_t nr;
61 xwsz_t pgsize;
62
63/*
64 * ----------------------------
65 * | struct xwmm_mempool_page |
66 * -----------------------------------------------------------------------------
67 * | attr.objcache.objhead |->| obj | a | obj | a | obj | a | ...
68 * |--------------------------|-------------------------------------------------
69 * | ... | | ^ | ^ | ^
70 * |--------------------------| |___| |___| |___|
71 * obj: object
72 * a: alignment area
73 */
74
75 alignment = XWBOP_ALIGN(alignment, (xwsz_t)XWMM_ALIGNMENT);
76 objsize = XWBOP_ALIGN(objsize, (xwsz_t)alignment);
77 if (NULL != ctor) {
78 xwu8_t obj[objsize];
79 ctor((void *)obj);
80 oc->backup = *((xwptr_t *)obj);
81 } else {
82 oc->backup = 0;
83 }
84
85 pgsize = pa->pgsize << pg_order;
86 nr = pgsize / objsize;
87
88 oc->name = name;
89 oc->pa = pa;
90 oc->objsize = objsize;
91 oc->alignment = alignment;
92 oc->pg_order = pg_order;
93 oc->pg_objnr = nr;
94 oc->ctor = ctor;
95 oc->dtor = dtor;
96 oc->capacity = 0;
97 oc->idleness = 0;
98 oc->reserved = 0;
105
106 return XWOK;
107}
108
114static __xwos_code
116 struct xwmm_mempool_page * pg)
117{
118 xwsz_t i;
119 xwsz_t loop;
120 xwptr_t curr;
121 xwptr_t next;
122
124 pg->attr.objcache.refcnt = 0;
125 pg->data.value = oc->objsize;
126
127 /* 构造所有对象 */
128 if (NULL != oc->ctor) {
129 curr = pg->mapping;
130 next = curr;
131 loop = oc->pg_objnr;
132 for (i = 0; i < loop; i++) {
133 next += oc->objsize;
134 oc->ctor((void *)curr);
135 curr = next;
136 }
137 }
138
139 /* 初始化无锁队列 */
141 curr = pg->mapping;
142 next = curr;
143 loop = oc->pg_objnr;
144 for (i = 0; i < loop; i++) {
145 next += oc->objsize;
148 (atomic_xwlfq_t *)curr);
149 curr = next;
150 }
151}
152
159static __xwos_code
161 xwsz_t nr)
162{
163 struct xwmm_mempool_page * pg;
164 xwreg_t flag;
165 xwsz_t real;
166
167 real = 0;
168 while (real < nr) {
172 break;
173 }
175 struct xwmm_mempool_page,
176 attr.objcache.node);
179 // cppcheck-suppress [misra-c2012-17.7]
180 xwmm_mempool_page_free(oc->pa, pg);
183 real++;
184 }
185 return real;
186}
187
196static __xwos_code
198 struct xwmm_mempool_page * pg)
199{
200 xwreg_t flag;
201
204 pg->attr.objcache.refcnt--;
206 if ((xwsq_t)0 == pg->attr.objcache.refcnt) {
208 &pg->attr.objcache.node);
209 } else {
211 &pg->attr.objcache.node);
212 }
214}
215
224static __xwos_code
226 struct xwmm_mempool_page ** pgbuf)
227{
228 struct xwmm_mempool_page * pg;
229 xwreg_t flag;
230 xwer_t rc;
231
235 struct xwmm_mempool_page,
236 attr.objcache.node);
239 } else if (!xwlib_bclst_tst_empty(&oc->page_list.idle)) {
241 struct xwmm_mempool_page,
242 attr.objcache.node);
245 } else {
247 rc = xwmm_mempool_page_allocate(oc->pa, oc->pg_order, &pg);
248 if (rc < 0) {
249 goto err_pg_alloc;
250 }
254 }
255 *pgbuf = pg;
256 return XWOK;
257
258err_pg_alloc:
259 return rc;
260}
261
264{
265 struct xwmm_mempool_page * pg;
266 xwlfq_t * obj;
267 xwreg_t flag;
268 xwer_t rc;
269
270 rc = xwmm_mempool_objcache_page_get(oc, &pg);
271 if (rc < 0) {
272 goto err_page_get;
273 }
274
275 xwaop_sub(xwsz_t, &oc->idleness, 1, NULL, NULL);
277 XWOS_BUG_ON(NULL == obj);
278 *obj = oc->backup;
279 *objbuf = (void *)obj;
280
283 pg->attr.objcache.refcnt++;
285 if (pg->attr.objcache.refcnt == oc->pg_objnr) {
287 } else {
289 }
291
292 return XWOK;
293
294err_page_get:
295 return rc;
296}
297
300{
301 atomic_xwlfq_t * lfq;
302 struct xwmm_mempool_page * pg;
303 xwsz_t reserved;
304 xwsz_t idleness;
305 xwptr_t offset;
306 xwptr_t origin;
307 xwer_t rc;
308
309 rc = xwmm_mempool_page_find(oc->pa, obj, &pg);
310 if (rc < 0) {
311 goto err_pg_find;
312 }
313
314 offset = ((xwptr_t)obj - pg->mapping) % oc->objsize;
315 origin = (xwptr_t)obj - offset;
316 obj = (void *)origin;
317
318 if (NULL != oc->dtor) {
319 oc->dtor(obj);
320 }
321
322 lfq = (atomic_xwlfq_t *)obj;
324
326 xwaop_add(xwsz_t, &oc->idleness, 1, &idleness, NULL);
327 reserved = xwaop_load(xwsz_t, &oc->reserved, xwaop_mo_relaxed);
328
329 if ((reserved + oc->pg_objnr) <= idleness) {
330 xwsz_t nr;
331
332 nr = (idleness - reserved) / oc->pg_objnr;
333 // cppcheck-suppress [misra-c2012-17.7]
335 }
336
337 return XWOK;
338
339err_pg_find:
340 return rc;
341}
342
345 xwsz_t reserved)
346{
347 struct xwmm_mempool_page * pg;
348 xwsz_t capacity;
349 xwsz_t idleness;
350 xwreg_t flag;
351 xwer_t rc;
352
353 reserved = XWBOP_DIV_ROUND_UP(reserved, oc->pg_objnr);
354 xwaop_write(xwsz_t, &oc->reserved, reserved, NULL);
355 capacity = xwaop_load(xwsz_t, &oc->capacity, xwaop_mo_relaxed);
356 idleness = xwaop_load(xwsz_t, &oc->idleness, xwaop_mo_relaxed);
357 if (capacity < reserved) {
358 rc = xwmm_mempool_page_allocate(oc->pa, oc->pg_order, &pg);
359 if (rc < 0) {
360 goto err_pg_alloc;
361 }
368 } else if ((reserved + oc->pg_objnr) < idleness) {
369 xwsz_t nr;
370
371 nr = (idleness - reserved) / oc->pg_objnr;
372 // cppcheck-suppress [misra-c2012-17.7]
374 } else {
375 }
376 return XWOK;
377
378err_pg_alloc:
379 return rc;
380}
381
384 xwsz_t * capacity)
385{
386 *capacity = xwaop_load(xwsz_t, &oc->capacity, xwaop_mo_relaxed);
387 return XWOK;
388}
389
399static __xwos_code
400xwer_t xwmm_mempool_objcache_i_a_malloc(void * this, xwsz_t size, void ** membuf)
401{
402 struct xwmm_mempool_objcache * oc;
403 xwer_t rc;
404
405 oc = this;
406 if (size > oc->objsize) {
407 rc = -ESIZE;
408 goto err_size;
409 }
410 rc = xwmm_mempool_objcache_alloc(oc, membuf);
411 if (rc < 0) {
412 goto err_alloc;
413 }
414 return XWOK;
415
416err_alloc:
417err_size:
418 return rc;
419}
420
429static __xwos_code
431{
432 struct xwmm_mempool_objcache * oc;
433 xwer_t rc;
434
435 oc = this;
436 rc = xwmm_mempool_objcache_free(oc, mem);
437 return rc;
438}
XWOS通用库:双循环链表
#define XWMM_ALIGNMENT
Definition common.h:29
xwer_t xwmm_mempool_objcache_init(struct xwmm_mempool_objcache *oc, struct xwmm_mempool_page_allocator *pa, const char *name, xwsz_t objsize, xwsz_t alignment, xwsq_t pg_order, ctor_f ctor, dtor_f dtor)
XWMM API:初始化对象缓存
Definition objcache.c:54
xwer_t xwmm_mempool_page_free(struct xwmm_mempool_page_allocator *pa, struct xwmm_mempool_page *pg)
XWMM API:释放一页内存
Definition page.c:194
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
xwer_t xwmm_mempool_objcache_alloc(struct xwmm_mempool_objcache *oc, void **objbuf)
XWMM API:从对象缓存中申请一个对象
Definition objcache.c:263
xwer_t xwmm_mempool_objcache_reserve(struct xwmm_mempool_objcache *oc, xwsz_t reserved)
XWMM API:预留对象到对象缓存中
Definition objcache.c:344
xwer_t xwmm_mempool_objcache_get_capacity(struct xwmm_mempool_objcache *oc, xwsz_t *capacity)
XWMM API:获取对象缓存的容量
Definition objcache.c:383
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_objcache_free(struct xwmm_mempool_objcache *oc, void *obj)
XWMM API:释放对象到对象缓存中
Definition objcache.c:299
static void xwlib_bclst_init_head(struct xwlib_bclst_node *h)
初始化一个链表头。
Definition bclst.h:229
static void xwlib_bclst_add_tail(struct xwlib_bclst_node *head, struct xwlib_bclst_node *newn)
将一个节点加入链表尾部(链表头的前面)
Definition bclst.h:357
static void xwlib_bclst_init_node(struct xwlib_bclst_node *n)
初始化一个链表节点。
Definition bclst.h:240
static bool xwlib_bclst_tst_empty(const struct xwlib_bclst_node *h)
测试链表是否为空。
Definition bclst.h:253
static void xwlib_bclst_add_head(struct xwlib_bclst_node *head, struct xwlib_bclst_node *newn)
将一个节点加入链表头部(链表头的后面)
Definition bclst.h:345
static void xwlib_bclst_del_init(struct xwlib_bclst_node *node)
删除一个节点,并重新初始化它
Definition bclst.h:391
#define xwlib_bclst_last_entry(head, type, member)
获得包含链表最后一个节点的外层结构体的指针。
Definition bclst.h:73
#define xwlib_bclst_first_entry(head, type, member)
获得包含链表第一个节点的外层结构体的指针。
Definition bclst.h:63
#define __xwos_code
Definition compiler.h:171
#define __xwos_api
Definition compiler.h:175
#define XWOK
No error
Definition errno.h:182
#define ESIZE
Size error
Definition errno.h:199
static void xwlib_lfq_push(atomic_xwlfq_t *h, atomic_xwlfq_t *n)
将一个节点推入无锁队列(栈式队列)
Definition lfq.h:42
static void xwlib_lfq_init(atomic_xwlfq_t *n)
初始化无锁队列节点
Definition lfq.h:31
static xwlfq_t * xwlib_lfq_pop(atomic_xwlfq_t *h)
弹出无锁队列中的第一个节点(栈式队列)
Definition lfq.h:53
signed long xwer_t
Definition type.h:554
#define NULL
Definition type.h:28
__xwcc_atomic xwlfq_t atomic_xwlfq_t
Definition type.h:594
unsigned long xwsz_t
Definition type.h:339
uint8_t xwu8_t
Definition type.h:194
unsigned long xwsq_t
Definition type.h:445
xwptr_t xwlfq_t
Definition type.h:591
unsigned long xwptr_t
Definition type.h:375
xwptr_t xwreg_t
Definition type.h:409
void(* ctor_f)(void *)
Definition type.h:604
void(* dtor_f)(void *)
Definition type.h:605
@ xwaop_mo_relaxed
Definition type.h:628
#define xwaop_load(type, a, memorder)
对原子变量进行原子操作:加载
Definition xwaop.h:45
#define xwaop_write(type, a, v, ov)
对原子变量进行原子操作:读取—写
Definition xwaop.h:91
#define xwaop_add(type, a, v, nv, ov)
对原子变量进行原子操作:读取-相加-回写
Definition xwaop.h:330
#define xwaop_sub(type, a, v, nv, ov)
对原子变量进行原子操作:读取-相减-回写
Definition xwaop.h:598
#define XWBOP_DIV_ROUND_UP(n, d)
Definition xwbop.h:31
#define XWBOP_ALIGN(x, n)
Definition xwbop.h:37
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_ON(x)
Definition standard.h:57
XWOS通用库:无锁队列
操作系统抽象层:顺序锁
static xwsz_t xwmm_mempool_objcache_free_idle_page(struct xwmm_mempool_objcache *oc, xwsz_t nr)
释放空闲页
Definition objcache.c:160
static xwer_t xwmm_mempool_objcache_page_get(struct xwmm_mempool_objcache *oc, struct xwmm_mempool_page **pgbuf)
获取一页,准备从页内存中分配对象
Definition objcache.c:225
static xwer_t xwmm_mempool_objcache_i_a_malloc(void *this, xwsz_t size, void **membuf)
i_allocator接口函数:申请内存
Definition objcache.c:400
static void xwmm_mempool_objcache_page_put(struct xwmm_mempool_objcache *oc, struct xwmm_mempool_page *pg)
减少页的引用计数
Definition objcache.c:197
static xwer_t xwmm_mempool_objcache_i_a_free(void *this, void *mem)
i_allocator接口函数:释放内存
Definition objcache.c:430
static void xwmm_mempool_objcache_page_init(struct xwmm_mempool_objcache *oc, struct xwmm_mempool_page *pg)
初始化新页
Definition objcache.c:115
XWOS内存管理:内存池:对象缓存
XWOS内存管理:内存池:页分配器
xwer_t(* free)(void *, void *)
Definition i_allocator.h:31
xwer_t(* malloc)(void *, xwsz_t, void **)
Definition i_allocator.h:29
对象缓存
Definition objcache.h:34
struct xwmm_mempool_page_allocator * pa
Definition objcache.h:36
struct xwlib_bclst_node full
Definition objcache.h:55
struct xwlib_bclst_node idle
Definition objcache.h:57
struct xwos_sqlk lock
Definition objcache.h:58
struct xwlib_bclst_node available
Definition objcache.h:56
struct xwmm_mempool_i_allocator i_a
Definition objcache.h:35
atomic_xwsz_t reserved
Definition objcache.h:52
atomic_xwsz_t idleness
Definition objcache.h:51
const char * name
Definition objcache.h:37
struct xwmm_mempool_objcache::@0 page_list
atomic_xwsz_t capacity
Definition objcache.h:50
内存页
Definition page.h:37
struct xwlib_bclst_node node
Definition page.h:51
xwsq_t value
Definition page.h:61
union xwmm_mempool_page::@1 attr
xwptr_t mapping
Definition page.h:40
union xwmm_mempool_page::@2 data
xwsq_t refcnt
Definition page.h:53
atomic_xwlfq_t objhead
Definition page.h:52
struct xwmm_mempool_page::@1::@4 objcache
XWOS通用库:原子操作
XWOS通用库:位操作
XWOS内存管理:通用定义
XWOS的标准头文件