The <alloc.h> header file
This header file contains the following functions:
alloca calloc free FreeHandles
HeapAlloc HeapAllocESTACK HeapAllocHigh HeapAllocHighThrow
HeapAllocThrow HeapAllocPtr HeapAvail HeapCompress
HeapDeref HeapEnd HeapFree HeapFreePtr
HeapFreeIndir HeapGetHandle HeapGetLock HeapLock
HeapMax HeapMoveHigh HeapPtrToHandle HeapRealloc
HeapSize HeapUnlock HLock malloc
realloc
and the following constants and predefined types:
Bool H_NULL HANDLE NULL
size_t
Functions
Allocates a memory block.
malloc allocates a block of Size bytes from the memory heap.
It allows a program to allocate memory explicitly as it's needed, and in
the exact amounts needed. The heap is used for dynamic allocation of
variable-sized blocks of memory. Many data structures, such as trees and
lists, naturally employ heap memory allocation. On success, malloc returns
a pointer to the newly allocated block of memory. If not enough space
exists for the new block, it returns NULL. The contents
of the block are left unchanged. If the argument Size is zero
malloc also returns NULL.
malloc is in fact an ANSI C alias for a TIOS routine originally called
HeapAllocPtr (see description of it for more
system info).
NOTE: As the TIOS memory manager assigns a handle to each allocated block, and
as the total number of handles is limited, malloc is not good for algorithms
where you need to allocate a large number of small blocks (as in implementations
of linked lists which are usually seen in various C language books and tutorials).
The same is true for all other TIOS memory management routines.
Allocates a memory block for a given number of items.
calloc allocates a block of NoOfItems x SizeOfItems
bytes from the memory heap. On success, calloc returns a pointer to the newly allocated
block of memory. If not enough space exists for the new block, it returns
NULL. The allocated block will be cleared to zero content.
NOTE: In releases of TIGCCLIB prior to 2.0, calloc was implemented here as a macro,
Now, it is a function. It first calls malloc
with NoOfItems x SizeOfItems as the argument, then calls
memset if the first call was successful.
Reallocates allocated memory.
realloc attempts to shrink or expand the previously allocated block to NewSize
bytes. The Ptr argument points to a memory block previously obtained by calling
malloc, calloc, or realloc.
In opposite to ANSI C implementation, Ptr should not be NULL
(anyway, nobody calls realloc with NULL as the argument: ANSI C proposes
that realloc should work just like malloc in this case).
realloc adjusts the size of the allocated block to size, copying the contents to a new location
if necessary (note that the block will not stay in the high memory after the reallocation, but
it will still remain locked; see other functions from this header file for more info).
realloc returns the address of the reallocated block, which can be different than the address
of the original block. If the block cannot be reallocated, realloc returns NULL.
NOTE: realloc is introduced to increase compatibility with ANSI C. It is better to use
TIOS official function HeapRealloc which uses system of handles
to memory blocks.
Frees allocated blocks.
free deallocates a memory block allocated by a previous call to
malloc or calloc.
NOTE: free is in fact an ANSI C alias for a TIOS routine originally called
HeapFreePtr.
Allocates memory on a local storage space.
alloca is function which is not included in ANSI C standard, but it exists in many C dialects
(including TIGCC). It allocates a block of Size bytes on the CPU stack (local
storage space), in opposite to malloc which allocates memory on the
memory heap. The space allocated with alloca exists until the containing function returns
(i.e. it will be automatically deallocated at the end of the function). Be aware of the
fact that the size of the hardware stack on TI calculators is limited to 16 kilobytes, so
do not use alloca for allocating large blocks.
alloca is usually used for simulating automatic variable-sized one-dimensional arrays, which will be automatically
deallocated when the function ends (like all automatic variables), so it is sometimes more
preferable than malloc. For example, to simulate
int a[n];
where 'n'
is not known in advance, you can use
int *a = alloca (n);
Note, however, that GNU C extensions allows variable-length
arrays, which are more elegant than usage of alloca, and which may also be with more than
one dimension (which is not possible with alloca).
NOTE: alloca is a builtin (open-coded) function in GNU C, which is translated to a single
instruction which simply adjust the stack. Some compiler command options (like
'-ansi') prevent alloca to be an open-codes function. In this implementation
of TIGCC, you can not use alloca with such options (however, it is very unlikely that you will
ever have such problems).
HANDLE HeapAlloc (unsigned long Size);
Allocates memory and returns a handle of allocated block.
HeapAlloc allocates a block of heap memory of the Size bytes (all odd sizes
are rounded up to be even) and returns
its handle. Allocated blocks are kept in a single-linked list of blocks.
Returns H_NULL if there is not enough memory. The maximum
size of a single block is 65520 bytes, and the minimum size is 8 bytes. Use
HeapDeref to dereference
the handle and get a pointer to the actual memory. Note that an unlocked pointer to the
heap is valid only as long as heap compression (i.e. garbage collection) is not done.
This routine may cause garbage collection.
HANDLE HeapAllocHigh (unsigned long Size);
Allocates memory at the high end of the heap and returns a handle of allocated block.
HeapAllocHigh allocate a block of Size bytes of heap memory at the high end of the heap,
lock it, and return its handle. Returns H_NULL if there is not enough memory.
The primary use of this routine is to allocate task
local storage. It also compresses the heap first to (hopefully) move all used
(unlocked) blocks of memory down. This routine will cause garbage collection.
See also HeapAlloc.
NOTE: Blocks of memory that are locked for long periods of time should be moved high
in memory so that they do not interfere as much with rest of the system. This routine
ALWAYS compresses the heap before it tries to allocate the requested memory and so is
much slower than the standard HeapAlloc routine. Locking
memory may cause the system to run out of useable memory sooner than if memory is
kept unlocked.
Allocates memory at the high end of the heap and returns a pointer to the allocated block.
HeapAllocPtr performs HeapAllocHigh, but instead of the handle, it returns
a pointer to the allocated block (NULL in a case of error). It also
gives a necessary information to the heap manager which is needed later for deallocating
the memory using HeapFreePtr command. This routine is principally
equivalent to ANSI C malloc function, so it is aliased here also as
malloc.
NOTE: If somebody is interested for it, the handle of the allocated block is stored two
bytes below the address returned by HeapAllocPtr.
HANDLE HeapAllocThrow (unsigned long Size);
Performs HeapAlloc, and throws an error if not successful.
HeapAllocThrow calls HeapAlloc and throws a
memory error if there is not enough memory. Otherwise, it returns the handle
of allocated block.
HANDLE HeapAllocHighThrow (unsigned long Size);
Performs HeapAllocHigh, and throws an error if not successful.
HeapAllocHighThrow calls HeapAllocHigh and throw a memory error if there is
not enough memory. Otherwise, it returns the handle of allocated block.
void *HeapDeref (HANDLE Handle);
Dereferences a handle.
HeapDeref dereferences Handle and returns a pointer to the actual block
of the memory defined by that Handle. Nearly all heap allocation routines
return a "handle" which is an identifier for a block of memory allocated in the heap.
In order to use that memory, the handle must be dereferenced. Once a handle is
dereferenced, that pointer is valid as long as nothing else is done to cause
the heap to be compressed. If the heap is compressed the handle can be
redereferenced to make it valid again. If a handle is locked, then the
pointer that references that block of memory is valid even after the heap is
compressed (since locking a handle means the heap manager will never
move the memory associated with that handle).
NOTE: HeapDeref returns a garbage if Handle is H_NULL.
Determines number of free handles.
FreeHandles returns a number of free handles.
Determines size of the heap.
HeapAvail returns the total amount of free bytes in the heap (the sum of all
of the individual blocks of memory).
Compress the heap.
HeapCompress coalesces all used heap blocks, deleting any free blocks from the
heap if possible. If there are any locked blocks, the heap may remain fragmented.
This routine is called automatically by the system whenever it is needed
and usually should not be called by applications.
void HeapFree (HANDLE Handle);
Free a heap block given its handle.
HeapFree frees a heap block associated with handle Handle.
Free a heap block given a pointer to it.
HeapFreeIndir is like HeapFree except you pass the address
of a variable which keeps the block handle instead of the handle itself. If the handle
that PtrHandle points to is not H_NULL, then frees that
handle and sets the handle variable that is pointed to by PtrHandle to
H_NULL.
Maybe this sounds a bit confuse to you. In fact, doing
HeapFreeIndir (&handle); // The ampersand ('&') is important
works exactly the same as
if (handle) HeapFree (handle);
handle = H_NULL;
NOTE: In releases of TIGCCLIB prior to 2.2, the information about this routine was
quite misleading or even wrong.
Frees a block allocated using HeapAllocPtr.
HeapFreePtr frees a heap block pointed to by Ptr. The block must be a block
which is allocated using HeapAllocPtr command.
short HeapGetLock (HANDLE Handle);
Determines whether a block is locked.
Returns non-zero if the block given by Handle is locked, 0 if it is not
(i.e. if that memory is free to move on the next heap compression).
Locks a block.
HeapLock locks the block referenced by Handle so that it is not moved
during garbage collection. Returns Handle if OK, else returns
H_NULL.
NOTE: Locking memory may cause the system to run out of useable memory
sooner than if memory is kept unlocked.
Determines maximum allocatable block.
HeapMax returns the maximum block allocatable on
the heap (it will be in range 0..65520). Note that this may not
equal to HeapAvail due to
locked blocks, overhead, and maximum block size. This routine will (always) cause
garbage collection.
Reallocates a block.
HeapMoveHigh tries to reallocate a block referenced by Handle as high in
memory as possible. The block must not be locked. If successful, returns
the handle passed; otherwise returns H_NULL (in this case,
the block is still in the same place as before, so no memory is lost). This routine
will cause heap compression (garbage collection).
HANDLE HeapRealloc (HANDLE Handle, unsigned long NewSize);
Reallocates a block to a new size.
If Handle is H_NULL, HeapRealloc calls
HeapAlloc. Otherwise, it tries to reallocate the given heap block
to a new size. Returns H_NULL if there is not enough memory (it will
try to call HeapCompress) or if new size is invalid; otherwise
returns Handle. If the heap-block is locked, then the block will not be moved in
order to reallocate it. However, unlocked blocks above the heap-block will be moved.
The contents of the object will be unchanged up to
the lesser of the new and old size. If the new size is larger the value of the
newly allocated portion of the object is indeterminate.
This routine may cause garbage collection.
unsigned short HeapSize (HANDLE Handle);
Determines the size of an allocated block.
HeapSize returns the number of bytes allocated for the heap block referenced by
Handle. Due to word alignment and minimum block size, this may not be the
amount it was allocated with. Also note that because of locked blocks, it is possible
(rare) that a heap block will actually be bumped up a few words by the
HeapCompress routine. So never assume that the value
returned by HeapSize is the true number of bytes used by the data stored in the
heap block.
Unlocks a block.
HeapUnlock unlock the block referenced by the Handle so that it can be moved
during garbage collection. Returns Handle if OK, else returns
H_NULL.
void *HLock (HANDLE Handle);
Locks and dereferences a handle.
HLock locks a block referenced by Handle so that it will not
move on the next heap compression, and returns a pointer to the actual memory
block. Returns NULL in a case of error.
NOTE: Locking memory may cause the system to run out of useable memory
sooner than if memory is kept unlocked.
HANDLE HeapPtrToHandle (void *Ptr);
Determines a handle associated with block.
HeapPtrToHandle returns a handle which is associated to a block which is
pointed to by Ptr (or H_NULL if there is no any handle
which references to given block).
This routine works by searching the entire table of handles for the given pointer,
and so should be used accordingly. It assumes that the heap has not been compressed
since the dereferenced pointer was
originally obtained or the block it points to is locked.
HANDLE HeapGetHandle (void);
Gets a next available handle.
HeapGetHandle returns a number of first unallocated (free) handle, or
H_NULL if there is no free handles. Used mainly
for internal purposes.
Determines the end of the heap.
HeapEnd returns the pointer to the end of the heap.
HANDLE HeapAllocESTACK (unsigned long Size);
HeapAllocESTACK works like HeapAlloc, but performs
reducing the size of the expressions stack if necessary (i.e. if there is no
enough memory). Returns NULL if there is not enough
memory even after reducing the size of the expressions stack.
NOTE: The information about this routine in releases of TIGCCLIB prior to 2.0
were wrong!
Constants and predefined types
Bool is enumerated type for describing true or false values. It is defined as
enum Bool {FALSE, TRUE};
size_t is a type proposed in ANSI C for defining size of strings and
memory blocks. It is defined here as
typedef unsigned long size_t;
NULL is a null-pointer value, defined as (void *) 0.
HANDLE is a type which represents handles associated to allocated memory
blocks. It is defined as
typedef unsigned short HANDLE;
H_NULL is a null-handle defined as a constant with value 0.