Memory Allocation and RPL Usage

Introduction

This topic describes memory allocation (malloc) procedures and options available in the Cafe SDK. The MEM library is the memory management library provided by the Cafe SDK. It supports the following types of memory heaps:

For more information on the algorithm and APIs for each type of heap, see Memory Management.

Background

When calling any of the GHS malloc routines from an RPL, the usage causes a unique malloc heap to be created for that particular RPL. When more than one RPL calls malloc, each individual RPL has a unique malloc heap.

This scenario causes the following issues:

The following options are possible solutions to the above issues:

Creating a Single malloc Heap

There are two ways to use a single malloc heap:

  1. Create a single RPL containing ghs_malloc
  2. Export malloc from the RPX

Create a Single RPL Containing ghs_malloc

The ghs_malloc RPL should contain only an RPL entry function. This entry function should force the inclusion of memset and memcpy.

memset and memcpy are defined when malloc is pulled in:

int rpl_entry(void *p, int i)
{
    if (i == 0xcafedead) {
        /* force include of memset and memcpy, so they are defined when malloc is pulled in */
        memset(&malloc_force_include_memset, 0, sizeof(malloc_force_include_memset));
        memcpy(&malloc_force_include_memcpy, &malloc_force_include_memset, sizeof(malloc_force_include_memcpy));
    }
    return 0;
}

Then export the following GHS-defined symbols in the export definition file:

[CODE]
__malloc_info
calloc
free
malloc
realloc

[DATA]
__mallocInfo

Other Considerations

Export malloc from the RPX

In the RPX export definition file, export the following GHS defined symbols:

[CODE]
__malloc_info
calloc
free
malloc
realloc

[DATA]
__mallocInfo

Other Considerations

Override Default Heap Implementation

Cafe Core OS (COS) provides the implementation of malloc, free, realloc and calloc in cos_def_malloc.o to override the default GHS memory manager.

To use a user-defined version of these functions, build an object to link with the program but do not link with cos_def_malloc.o. When there is no user-defined version nor is cos_def_malloc.o linked, the default GHS libansi.a ccmalloc.o is linked.

Demos

By default, when calling malloc, calloc, realloc and free, the implementation in ccmalloc.o of libansi.a will be used. It creates a unique malloc heap for each individual RPL. The malloc heap will not be released even when the RPL is released. The following example shows how users can avoid this scenario.

A demonstration on how to create a single malloc heap, and replace the GHS default malloc, exists in the directory:

%CAFE_ROOT%\system\src\demo\examplemake\cafe_sdk\shared_malloc

The demo code demonstrates three cases:

  1. Global GHS malloc
  2. Local GHS malloc
  3. COS default malloc to override GHS malloc

In the file malloc_heap_helper.h, the macro USER_CALL_FREE_TO_RELEASE_HEAP controls if free is explicitly called. Toggle its value (1 or 0) to see how the malloc heap is allocated and released differently in each case.

Global GHS malloc

Local GHS malloc

COS Default malloc

-noar Option in preprpl[32|64]

When building ghs_malloc.rpl with preprpl[32|64], use the option -noar to indicate that no library header is generated for ghs_malloc.a. However, despite its extension of .a, its property is the same as an object with an extension of .o.

The reason for using -noar is that the GHS link editor treats the library and object differently when searching for references.

When the linker scans for the symbols in a library, it tracks only the symbols that were referenced by the files that have been scanned before. If the symbols in the library are referenced by the files that have not been scanned by the linker, the linker will not track it. For example, the linker scans the files in the following order:

ghs_malloc.a games.cpp libansi.a
Defines malloc Calls malloc Defines malloc

When ghs_malloc.a is built as a library, with the library header, its malloc definition is ignored by the linker because games.cpp is not yet scanned. There is no reference to malloc when ghs_malloc.a is scanned. Only when the linker scans games.cpp, does the linker start to track for malloc, and the definition it finds is in libansi.a which is scanned after games.cpp.

However, when ghs_malloc.a is built without a library header, which is now an object, GHS linker will include it in the final executable. Since object definition takes over library definition, the version in ghs_malloc.a (an object) is used instead of libansi.a.

See Also

Create an Application
Application Lifecycle
Basic Memory Allocation

Revision History

2014/03/25 Initial Creation.


CONFIDENTIAL