MAlloc - Memory Allocation Library Routines =========================================== File: MAlloc - Update: 1.05 Author: J.G.Harston - Date: 15-Sep-2011 MAlloc provides functions and procedures to claim and release blocks of memory in the BASIC heap. The library keeps track of released memory and tries to reuse it as efficiently as possible. Requirements and Dependancies ============================= None. Routine Summary =============== FNm_alloc() - claim memory FNm_zalloc() - claim zeroed memory FNm_free() - release memory FNm_realloc() - resize claimed memory Claim Memory ============ DEFFNm_alloc(size%) Allocates size% bytes in the heap. Returns zero if failed, or a pointer to memory block. If size% is zero, returns the largest contiguous amount of memory that can be claimed in a single call, an amount that is guaranteed can be used by a subsequent FNm_alloc() call. Once this block is claimed there may or may not be more memory that can be claimed in subsequent calls. Consequently, ptr%=FNm_alloc(FNm_alloc(0)) can be used to claim the largest block available. ptr% must be checked for 0 which will result if no memory is available to claim. Claim and Zero Memory ===================== DEFFNm_zalloc(size%) Allocates size% bytes in the heap and clears each byte of the allocated memory to zero. Returns zero if failed, or pointer to memory block. As with FNm_alloc(), if size% is zero, returns an amount of free claimable memory that can be claimed by a subsequent FNm_zalloc() call. Release Memory ============== DEFPROCm_free(ptr%) Returns the specified block to the heap. If ptr% is zero, the call is a null operation. Resize claimed memory ===================== DEFFNm_realloc(ptr%,size%) Reallocates the memory block to be the new size. If the pointer is zero a new block is created, if the size is 0 the block is freed. Returns a pointer to a new block, or zero if the call failed. If data from old block needs to be preserved, it must be copied by the program between an FNm_alloc() call to claim new memory and a PROCm_free() call to release the old memory. As with FNm_alloc() and FNm_zalloc(), calling FNm_realloc() with a size% of zero will return an amount of free claimable memory. This means that you can use ptr%=FNm_alloc(FNm_realloc(ptr%,0)) to release the block at ptr% and then claim the largest possible claimable block. Notes ===== PROCm_free() and FNm_realloc() are undefined and potentially dangerous if ptr% is not a value previously returned from FNm_alloc(), FNm_zalloc() or FNm_realloc(). Note that normally FNm_alloc() and FNm_zalloc() return a pointer to a block of memory, but bear in mind that FNm_alloc(0) and FNm_zalloc(0) return a /size/, not a pointer. This is a consistant API that can be reimplemented using other storage methods, such as global Windows memory, RISC OS module memory, dynamic memory, etc., and other programmers are free to do so. Technical notes =============== FNm_alloc() and FNm_zalloc() try to reuse memory released by PROCm_free(), but, as in any allocation system, reuse is not perfect. In particular, if lots of small, different size blocks of memory are claimed and released the heap will fragment rapidly. Space is claimed from the BASIC heap, but freed space is not returned to the BASIC heap, but only returned to the MAlloc routines. Blocks that are released in the opposite order to being claimed will tend to compact more efficiently than otherwise. There is a small overhead to each claimed block so that it can be released back to the heap. Version History =============== 1.00 06-Sep-1989 m_alloc() and m_free() written. 1.01 08-Sep-1989 Bug in reuse of released memory fixed. 1.02 15-Sep-1989 m_realloc() added. 1.03 23-Jul-2006 m_zalloc() added. 1.04 12-Aug-2006 Checks for remaining heap space left. 1.05 15-Sep-2011 Extends last slot into free space.