Allocating Memory
The following sections explain the easy way to allocate memory: by asking the kernel to do it. To learn how tasks can allocate their own memory from private memory lists, see Using Private Memory Lists.
Allocating a Memory Block
The normal way to allocate memory is with the AllocMem()
macro:
void *AllocMem( int32 s, uint32 t )
The s
argument specifies the size of the memory block to allocate, in bytes. The t
argument contains memory allocation flags that specify the type of memory to allocate. You can include optional flags in the t
argument that specify other characteristics of the block. The macro returns a pointer to the allocated block or NULL if the block couldn't be allocated.
Memory Block Flags
In the t
argument, you must include one of the following flags to specify the type of memory to allocate:
- MEMTYPE_ANY. Allocates any memory that is available.
- MEMTYPE_VRAM. Allocates only video random-access memory (VRAM).
- MEMTYPE_DRAM. Allocates only dynamic random-access memory (DRAM).
If a block of VRAM must come from a specific VRAM bank, you must include the following flag to specify that bank:
- MEMTYPE_BANKSELECT, Allocates VRAM from a specific VRAM bank.
You must also include one of the following two VRAM bank selection flags:
- MEMTYPE_BANK1. Allocates only memory from VRAM bank 1.
- MEMTYPE_BANK2. Allocates only memory from VRAM bank 2.
The following flags are for compatibility with future hardware. You can set them in addition to the preceding flags.
- MEMTYPE_DMA. Allocates only the memory that is accessible via direct memory access (DMA). Currently, all memory is accessible via DMA, but this may not be true in future hardware. Include this flag if you know the memory must be accessible via DMA.
- MEMTYPE_CEL. Allocates memory that is accessible only to the cel engine. Currently, all memory is accessible to the cel engine, but this may not be true in future hardware. Include this flag if you know the memory will be used for graphics.
- MEMTYPE_AUDIO. Allocates only memory that is used only for audio data (such as digitized sound). Currently, all memory can be used for audio, but this may not be true in future hardware. Include this flag if you know the memory will be used for audio data.
- MEMTYPE_DSP. Allocates only memory that is accessible to the digital signal processor (DSP). Currently, all memory is accessible to the DSP, but this may not be true in future hardware. Include this flag if you know the memory must be accessible to the DSP.
You can use the following optional flags to specify alignment (where the block is in relation to page boundaries), fill (the initial value of all memory locations in the block), and other allocation characteristics:
- MEMTYPE_FILL. Sets every byte in the memory block to the value of the lower-8 bits of the flags. If this flag is not set, the previous contents of the memory block are not changed. Using this flag is slower than not using it, so don't set this flag if you plan to initialize memory with your own data.
- MEMTYPE_INPAGE. Allocates a memory block that does not cross page boundaries.
- MEMTYPE_SYSTEMPAGESIZE. Allocates a memory block that starts on a memory protection page boundary as opposed to a SPORT page boundary.
- MEMTYPE_STARTPAGE. Allocates a memory block that starts on a page boundary. When allocating VRAM, this flag tells the system to allocate memory at the start of a SPORT page (2 KB boundaries) as opposed to a memory protection page. To always use the memory protection page size, you must also set the
MEMTYPE_SYSTEMPAGESIZE
flag.
- MEMTYPE_MYPOOL. Allocates a memory block from memory that is already in your task's free memory pool. This means that if there is not sufficient memory in the task's pool, the kernel will not allocate additional memory from the system-wide free memory pool.
- MEMTYPE_FROMTOP. Causes the allocation to come from the top of the task's free pool instead of from the bottom.
If there is insufficient memory in a task's free memory pool to allocate the requested memory, the kernel automatically transfers the necessary pages of additional memory from the system-wide free memory pool to the task's free memory pool. The only exceptions are when there is not enough memory in both pools together to satisfy the request, or when the MEMTYPE_MYPOOL
memory flag-which specifies that the memory block must be allocated only from the task's current free memory pool-is set.
Freeing a Memory Block
To free a memory block allocated with AllocMem()
, use FreeMem()
:
void FreeMem( void *p, int32 size )
The p
argument points to the memory block to free. The size
argument specifies the size of the block to free, in bytes. The size you specify must always be the same as the size specified when you allocated the block.
Allocating Memory in Programs Ported From Other Platforms
If you're porting a program from another platform that uses the malloc()
function from the standard C library to allocate memory, you can continue to use malloc():
void *malloc( int32 size )
The size
argument specifies the size of block to allocate, in bytes. It returns a pointer to the block that was allocated, or NULL if the memory couldn't be
allocated.
Because malloc()
does not accept memory allocation flags, you cannot use it to specify a particular kind of memory or any other memory characteristics. If you are writing programs specifically for 3DO systems, you should use AllocMem()
in place of malloc()
.
You must only use free()
to free memory that you've allocated with malloc()
. Each memory allocation function has a corresponding deallocation function; if you use a different memory allocation function, you must use its corresponding deallocation function. (See .)
Freeing Memory in Programs Ported From Other Platforms
To free a memory block you have allocated with malloc(),
use free()
:
void free( void *p )
The p
argument points to the memory block to free. The entire block is freed automatically; unlike FreeMem(),
you do not need to specify the amount of
memory to free.