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, 1995 Jason Williams and Jason Howat
- Version: 2.00 (18 Jun 1995)
- Purpose: Dynamic memory manager
- */
-
- #ifndef __Desk_Mem_h
- #define __Desk_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 Desk_Mem_Compact() (and other Desk_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 Desk_Mem_Compact before calling
- * Desk_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 Desk_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 Desk_flex_ if you really want it. To
- * do this, set Desk_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 Desk_Mem_ call.
- */
-
-
- #ifndef __Desk_Core_h
- #include "Desk.Core.h"
- #endif
-
-
- typedef void *Desk_mem_anchor;
-
-
- /* Compaction control
- * Apart from compacting when you call Desk_Mem_Compact(), Mem will also compact
- * at the following times, depending on the value of Desk_mem_autocompact
- *
- * Desk_mem_NOCOMPACT: Auto compaction never occurs. This may be useful if
- * you wish to guarantee that chunks ONLY move when you
- * call Desk_Mem_Compact().
- *
- * Desk_mem_PARTCOMPACT: Auto compaction occurs whenever compaction might make
- * an otherwise impossible memory claim possible. This
- * is the recommended (and default) setting.
- *
- * Desk_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 Desk_mem_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 Desk_mem_autocompact = Desk_mem_NOCOMPACT while procssing, and return it to
- * its former value when finished.
- */
-
- extern int Desk_mem_autocompact;
-
- typedef enum
- {
- Desk_mem_NOCOMPACT = 0, /* ONLY compacts if Desk_Mem_Compact called */
- Desk_mem_FASTCOMPACT = 1, /* Compacts only if necessary */
- Desk_mem_PARTCOMPACT = 1,
- Desk_mem_FULLCOMPACT = 2 /* Compacts on every heap change */
- } Desk_mem_compaction;
-
-
-
- /* Desk_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 Desk_Mem_Initialise() provides a function to
- * _kernel_register_slotextend() to stop the SharedCLibrary being able to
- * overwrite the Mem heap with the stack/malloc chunks.
- */
- extern Desk_bool Desk_Mem_Initialise(void);
-
-
- /* Desk_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 Desk_bool_TRUE if it succeeded
- *
- * If permitted to by the setting of Desk_mem_autocompact, this call MAY
- * relocate other Mem chunks.
- */
- extern Desk_bool Desk_Mem_Alloc(Desk_mem_anchor *anchor, int numbytes);
-
-
- /* Desk_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 Desk_bool_TRUE if the extension was successful.
- * The allocated memory starts at a word-aligned address
- *
- * If permitted to by the setting of Desk_mem_autocompact, this call MAY
- * relocate other Mem chunks.
- */
- extern Desk_bool Desk_Mem_MidExtend(Desk_mem_anchor *anchor, int at, int by);
-
-
- /* Desk_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;
- * Desk_Mem_Alloc((Desk_mem_anchor *) &old, 1024); |* Get some memory *|
- * if (old != NULL)
- * {
- * old[5] = 'a';
- * Desk_Mem_MoveAnchor((Desk_mem_anchor *) &old, (Desk_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 Desk_Mem_MoveAnchor(Desk_mem_anchor *from, Desk_mem_anchor *to);
-
-
- /* Desk_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 Desk_mem_autocompact, this call MAY
- * relocate other Mem chunks.
- */
- extern void Desk_Mem_Free(Desk_mem_anchor *anchor);
-
-
- /* Desk_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 Desk_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 Desk_Mem_ functions IF
- * Desk_mem_autocompact allows it. However, it will NEVER be called if
- * Desk_mem_autocompact == Desk_mem_NOCOMPACT
- */
- extern void Desk_Mem_Compact(void);
-
-
- /* Desk_Mem_Size()
- * Returns the current size (in bytes) of a Mem chunk
- */
- extern int Desk_Mem_Size(Desk_mem_anchor *anchor);
-
-
- /* Desk_Mem_CheckHeap()
- * Returns Desk_bool_TRUE if the heap data structure is valid (i.e. the links are
- * all intact and anchors are consistent)
- */
- extern Desk_bool Desk_Mem_CheckHeap(void);
-
-
-
-
-
- #ifdef Desk_DeskLib_DEBUG
- #ifdef Desk__making_Mem
- #include "Debug.h"
- #define Desk_debug_level Desk_mem_debuglevel
- #endif
-
- extern int Desk_mem_debuglevel;
- /*
- In the debug version of DeskLib, this is the Mem library's own version
- of Desk_debug_level. It is initially 0; a program can set it to different
- values to turn on different debug ouputs in the Mem library.
- */
- #endif
-
-
- #ifdef __cplusplus
- }
- #endif
-
-
- #endif
-