Skip to content

Customizing a memory allocator

Wang Renxin edited this page Nov 19, 2017 · 3 revisions

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.

Clone this wiki locally