-
Notifications
You must be signed in to change notification settings - Fork 120
Customizing a memory allocator
Get started
The memory is limited on embedded systems which can run for years and cause a severe waste of memory due to fragmentation. Besides, it's efficient for MY-BASIC to customizing a memory allocator, even on systems, with a mass of memory. MY-BASIC provides an interface that let you do so.
An allocator need to be in form of:
typedef char* (* mb_memory_allocate_func_t)(unsigned s);
And a freer:
typedef void (* mb_memory_free_func_t)(char* p);
Then you can tell MY-BASIC to use them globally instead of standard malloc
and free
by calling:
MBAPI int mb_set_memory_manager(mb_memory_allocate_func_t a, mb_memory_free_func_t f);
Note the functors only affect allocation inside my_basic.c
, that is to say main.c
still uses the raw allocator.
Tutorial
There is already a simple memory pool implementation in main.c
. You need to make sure the _USE_MEM_POOL
macro is defined to enable the pool mechanism, and undefine it to disable it.
There are four functions in this implementation as a tutorial: _open_mem_pool
opens the pool when setting up an interpreter; _close_mem_pool
closes the pool when terminating; a pair of _pop_mem
and _push_mem
will be registered to MY-BASIC. Note _pop_mem
will call the standard malloc
if an expected size is not a common size in MY-BASIC; and it will take sizeof(union _pool_tag_t)
extra bytes to store meta data with each common size allocation. At the moment, this pool algorithm manages several types by pool: int
, intptr_t
, _ls_node_t
, _ht_node_t
, _object_t
, _func_t
, _array_t
, _var_t
, _label_t
, _routine_t
, _class_t
, and also some common sizes such as 32 bytes, 128 bytes, 512 bytes, etc. The allocator will lookup for a minimum pool which can allocate an expected size (may be a little larger) of memory to deal with, it will use the raw allocator if no pool met.
A typical workflow may looks like below:
_open_mem_pool(); /* Open it */
mb_set_memory_manager(_pop_mem, _push_mem); /* Set them */
{
mb_init();
mb_open(&bas);
/* Other deals with MY-BASIC */
mb_close(&bas);
mb_dispose();
}
_close_mem_pool(); /* Finished */
Strictly speaking, the tutorial pool doesn't guarantee to allocate continuous address memory, it is an object pool other than a memory pool, which pops a free chunk of memory with an expected size to user, and pushes it to the stack back when user frees it instead of freeing it to system. This could be a good start if you would like to implement your own memory pool algorithm optimized for a specific system.
- Principles
- Coding
- Data types
- Standalone shell
- Integration
- Customization
- More scripting API
- FAQ