home *** CD-ROM | disk | FTP | other *** search
/ RISC DISC 1 / RISC_DISC_1.iso / pd_share / code / desklib / !DeskLib / h / Mem < prev    next >
Encoding:
Text File  |  1994-05-22  |  8.1 KB  |  211 lines

  1. /*
  2.     ####             #    #     # #
  3.     #   #            #    #       #          The FreeWare C library for 
  4.     #   #  ##   ###  #  # #     # ###             RISC OS machines
  5.     #   # #  # #     # #  #     # #  #   ___________________________________
  6.     #   # ####  ###  ##   #     # #  #                                      
  7.     #   # #        # # #  #     # #  #    Please refer to the accompanying
  8.     ####   ### ####  #  # ##### # ###    documentation for conditions of use
  9.     ________________________________________________________________________
  10.  
  11.     File:    Mem.h
  12.     Author:  Copyright © 1993, 1994 Jason Williams
  13.     Version: 1.01 (22 May 1994)
  14.     Purpose: Dynamic memory manager
  15. */
  16.  
  17. #ifndef __dl_mem_h
  18. #define __dl_mem_h
  19.  
  20. /* "Flex" is the RISC OS Lib 'flexible' malloc for desktop tasks
  21.  * "Mem" is DeskLib's equivalent thereof. 
  22.  *
  23.  *  Mem memory chunks are held in a 'heap' of memory above the area grabbed
  24.  *  by the SharedCLibrary for mallocs and stackspace, extending up to the
  25.  *  end of the WimpSlot, which is adjusted up & down as necessary.
  26.  *
  27.  *  The major feature that externally distinguishes Mem from flex() is that
  28.  *  the heap is NOT compacted automatically (flex keeps the entire heap
  29.  *  compacted at all times). This has several advantages:
  30.  *    - You can rely on pointers remaining constant at all times between
  31.  *      calls to Mem_Compact() (and other Mem_ calls if you allow it)
  32.  *    - everything is a lot faster if you are allocating and/or
  33.  *      deallocating many chunks in one go.
  34.  *
  35.  *  The idea behind this is that you simply call Mem_Compact before
  36.  *  calling Wimp_Poll - this returns free memory to the Wimp as effectively
  37.  *  as the flex system did, but saves us from having to waste time on
  38.  *  multiple compactions between Wimp_Polls.
  39.  *
  40.  *  Automatic compaction (a la flex) can be turned on (or off) at any time
  41.  *  so the Mem system can be made to emulate flex_ if you really want it.
  42.  *  To do this, set mem_autocompact to the values described below.
  43.  *  NOTE that by default, mem will only autocompact if it has no choice,
  44.  *  but *may* autocompact during any Mem_ call.
  45.  */
  46.  
  47.  
  48. #ifndef __dl_core_h
  49. #include "Core.h"
  50. #endif
  51.  
  52.  
  53. typedef void *mem_anchor;
  54.  
  55.  
  56. /*  Compaction control
  57.  *  Apart from compacting when you call Mem_Compact(), Mem will also
  58.  *  compact at the following times, depending on the value of mem_autocompact
  59.  *
  60.  *    mem_NOCOMPACT:    Auto compaction never occurs. This may be useful if
  61.  *                      you wish to guarantee that chunks ONLY move when you
  62.  *                      call Mem_Compact().
  63.  *
  64.  *    mem_PARTCOMPACT:  Auto compaction occurs whenever compaction might make
  65.  *                      an otherwise impossible memory claim possible. This is
  66.  *                      the recommended (and default) setting.
  67.  *
  68.  *    mem_FULLCOMPACT:  Auto compaction occurs every time a chunk is freed
  69.  *                      (the way that RISC OS Lib flex() operates)
  70.  *                      This is not reccommended, as it can be very inefficient
  71.  *
  72.  *  NOTE that the value of flex_autocompact may be changed at any time
  73.  *  and will take immediate effect. Therefore, if you wish to ensure that
  74.  *  pointers into mem chunks remain 'safe' for a short period of time, you
  75.  *  can set mem_autocompact = mem_NOCOMPACT while procssing, and return
  76.  *  it to its former value when finished.
  77.  */
  78.  
  79. #ifndef __dl_mem_c
  80.   extern int mem_autocompact;
  81. #endif
  82.  
  83. typedef enum
  84. {
  85.   mem_NOCOMPACT   = 0,               /* ONLY compacts if Mem_Compact called  */
  86.   mem_FASTCOMPACT = 1,               /* Compacts only if necessary           */
  87.   mem_PARTCOMPACT = 1,
  88.   mem_FULLCOMPACT = 2                /* Compacts on every heap change        */
  89. } mem_compaction;
  90.  
  91.  
  92.  
  93.   /*  Mem_Initialise()
  94.    *  Initialises the Mem system ready for use.
  95.    *  Note that this locks down the malloc and stack memory area to the
  96.    *  current WimpSlot size at the point of calling, and builds a mem
  97.    *  heap above this. Malloc and stack allocation will not be able to get
  98.    *  more memory than is originally available in your WimpSlot, so get it
  99.    *  right!
  100.    *  Note that Mem_Initialise() provides a function to
  101.    *  _kernel_register-slotextend() to stop the SharedCLib being able to
  102.    *  overwrite the Mem heap with the stack/malloc chunks.
  103.    */
  104. extern BOOL Mem_Initialise(void);
  105.  
  106.  
  107.   /*  Mem_Alloc()
  108.    *  Attempts to allocate the given amount of memory (in bytes) in the mem
  109.    *  heap. Updates the anchor you pass in to point to this block, or
  110.    *  to contain NULL if it is unable to allocate the requested memory.
  111.    *  The returned block of memory starts at a word-aligned address
  112.    *  Returns TRUE if it succeeded
  113.    *
  114.    *  If permitted to by the setting of mem_autocompact, this call MAY
  115.    *  relocate other mem chunks.
  116.    */
  117. extern BOOL Mem_Alloc(mem_anchor *anchor, int numbytes);
  118.  
  119.  
  120.   /*  Mem_MidExtend()
  121.    *  Attempts to alter the size of a mem chunk.
  122.    *  "at" is a byte-offset within the data chunk
  123.    *  "by" is the number of bytes to extend by (negative to reduce the chunk)
  124.    *  If "by" is positive,
  125.    *    'by' bytes of indeterminate value will be inserted at 'at', shifting
  126.    *    the rest of the data up to make room
  127.    *  else
  128.    *    'by' bytes of data BELOW 'at' will be deleted by moving the data
  129.    *    from 'at' onwards down by 'by' bytes.
  130.    *
  131.    *  Returns TRUE if the extension was successful.
  132.    *  The allocated memory starts at a word-aligned address
  133.    *
  134.    *  If permitted to by the setting of mem_autocompact, this call MAY
  135.    *  relocate other mem chunks.
  136.    */
  137. extern BOOL Mem_MidExtend(mem_anchor *anchor, int at, int by);
  138.  
  139.  
  140.   /*  Mem_MoveAnchor
  141.    *  Allows you to move an anchor from one variable to another.
  142.    *  This allows you to allocate a chunk with a temporary anchor and then
  143.    *  move the anchor into permanent storage at a later time (without having
  144.    *  to allocate a new chunk and copy, as is necessary under flex)
  145.    *
  146.    *  Use with care - i.e. remember to check anchors to see if they are NULL
  147.    *  (in which case you're using the wrong anchor!)
  148.    *
  149.    *  If all goes well (i.e. 'from' was a valid chunk), *from will be set
  150.    *  to NULL and *to will now point at the chunk. From this point on,
  151.    *  the anchor 'to' will be adjusted whenever the chunk is moved.
  152.    *
  153.    *  Otherwise, from is left as it was, and to will be set to NULL
  154.    *
  155.    *  example:
  156.    *  {
  157.    *    char *old, *new;
  158.    *    Mem_Alloc((mem_anchor *) &old, 1024);   |* Get some memory *|
  159.    *    if (old != NULL)
  160.    *    {
  161.    *      old[5] = 'a';
  162.    *      Mem_MoveAnchor((mem_anchor *) &old, (mem_anchor *) &new);
  163.    *          |* if 'old' was valid, 'new' now points to where old was, *|
  164.    *          |* and old is now NULL                                    *|
  165.    *
  166.    *      if (new == NULL)    printf("Error - old was invalid! \n");
  167.    *      if (new[5] != 'a')  printf("Error - Jason's code is buggy! \n");
  168.    */
  169. extern void Mem_MoveAnchor(mem_anchor *from, mem_anchor *to);
  170.  
  171.  
  172.   /*  Mem_Free()
  173.    *  Releases a chunk of memory back to the free pool
  174.    *  The contents of the anchor will be set to NULL to indicate it is no
  175.    *  longer a valid pointer.
  176.    *  If permitted to by the contents of mem_autocompact, this call MAY
  177.    *  relocate other mem chunks.
  178.    */
  179. extern void Mem_Free(mem_anchor *anchor);
  180.  
  181.  
  182.   /*  Mem_Compact()
  183.    *  This call compacts the mem heap, moving all free space to the end of
  184.    *  the chunk, and giving back as much memory as possible to the Wimp.
  185.    *  This may result in some mem chunks moving, so you cannot rely on
  186.    *  anchors remaining the same across this call.
  187.    *  Ideally, you should call this just before calling Wimp_Poll, to
  188.    *  ensure the Wimp has all possible available memory (and also keep the
  189.    *  heap tidy)
  190.    *  Note that this may be automatically called by other Mem_ functions
  191.    *  IF mem_autocompact allows it. However, it will NEVER be called if
  192.    *  mem_autocompact == mem_NOCOMPACT
  193.    */
  194. extern void Mem_Compact(void);
  195.  
  196.  
  197.   /*  Mem_Size()
  198.    *  Returns the current size (in bytes) of a mem chunk
  199.    */
  200. extern int  Mem_Size(mem_anchor *anchor);
  201.  
  202.  
  203.   /*  Mem_CheckHeap()
  204.    *  Returns TRUE if the heap data structure is valid (i.e. the links are all
  205.    *  intact and anchors are consistent)
  206.    */
  207. extern BOOL Mem_CheckHeap(void);
  208.  
  209.  
  210. #endif
  211.