home *** CD-ROM | disk | FTP | other *** search
- /*
- #### # # # #
- # # # # # The FreeWare C library for
- # # ## ### # # # # ### RISC OS machines
- # # # # # # # # # # # ___________________________________
- # # #### ### ## # # # #
- # # # # # # # # # # Please refer to the accompanying
- #### ### #### # # ##### # ### documentation for conditions of use
- ________________________________________________________________________
-
- File: Mem.h
- Author: Copyright © 1993, 1994 Jason Williams
- Version: 1.01 (22 May 1994)
- Purpose: Dynamic memory manager
- */
-
- #ifndef __dl_mem_h
- #define __dl_mem_h
-
- #ifdef __cplusplus
- extern "C" {
- #endif
-
- /* "Flex" is the RISC OS Lib 'flexible' malloc for desktop tasks
- * "Mem" is DeskLib's equivalent thereof.
- *
- * Mem memory chunks are held in a 'heap' of memory above the area grabbed
- * by the SharedCLibrary for mallocs and stackspace, extending up to the
- * end of the WimpSlot, which is adjusted up & down as necessary.
- *
- * The major feature that externally distinguishes Mem from flex() is that
- * the heap is NOT compacted automatically (flex keeps the entire heap
- * compacted at all times). This has several advantages:
- * - You can rely on pointers remaining constant at all times between
- * calls to Mem_Compact() (and other Mem_ calls if you allow it)
- * - everything is a lot faster if you are allocating and/or
- * deallocating many chunks in one go.
- *
- * The idea behind this is that you simply call Mem_Compact before
- * calling Wimp_Poll - this returns free memory to the Wimp as effectively
- * as the flex system did, but saves us from having to waste time on
- * multiple compactions between Wimp_Polls.
- *
- * Automatic compaction (a la flex) can be turned on (or off) at any time
- * so the Mem system can be made to emulate flex_ if you really want it.
- * To do this, set mem_autocompact to the values described below.
- * NOTE that by default, mem will only autocompact if it has no choice,
- * but *may* autocompact during any Mem_ call.
- */
-
-
- #ifndef __dl_core_h
- #include "Core.h"
- #endif
-
-
- typedef void *mem_anchor;
-
-
- /* Compaction control
- * Apart from compacting when you call Mem_Compact(), Mem will also
- * compact at the following times, depending on the value of mem_autocompact
- *
- * mem_NOCOMPACT: Auto compaction never occurs. This may be useful if
- * you wish to guarantee that chunks ONLY move when you
- * call Mem_Compact().
- *
- * mem_PARTCOMPACT: Auto compaction occurs whenever compaction might make
- * an otherwise impossible memory claim possible. This is
- * the recommended (and default) setting.
- *
- * mem_FULLCOMPACT: Auto compaction occurs every time a chunk is freed
- * (the way that RISC OS Lib flex() operates)
- * This is not reccommended, as it can be very inefficient
- *
- * NOTE that the value of flex_autocompact may be changed at any time
- * and will take immediate effect. Therefore, if you wish to ensure that
- * pointers into mem chunks remain 'safe' for a short period of time, you
- * can set mem_autocompact = mem_NOCOMPACT while procssing, and return
- * it to its former value when finished.
- */
-
- #ifndef __dl_mem_c
- extern int mem_autocompact;
- #endif
-
- typedef enum
- {
- mem_NOCOMPACT = 0, /* ONLY compacts if Mem_Compact called */
- mem_FASTCOMPACT = 1, /* Compacts only if necessary */
- mem_PARTCOMPACT = 1,
- mem_FULLCOMPACT = 2 /* Compacts on every heap change */
- } mem_compaction;
-
-
-
- /* Mem_Initialise()
- * Initialises the Mem system ready for use.
- * Note that this locks down the malloc and stack memory area to the
- * current WimpSlot size at the point of calling, and builds a mem
- * heap above this. Malloc and stack allocation will not be able to get
- * more memory than is originally available in your WimpSlot, so get it
- * right!
- * Note that Mem_Initialise() provides a function to
- * _kernel_register-slotextend() to stop the SharedCLib being able to
- * overwrite the Mem heap with the stack/malloc chunks.
- */
- extern BOOL Mem_Initialise(void);
-
-
- /* Mem_Alloc()
- * Attempts to allocate the given amount of memory (in bytes) in the mem
- * heap. Updates the anchor you pass in to point to this block, or
- * to contain NULL if it is unable to allocate the requested memory.
- * The returned block of memory starts at a word-aligned address
- * Returns TRUE if it succeeded
- *
- * If permitted to by the setting of mem_autocompact, this call MAY
- * relocate other mem chunks.
- */
- extern BOOL Mem_Alloc(mem_anchor *anchor, int numbytes);
-
-
- /* Mem_MidExtend()
- * Attempts to alter the size of a mem chunk.
- * "at" is a byte-offset within the data chunk
- * "by" is the number of bytes to extend by (negative to reduce the chunk)
- * If "by" is positive,
- * 'by' bytes of indeterminate value will be inserted at 'at', shifting
- * the rest of the data up to make room
- * else
- * 'by' bytes of data BELOW 'at' will be deleted by moving the data
- * from 'at' onwards down by 'by' bytes.
- *
- * Returns TRUE if the extension was successful.
- * The allocated memory starts at a word-aligned address
- *
- * If permitted to by the setting of mem_autocompact, this call MAY
- * relocate other mem chunks.
- */
- extern BOOL Mem_MidExtend(mem_anchor *anchor, int at, int by);
-
-
- /* Mem_MoveAnchor
- * Allows you to move an anchor from one variable to another.
- * This allows you to allocate a chunk with a temporary anchor and then
- * move the anchor into permanent storage at a later time (without having
- * to allocate a new chunk and copy, as is necessary under flex)
- *
- * Use with care - i.e. remember to check anchors to see if they are NULL
- * (in which case you're using the wrong anchor!)
- *
- * If all goes well (i.e. 'from' was a valid chunk), *from will be set
- * to NULL and *to will now point at the chunk. From this point on,
- * the anchor 'to' will be adjusted whenever the chunk is moved.
- *
- * Otherwise, from is left as it was, and to will be set to NULL
- *
- * example:
- * {
- * char *old, *new;
- * Mem_Alloc((mem_anchor *) &old, 1024); |* Get some memory *|
- * if (old != NULL)
- * {
- * old[5] = 'a';
- * Mem_MoveAnchor((mem_anchor *) &old, (mem_anchor *) &new);
- * |* if 'old' was valid, 'new' now points to where old was, *|
- * |* and old is now NULL *|
- *
- * if (new == NULL) printf("Error - old was invalid! \n");
- * if (new[5] != 'a') printf("Error - Jason's code is buggy! \n");
- */
- extern void Mem_MoveAnchor(mem_anchor *from, mem_anchor *to);
-
-
- /* Mem_Free()
- * Releases a chunk of memory back to the free pool
- * The contents of the anchor will be set to NULL to indicate it is no
- * longer a valid pointer.
- * If permitted to by the contents of mem_autocompact, this call MAY
- * relocate other mem chunks.
- */
- extern void Mem_Free(mem_anchor *anchor);
-
-
- /* Mem_Compact()
- * This call compacts the mem heap, moving all free space to the end of
- * the chunk, and giving back as much memory as possible to the Wimp.
- * This may result in some mem chunks moving, so you cannot rely on
- * anchors remaining the same across this call.
- * Ideally, you should call this just before calling Wimp_Poll, to
- * ensure the Wimp has all possible available memory (and also keep the
- * heap tidy)
- * Note that this may be automatically called by other Mem_ functions
- * IF mem_autocompact allows it. However, it will NEVER be called if
- * mem_autocompact == mem_NOCOMPACT
- */
- extern void Mem_Compact(void);
-
-
- /* Mem_Size()
- * Returns the current size (in bytes) of a mem chunk
- */
- extern int Mem_Size(mem_anchor *anchor);
-
-
- /* Mem_CheckHeap()
- * Returns TRUE if the heap data structure is valid (i.e. the links are all
- * intact and anchors are consistent)
- */
- extern BOOL Mem_CheckHeap(void);
-
-
- #ifdef __cplusplus
- }
- #endif
-
- #endif
-