Heap Memory Allocation

Heap definition

The heap is allocated from a predefined section of memory. Facilities are provided for user expansion of the heap to mass storage, although the current code makes no provision for page management. When the heap is initialised, a free block and an end block are created. The end block is of zero size, and is used only as a marker. The address returned by ALLOCATE and RESIZE is the address of the first data byte, as is the address consumed by FREE.

The heap must be initialised before use by calling INIT-HEAP. Heap access words return status=0 for success, and status<>0 for error.

Two equates are required during compilation to allocate a contiguous block of RAM for the heap.


  STARTOFHEAP is the start address of the heap
  SIZEOFHEAP is the size of the RAM for the heap

There are two versions of this code provided. Heap32.fth is provided for 32-bit targets and is optimised for the VFX code generator. Heap16.fth is for 16 bit targets, and is optimised for code density.

32 bit targets - HEAP32.FTH

The heap is controlled using a single cell per block. This information is used in two parts:


bits 31..24: $EE - End, $FF - Free, $AA - Allocated
bits 23..0: 24 bits for number of data bytes in block.

A consequence of this is that the maximum block size that can be allocated is 16Mb-1 bytes.

If you use a pre-emptive scheduler or need to use the heap words inside interrupt routines, you must define suitable heap lock and unlock words and set the equate LOCKHEAP? to non-zero.

LockHeap=0

no heap locking

LockHeap=1

heap locking by turning off interrupts

LockHeap=2

heap locking by semaphore.

16 bit targets - HEAP16.FTH

The heap is controlled using two cells per block. This information is used in three parts:


cell = #bytes, number of bytes in this block
cell = flag, split between a four bit and a 12 bit field

The top four bits of the flag are used to indicate the block type, where $E = End, $F = Free, $A = Allocated. Others may be added later for type management.

The bottom 12 bits of the flag are currently unused, and should be set to zero.

Gotchas

The heap routines must be protected if they are to be used both in normal code and in interrupts. In this case the code must be modified to be interrupt safe, but this may have a significant impact on interrupt latency. Examples may be found in heap32.fth.

If you use a pre-emptive scheduler, you must also define suitable heap lock and unlock routines.

The equate LOCKHEAP? controls the usage:

LockHeap=0

no heap locking

LockHeap=1

heap locking by turning off interrupts

LockHeap=2

heap locking by semaphore.

Glossary

The glossary does not include all the factors used in the code. If you are interested in the implementation, please read the sources.

sizeofheap buffer: STARTOFHEAP  \ -- addr
The heap memory is defined at compile time.

STARTOFHEAP sizeofheap + equ ENDOFHEAP  \ -- addr
The end+1 of the heap.

: init-heap     \ --
The heap is initialised by creating 2 blocks. Block 1 starts at the beginning and is marked as a free block. Block 2 Is a null marker at the end of heap space.

: allocate      \ #bytes -- addr status
Attempt to allocate some memory from the heap. Walk the heap looking for a single big enough block. If the block is larger than than required split it into two blocks. Allocate part or all of the free block. Status=0 for success.

: free          \ addr -- status
Attempt to free a heap block. Status=0 for success. If addr is zero, no action is taken and zero is returned.

: resize        { *ptr newsize | currsize -- *newptr ior }
Try to resize an allocated block to a new size, allowing for alignment. If the existing memory block is not big enough, the data will be copied to a new block, and the returned addr2 will not be the same as addr1. Status=0 for success.

: size          \ *ptr -- currsize|-1
Return the size of an allocated block or -1 if there's an error.

Diagnostics

: .heap         \ --
Walk the heap displaying block information.

: heapok?       \ -- t/f
Walk the heap and return TRUE if the heap is "well".