mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
memory manager support multi blocks of memory
This commit is contained in:
parent
25e05644cf
commit
bec68c3713
@ -93,7 +93,10 @@ COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_EVENT_RECORDER_PLAYER=1 '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_ASSET_LOADER -DWITH_FS_RES -DWITH_ASSET_LOADER_ZIP '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DSTBTT_STATIC -DSTB_IMAGE_STATIC -DWITH_STB_IMAGE '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_VGCANVAS -DWITH_UNICODE_BREAK -DWITH_DESKTOP_STYLE '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DHAS_STD_MALLOC -DWITH_SDL -DHAS_STDIO -DHAVE_STDIO_H -DHAS_GET_TIME_US64 '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DWITH_SDL -DHAS_STDIO -DHAVE_STDIO_H -DHAS_GET_TIME_US64 '
|
||||
COMMON_CCFLAGS=COMMON_CCFLAGS+' -DHAS_STD_MALLOC -DTK_MAX_MEM_BLOCK_NR=3 '
|
||||
|
||||
#COMMON_CCFLAGS=COMMON_CCFLAGS+' -DTK_MAX_MEM_BLOCK_NR=3 '
|
||||
|
||||
GRAPHIC_BUFFER='default'
|
||||
|
||||
|
@ -87,6 +87,7 @@
|
||||
* [如何使用 packed 图](how_to_use_packed_image.md)
|
||||
* [如何根据实际分辨率自动调整窗口中子控件的位置大小](how_to_auto_scale_children.md)
|
||||
* [如何修改 stb\_truetype 获取字模时申请的缓冲区大小](how_to_modify_stb_truetype_buffer_size.md)
|
||||
* [如何让内存管理器支持管理多块不连续的内存](how_to_support_multi_mem_block.md)
|
||||
|
||||
### 3. 内部原理
|
||||
* [AWTK 脚本绑定原理](script_binding.md)
|
||||
|
@ -1,5 +1,9 @@
|
||||
# 最新动态
|
||||
|
||||
2021/04/22
|
||||
* 修改内存泄漏问题。
|
||||
* 内存管理器支持管理多块不连续的内存。
|
||||
|
||||
2021/04/20
|
||||
* 完善progress cirle demo(感谢雨欣提供补丁)
|
||||
* 添加 获取光标位置 接口(感谢兆坤提供补丁)
|
||||
|
41
docs/how_to_support_multi_mem_block.md
Normal file
41
docs/how_to_support_multi_mem_block.md
Normal file
@ -0,0 +1,41 @@
|
||||
# AWTK 内存分配器支持多块不连续的内存。
|
||||
|
||||
在嵌入式系统中,可能有多块不连续的内存。AWTK 最新版本支持管理多个不连续的内存块。使用方法如下:
|
||||
|
||||
* 定义内存块数目
|
||||
|
||||
> 在 awtk\_config.h 中定义:
|
||||
|
||||
```c
|
||||
#define TK_MAX_MEM_BLOCK_NR 3
|
||||
```
|
||||
|
||||
* 初始化内存
|
||||
|
||||
> 需要使用 tk\_mem\_init\_ex 代替 tk\_mem\_init 初始化内存。一般将大块放到前面,小块放到后面。也可以将速度快的内存放到前面,将速度慢的放到后面。
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method tk_mem_init_ex
|
||||
* @export none
|
||||
* 初始化内存,支持多块不连续的内存。
|
||||
* >最后一个参数必须为NULL。
|
||||
*
|
||||
* 示例:
|
||||
* ```c
|
||||
* tk_mem_init_ex(mem1, sizeof(mem1), mem2, sizeof(mem2), mem3, sizeof(mem3), NULL);
|
||||
* ```
|
||||
*
|
||||
* @param {void*} buffer 内存地址。
|
||||
* @param {uint32_t} size 内存长度。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_mem_init_ex(void* buffer, uint32_t size, ...);
|
||||
|
||||
```
|
||||
|
||||
示例:
|
||||
```c
|
||||
tk_mem_init_ex(mem1, sizeof(mem1), mem2, sizeof(mem2), mem3, sizeof(mem3), NULL);
|
||||
```
|
@ -235,4 +235,10 @@
|
||||
* #define WITH_LCD_CLEAR_ALPHA 1
|
||||
*/
|
||||
|
||||
/**
|
||||
* 如果支持多块不连续的内存块,请定义内存块的数目。
|
||||
*
|
||||
* #define TK_MAX_MEM_BLOCK_NR 4
|
||||
*/
|
||||
|
||||
#endif /*AWTK_CONFIG_H*/
|
||||
|
@ -193,15 +193,14 @@ void sleep_ms(uint32_t ms) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAS_STD_MALLOC
|
||||
static uint32_t s_heap_mem[3 * 1024 * 1024];
|
||||
#endif /*HAS_STD_MALLOC*/
|
||||
|
||||
ret_t platform_prepare(void) {
|
||||
stm_time_init();
|
||||
|
||||
#ifndef HAS_STD_MALLOC
|
||||
tk_mem_init(s_heap_mem, sizeof(s_heap_mem));
|
||||
static uint32_t s_heap_mem1[10 * 1024];
|
||||
static uint32_t s_heap_mem2[1 * 1024 * 1024];
|
||||
static uint32_t s_heap_mem3[3 * 1024 * 1024];
|
||||
tk_mem_init_ex(s_heap_mem1, sizeof(s_heap_mem1), s_heap_mem2, sizeof(s_heap_mem2), s_heap_mem3, sizeof(s_heap_mem3),NULL);
|
||||
#endif /*HAS_STD_MALLOC*/
|
||||
|
||||
date_time_global_init_ex(&s_date_time_vtable);
|
||||
|
@ -19,6 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/time_now.h"
|
||||
#include "tkc/mem_allocator_oom.h"
|
||||
@ -69,28 +70,25 @@ ret_t tk_mem_init_stage2(void) {
|
||||
|
||||
#else /*non std memory manager*/
|
||||
#include "tkc/mem_allocator_lock.h"
|
||||
#include "tkc/mem_allocator_simple.h"
|
||||
#include "tkc/mem_allocator_composite.h"
|
||||
|
||||
static mem_allocator_lock_t s_lock;
|
||||
|
||||
static void* s_heap_start = NULL;
|
||||
static uint32_t s_heap_size = 0;
|
||||
static mem_allocator_pool_t pool;
|
||||
static mem_allocator_composite_t composite;
|
||||
|
||||
bool_t tk_mem_is_valid_addr(void* addr) {
|
||||
uint64_t start = (uint64_t)s_heap_start;
|
||||
uint64_t end = start + s_heap_size;
|
||||
|
||||
return (((uint64_t)addr >= (uint64_t)start) && ((uint64_t)addr < end));
|
||||
return mem_allocator_composite_is_valid_addr(MEM_ALLOCATOR(&composite), addr);
|
||||
}
|
||||
|
||||
ret_t tk_mem_init(void* buffer, uint32_t size) {
|
||||
static mem_allocator_simple_t simple;
|
||||
static mem_allocator_pool_t pool;
|
||||
ret_t tk_mem_init_ex(void* buffer, uint32_t size, ...) {
|
||||
va_list va;
|
||||
va_start(va, size);
|
||||
s_allocator = mem_allocator_composite_init_va(&composite, buffer, size, va);
|
||||
va_end(va);
|
||||
|
||||
s_heap_size = size;
|
||||
s_heap_start = buffer;
|
||||
return_value_if_fail(s_allocator != NULL, RET_BAD_PARAMS);
|
||||
|
||||
s_allocator = mem_allocator_simple_init(&simple, buffer, size);
|
||||
if (size < 100 * 1024) {
|
||||
s_allocator = mem_allocator_pool_init(&pool, s_allocator, 100, 100, 80, 80, 32);
|
||||
} else if (size < 1000 * 1024) {
|
||||
@ -105,6 +103,10 @@ ret_t tk_mem_init(void* buffer, uint32_t size) {
|
||||
return s_allocator != NULL ? RET_OK : RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t tk_mem_init(void* buffer, uint32_t size) {
|
||||
return tk_mem_init_ex(buffer, size, NULL, 0);
|
||||
}
|
||||
|
||||
ret_t tk_mem_init_stage2(void) {
|
||||
return_value_if_fail(s_allocator != NULL, RET_FAIL);
|
||||
s_allocator = mem_allocator_lock_init(&s_lock, s_allocator);
|
||||
|
@ -140,6 +140,24 @@ void tk_mem_dump(void);
|
||||
*/
|
||||
ret_t tk_mem_init(void* buffer, uint32_t size);
|
||||
|
||||
/**
|
||||
* @method tk_mem_init_ex
|
||||
* @export none
|
||||
* 初始化内存,支持多块不连续的内存。
|
||||
* >最后一个参数必须为NULL。
|
||||
*
|
||||
* 示例:
|
||||
* ```c
|
||||
* tk_mem_init_ex(mem1, sizeof(mem1), mem2, sizeof(mem2), mem3, sizeof(mem3), NULL);
|
||||
* ```
|
||||
*
|
||||
* @param {void*} buffer 内存地址。
|
||||
* @param {uint32_t} size 内存长度。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_mem_init_ex(void* buffer, uint32_t size, ...);
|
||||
|
||||
/**
|
||||
* @method tk_mem_init_stage2
|
||||
* @export none
|
||||
|
226
src/tkc/mem_allocator_composite.h
Normal file
226
src/tkc/mem_allocator_composite.h
Normal file
@ -0,0 +1,226 @@
|
||||
/**
|
||||
* File: mem_allocator_composite.h
|
||||
* Author: AWTK Develop Team
|
||||
* Brief: mem_allocator_composite
|
||||
*
|
||||
* Copyright (c) 2020 - 2021 Guangzhou ZHIYUAN Electronics Co.,Ltd.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2021-04-22 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TK_MEM_ALLOCATOR_COMPOSITE_H
|
||||
#define TK_MEM_ALLOCATOR_COMPOSITE_H
|
||||
|
||||
#include "tkc/mutex.h"
|
||||
#include "tkc/mem_allocator_simple.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/*最多支持的内存块数目*/
|
||||
#ifndef TK_MAX_MEM_BLOCK_NR
|
||||
#define TK_MAX_MEM_BLOCK_NR 1
|
||||
#endif /*TK_MAX_MEM_BLOCK_NR*/
|
||||
|
||||
/**
|
||||
* @class mem_allocator_composite_t
|
||||
* @parent mem_allocator_t
|
||||
*
|
||||
* 支持多个不连续的内存块。
|
||||
*
|
||||
*/
|
||||
typedef struct _mem_allocator_composite_t {
|
||||
mem_allocator_t allocator;
|
||||
mem_allocator_simple_t allocators[TK_MAX_MEM_BLOCK_NR];
|
||||
} mem_allocator_composite_t;
|
||||
|
||||
#define MEM_ALLOCATOR_COMPOSITE(allocator) ((mem_allocator_composite_t*)(allocator))
|
||||
|
||||
static inline void* mem_allocator_composite_alloc(mem_allocator_t* allocator, uint32_t size,
|
||||
const char* func, uint32_t line) {
|
||||
uint32_t i = 0;
|
||||
void* addr = NULL;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_is_valid(iter)) {
|
||||
addr = mem_allocator_alloc(iter, size, func, line);
|
||||
if (addr != NULL) {
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool_t mem_allocator_composite_is_valid_addr(mem_allocator_t* allocator, void* ptr) {
|
||||
uint32_t i = 0;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_contains(iter, ptr)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static inline void mem_allocator_composite_free(mem_allocator_t* allocator, void* ptr) {
|
||||
uint32_t i = 0;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_contains(iter, ptr)) {
|
||||
mem_allocator_free(iter, ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static inline void* mem_allocator_composite_realloc(mem_allocator_t* allocator, void* ptr,
|
||||
uint32_t size, const char* func,
|
||||
uint32_t line) {
|
||||
uint32_t i = 0;
|
||||
void* addr = NULL;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
if (ptr == NULL) {
|
||||
return mem_allocator_composite_alloc(allocator, size, func, line);
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_contains(iter, ptr)) {
|
||||
addr = mem_allocator_realloc(iter, ptr, size, func, line);
|
||||
if (addr == NULL) {
|
||||
uint32_t old_size = mem_allocator_simple_get_mem_size(iter, ptr);
|
||||
addr = mem_allocator_composite_alloc(allocator, size, func, line);
|
||||
if (addr != NULL) {
|
||||
uint32_t data_size = tk_min(old_size, size);
|
||||
memcpy(addr, ptr, data_size);
|
||||
mem_allocator_simple_free(iter, ptr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
static inline ret_t mem_allocator_composite_dump(mem_allocator_t* allocator) {
|
||||
uint32_t i = 0;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_is_valid(iter)) {
|
||||
mem_allocator_dump(iter);
|
||||
}
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static inline ret_t mem_allocator_composite_destroy(mem_allocator_t* allocator) {
|
||||
uint32_t i = 0;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (mem_allocator_simple_is_valid(iter)) {
|
||||
mem_allocator_destroy(iter);
|
||||
}
|
||||
}
|
||||
allocator->vt = NULL;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static const mem_allocator_vtable_t s_mem_allocator_composite_vtable = {
|
||||
.alloc = mem_allocator_composite_alloc,
|
||||
.realloc = mem_allocator_composite_realloc,
|
||||
.free = mem_allocator_composite_free,
|
||||
.dump = mem_allocator_composite_dump,
|
||||
.destroy = mem_allocator_composite_destroy};
|
||||
|
||||
static inline ret_t mem_allocator_composite_add_mem(mem_allocator_t* allocator, char* addr,
|
||||
uint32_t size) {
|
||||
uint32_t i = 0;
|
||||
mem_allocator_composite_t* impl = MEM_ALLOCATOR_COMPOSITE(allocator);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(impl->allocators); i++) {
|
||||
mem_allocator_t* iter = MEM_ALLOCATOR(impl->allocators + i);
|
||||
|
||||
if (!mem_allocator_simple_is_valid(iter)) {
|
||||
mem_allocator_simple_init(MEM_ALLOCATOR_SIMPLE(iter), addr, size);
|
||||
log_debug("add mem block %p %u\n", addr, size);
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
|
||||
log_warn("no space to add mem, please increase TK_MAX_MEM_BLOCK_NR\n");
|
||||
|
||||
return RET_BAD_PARAMS;
|
||||
}
|
||||
|
||||
static inline mem_allocator_t* mem_allocator_composite_init_va(mem_allocator_composite_t* composite,
|
||||
void* buffer, uint32_t size,
|
||||
va_list va) {
|
||||
char* p = NULL;
|
||||
mem_allocator_t* allocator = MEM_ALLOCATOR(composite);
|
||||
return_value_if_fail(composite != NULL, NULL);
|
||||
|
||||
memset(composite, 0x00, sizeof(*composite));
|
||||
allocator->vt = &s_mem_allocator_composite_vtable;
|
||||
|
||||
ENSURE(mem_allocator_composite_add_mem(allocator, buffer, size) == RET_OK);
|
||||
do {
|
||||
p = va_arg(va, char*);
|
||||
if (p != NULL) {
|
||||
uint32_t s = va_arg(va, uint32_t);
|
||||
ENSURE(mem_allocator_composite_add_mem(allocator, p, s) == RET_OK);
|
||||
}
|
||||
} while (p != NULL);
|
||||
|
||||
return allocator;
|
||||
}
|
||||
|
||||
static inline mem_allocator_t* mem_allocator_composite_init(mem_allocator_composite_t* composite,
|
||||
void* buffer, uint32_t size, ...) {
|
||||
va_list va;
|
||||
mem_allocator_t* ret = NULL;
|
||||
|
||||
va_start(va, size);
|
||||
ret = mem_allocator_composite_init_va(composite, buffer, size, va);
|
||||
va_end(va);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif /*TK_MEM_ALLOCATOR_COMPOSITE_H*/
|
@ -74,11 +74,9 @@ static void* tk_alloc_impl(mem_allocator_t* allocator, uint32_t s) {
|
||||
}
|
||||
|
||||
if (iter == NULL) {
|
||||
log_debug("%s: Out of memory(%d):\n", __FUNCTION__, (int)size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return_value_if_fail(iter != NULL, NULL);
|
||||
|
||||
/*如果找到的空闲块刚好满足需求,就从空闲块链表中移出它*/
|
||||
if (iter->size < (size + MIN_SIZE)) {
|
||||
if (info->free_list == iter) {
|
||||
@ -262,6 +260,19 @@ static inline void mem_allocator_simple_free(mem_allocator_t* allocator, void* p
|
||||
tk_free_impl(allocator, ptr);
|
||||
}
|
||||
|
||||
static inline bool_t mem_allocator_simple_is_valid(mem_allocator_t* allocator) {
|
||||
mem_info_t* info = &(MEM_ALLOCATOR_SIMPLE(allocator)->info);
|
||||
|
||||
return info->buffer != NULL && info->size > 0;
|
||||
}
|
||||
|
||||
static inline bool_t mem_allocator_simple_contains(mem_allocator_t* allocator, void* ptr) {
|
||||
char* p = (char*)ptr;
|
||||
mem_info_t* info = &(MEM_ALLOCATOR_SIMPLE(allocator)->info);
|
||||
|
||||
return (p >= info->buffer && (p - info->buffer) < info->size);
|
||||
}
|
||||
|
||||
static inline ret_t mem_allocator_simple_dump(mem_allocator_t* allocator) {
|
||||
mem_info_t* info = &(MEM_ALLOCATOR_SIMPLE(allocator)->info);
|
||||
log_debug("used: %u(max=%u) bytes %u(max=%u) blocks\n", info->used_bytes, info->used_max_bytes,
|
||||
@ -271,6 +282,16 @@ static inline ret_t mem_allocator_simple_dump(mem_allocator_t* allocator) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static uint32_t mem_allocator_simple_get_mem_size(mem_allocator_t* allocator, void* ptr) {
|
||||
free_node_t* free_iter = NULL;
|
||||
return_value_if_fail(ptr != NULL, 0);
|
||||
|
||||
free_iter = (free_node_t*)((char*)ptr - sizeof(uint32_t));
|
||||
|
||||
return free_iter->size;
|
||||
}
|
||||
|
||||
|
||||
static inline ret_t mem_allocator_simple_destroy(mem_allocator_t* allocator) {
|
||||
allocator->vt = NULL;
|
||||
return RET_OK;
|
||||
|
@ -29,7 +29,6 @@ SOURCES = [
|
||||
] + Glob('*.cc') + Glob('*.c')
|
||||
|
||||
env.Program(os.path.join(BIN_DIR, 'runTest'), SOURCES);
|
||||
#env.Program(os.path.join(BIN_DIR, 'mem_test'), ["mem_test.cpp"])
|
||||
env.Program(os.path.join(BIN_DIR, 'recycle_test'), ["recycle_test.cpp"])
|
||||
env.Program(os.path.join(BIN_DIR, 'waitable_action_queue_test'), ["waitable_action_queue_test.cpp"])
|
||||
env.Program(os.path.join(BIN_DIR, 'waitable_ring_buffer_test'), ["waitable_ring_buffer_test.cpp"])
|
||||
|
@ -1,15 +1,13 @@
|
||||
#include "tkc/mem_allocator_pool.h"
|
||||
#include "tkc/mem.h"
|
||||
#include "tkc/mem_allocator_pool.h"
|
||||
#include "tkc/mem_allocator_simple.h"
|
||||
|
||||
void allocator_test_basic() {
|
||||
#include "tkc/mem_allocator_composite.h"
|
||||
|
||||
void allocator_test_basic_ex(mem_allocator_t* allocator) {
|
||||
uint32_t i = 0;
|
||||
char buff[102400];
|
||||
void* addr = NULL;
|
||||
void* addrs[100];
|
||||
mem_allocator_simple_t simple;
|
||||
mem_allocator_pool_t pool;
|
||||
mem_allocator_t* allocator = mem_allocator_simple_init(&simple, buff, sizeof(buff));
|
||||
allocator = mem_allocator_pool_init(&pool, allocator, 10, 10, 10, 10, 10);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(addrs); i++) {
|
||||
addr = mem_allocator_alloc(allocator, i + 1, __FUNCTION__, __LINE__);
|
||||
@ -25,21 +23,31 @@ void allocator_test_basic() {
|
||||
mem_allocator_free(allocator, addrs[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void allocator_test_basic() {
|
||||
uint32_t i = 0;
|
||||
char buff[102400];
|
||||
mem_allocator_simple_t simple;
|
||||
mem_allocator_t* allocator = mem_allocator_simple_init(&simple, buff, sizeof(buff));
|
||||
mem_allocator_pool_t pool;
|
||||
allocator = mem_allocator_pool_init(&pool, allocator, 10, 10, 10, 10, 10);
|
||||
|
||||
allocator_test_basic_ex(allocator);
|
||||
|
||||
for (i = 0; i < TK_MEM_POOLS_NR; i++) {
|
||||
assert(pool.pools[i]->used == 0);
|
||||
}
|
||||
mem_allocator_destroy(allocator);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void allocator_test_rand() {
|
||||
void allocator_test_rand_ex(mem_allocator_t* allocator) {
|
||||
uint32_t k = 0;
|
||||
uint32_t i = 0;
|
||||
char buff[1000 * 1000];
|
||||
void* addr = NULL;
|
||||
void* addrs[1000];
|
||||
mem_allocator_simple_t simple;
|
||||
mem_allocator_pool_t pool;
|
||||
mem_allocator_t* allocator = mem_allocator_simple_init(&simple, buff, sizeof(buff));
|
||||
allocator = mem_allocator_pool_init(&pool, allocator, 10, 10, 10, 10, 10);
|
||||
|
||||
for (k = 0; k < 1000; k++) {
|
||||
for (i = 0; i < ARRAY_SIZE(addrs); i++) {
|
||||
@ -57,12 +65,101 @@ void allocator_test_rand() {
|
||||
mem_allocator_free(allocator, addrs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void allocator_test_rand() {
|
||||
uint32_t i = 0;
|
||||
char buff[1000 * 1000];
|
||||
mem_allocator_simple_t simple;
|
||||
mem_allocator_t* allocator = mem_allocator_simple_init(&simple, buff, sizeof(buff));
|
||||
mem_allocator_pool_t pool;
|
||||
|
||||
allocator = mem_allocator_pool_init(&pool, allocator, 10, 10, 10, 10, 10);
|
||||
|
||||
allocator_test_rand_ex(allocator);
|
||||
|
||||
for (i = 0; i < TK_MEM_POOLS_NR; i++) {
|
||||
assert(pool.pools[i]->used == 0);
|
||||
}
|
||||
mem_allocator_destroy(allocator);
|
||||
}
|
||||
|
||||
void allocator_test_composite0() {
|
||||
char mem1[100*1000];
|
||||
char mem2[1000*1000];
|
||||
char* addr = NULL;
|
||||
mem_allocator_composite_t composite;
|
||||
mem_allocator_t* allocator = mem_allocator_composite_init(&composite, mem1, sizeof(mem1), mem2, sizeof(mem2), NULL);
|
||||
|
||||
allocator_test_basic_ex(allocator);
|
||||
allocator_test_rand_ex(allocator);
|
||||
mem_allocator_destroy(allocator);
|
||||
}
|
||||
|
||||
void allocator_test_composite1() {
|
||||
char mem1[36];
|
||||
char mem2[64];
|
||||
char mem3[1280];
|
||||
char* addr = NULL;
|
||||
mem_allocator_composite_t composite;
|
||||
mem_allocator_t* allocator = mem_allocator_composite_init(&composite, mem1, sizeof(mem1), mem2, sizeof(mem2), mem3, sizeof(mem3), NULL);
|
||||
|
||||
/*mem1*/
|
||||
addr = mem_allocator_alloc(allocator, 16, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem1);
|
||||
assert(addr < (mem1 + sizeof(mem1)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
mem_allocator_free(allocator, addr);
|
||||
addr = mem_allocator_alloc(allocator, 16, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem1);
|
||||
assert(addr < (mem1 + sizeof(mem1)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
addr = mem_allocator_realloc(allocator, addr, 16+2, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem1);
|
||||
assert(addr < (mem1 + sizeof(mem1)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
/*mem2*/
|
||||
addr = mem_allocator_alloc(allocator, 36, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem2);
|
||||
assert(addr < (mem2 + sizeof(mem2)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
mem_allocator_free(allocator, addr);
|
||||
addr = mem_allocator_alloc(allocator, 36, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem2);
|
||||
assert(addr < (mem2 + sizeof(mem2)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
addr = mem_allocator_realloc(allocator, addr, 30, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem2);
|
||||
assert(addr < (mem2 + sizeof(mem2)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
/*mem3*/
|
||||
addr = mem_allocator_alloc(allocator, 66, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem3);
|
||||
assert(addr < (mem3 + sizeof(mem3)));
|
||||
|
||||
mem_allocator_free(allocator, addr);
|
||||
addr = mem_allocator_alloc(allocator, 66, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem3);
|
||||
assert(addr < (mem3 + sizeof(mem3)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
addr = mem_allocator_realloc(allocator, addr, 66+2, __FUNCTION__, __LINE__);
|
||||
assert(addr >= mem3);
|
||||
assert(addr < (mem3 + sizeof(mem3)));
|
||||
assert(mem_allocator_composite_is_valid_addr(allocator, addr));
|
||||
|
||||
mem_allocator_destroy(allocator);
|
||||
return;
|
||||
}
|
||||
|
||||
void allocator_test() {
|
||||
allocator_test_composite1();
|
||||
allocator_test_basic();
|
||||
allocator_test_rand();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user