home *** CD-ROM | disk | FTP | other *** search
- Heap memory manager
- ===================
-
- WimpExtension's heap manager is one of the module's most powerful, useful,
- and - unavoidably - complicated features. This document is provided to
- explain more about what a relocatable heap is, and how to use it.
-
- Programming examples in this document are given in BASIC, because practically
- everyone knows how to use it.
-
- This document assumes that you know how to program in the RISC OS Wimp, and
- that you understand terms such as "WimpSlot" (read the chapter "The Window
- Manager" in the PRMs if you don't).
-
- Read the "SWIs" and "Manual" files for a brief description of the parameters
- for the SWI WimpExt_Heap.
-
-
-
- Why do I need a heap?
- ---------------------
-
- Any program which uses more than one block of memory which changes size needs
- a heap manager. For example, Edit and Paint need a heap manager, because they
- can have several files loaded at once, all of which can be changing size at
- any time. The files are loaded into memory "blocks", which are provided by
- the heap manager.
-
-
-
- Why use a relocatable heap?
- ---------------------------
-
- RISC OS provides a non-relocatable heap manager. This means that the memory
- blocks are fixed in memory, and don't move about. The problem with this is
- that it gets very wasteful on memory when you have finished using the block.
- Say you loaded three files into a text editor:
-
- /--------\ Highest memory address
- | File 3 |
- | |
- |--------|
- | File 2 |
- | |
- | |
- |--------|
- | File 1 |
- \--------/ Lowest memory address
-
- This is fine, no problems so far. However, suppose the user decided the close
- the file "File 2":
-
- /--------\ Highest memory address
- | File 3 |
- | |
- |--------|
- | unused |
- | |
- | |
- |--------|
- | File 1 |
- \--------/ Lowest memory address
-
- The block of memory in the middle is now unused, and is wasting space. A
- non-relocatable heap manager can't do anything about this. Another example is
- if the user adds something to File 2, making it longer. File 2 will no longer
- fit in its original block - if you extended it then it would overwrite
- File 3. Therefore the heap manager has to copy the whole file up in memory,
- as shown in the diagram:
-
- /--------\ Highest memory address
- | File 2 |
- | |
- | |
- | |
- |--------|
- | File 3 |
- | |
- |--------|
- | unused |
- | |
- | |
- |--------|
- | File 1 |
- \--------/ Lowest memory address
-
- WimpExtension provides a relocatable heap manager, however. This means that
- the heap manager is allowed to move the blocks about, to try and reduce the
- amount of wasted memory. In the situation above, for example, WimpExtension
- would move File 2 and File 3 down in memory, like so:
-
- /--------\ Highest memory address
- | File 2 |
- | |
- | |
- | |
- |--------|
- | File 3 |
- | |
- |--------|
- | File 1 |
- \--------/ Lowest memory address
-
- As you can see, this can save a lot of memory.
-
-
-
- Anchors
- -------
-
- The only disadvantage of a reloctable heap is due to the fact that it IS
- relocatable - the blocks of memory aren't fixed and may move about. A
- question which immediately arises is "How do I find my memory block?" - if
- the block may have moved, how do you find it?
-
- The answer is by using an "anchor". An anchor is a word in memory. The
- contents of this word is always a pointer to the start of the block. ie:
-
- /-------\
- | |
- /--------\ | |
- | anchor |--------->| block |
- \--------/ \-------/
-
- The anchor always stays fixed in the same place in memory, so you always know
- where to find it. So, to find the location of your block, you would use:
-
- block%=!anchor% : REM block% now points to the first byte in the block
-
- The anchors are stored all together at the beginning of the heap.
-
-
-
- Size of blocks
- --------------
-
- The word before the start of any block contains the size of the block in
- bytes. So to find the size of a block, you would use:
-
- size%=!(block%-4)
-
- or:
-
- size%=!( (!anchor%) -4)
-
- (because block%=!anchor%).
-
- Due to the way the heap manager works, the size of a block is always four
- plus a multiple of eight (ie. 12, 20, 28, etc.). If you ask WimpExtension to
- make a block with a size which isn't four plus a multiple of eight, then the
- size will be rounded up by between one and seven bytes, to take it to the
- next largest acceptable size.
-
-
-
- Initialising the heap
- ---------------------
-
- Before you can use any of the heap operations, you must initialise the heap.
- This requires two parameters - the number of anchors to create initially, and
- the address in memory of the base of the heap.
-
- The anchors are stored all together at the beginning of the heap. Because you
- need one anchor for every block in use, the number of anchors is effectively
- the maximum number of blocks you can have in use at any one time. You can
- create more anchors later, but it is best to create enough now, and then you
- don't have to worry about it later. Remember that anchors do take memory
- though, so don't go wild.
-
- For example:
-
- SYS "WimpExt_Heap",0,base%,anchors%
-
- Note that a heap which is empty (ie. no blocks are in use) takes absolutely
- no memory at all.
-
-
-
- Allocating blocks
- -----------------
-
- Whenever you ask WimpExtension to make you a new block (called "allocating" a
- block), it gives you a pointer to the anchor for that block. You must store
- the pointer to the anchor, NOT the pointer to the block, because the anchor
- will never move, but the block may do. For example, to ask WimpExtension for
- a block "size%" bytes long, you would use:
-
- SYS "WimpExt_Heap",2,,size% TO ,anchor%
-
- If WimpExtension cannot create the block, because there is not enough free
- memory, then the anchor returned will be zero. You need to check for this
- before writing anything into the block. eg:
-
- SYS "WimpExt_Heap",2,,size% TO ,anchor%
- IF anchor%=0 THEN ERROR 1,"Not enough free memory"
-
-
-
- Freeing blocks
- --------------
-
- When you have finished using a block, you use the "Free block" call to tell
- WimpExtension that you don't need the block any more, and the memory it takes
- up can be re-used. eg:
-
- SYS "WimpExt_Heap",3,anchor%
-
- or:
-
- SYS "WimpExt_Heap",3,block%
-
- The block will be added to WimpExtension's list of free blocks.
-
-
-
- Reallocating blocks
- -------------------
-
- Sometimes you will want to re-size a block - this is called "reallocating"
- the block. WimpExtension allows you to increase or decrease the size of any
- block at any time. eg:
-
- SYS "WimpExt_Heap",4,block%,new_size% TO ,flag%
-
- or:
-
- SYS "WimpExt_Heap",4,anchor%,new_size% TO ,flag%
-
- If the flag is zero on exit then the re-size failed because there wasn't
- enough free memory.
-
- Note that this call may cause the specified block to move in memory. Only the
- specific block that you are re-sizing can move, though - all the other blocks
- will stay where they are.
-
-
-
- Garbarge collection
- -------------------
-
- "Garbage collection" is the whole point of the relocatable heap. This is the
- process of shuffling the blocks about in memory, so that no memory is wasted.
- For example, if the heap was in the following state:
-
- /---------\ Highest memory address
- | block 2 |
- | |
- |---------|
- | free |
- | |
- | |
- |---------|
- | block 1 |
- \---------/ Lowest memory address
-
- then performing garbage collection would shuffle the blocks as follows:
-
- /---------\ Highest memory address
- | block 2 |
- | |
- |---------|
- | block 1 |
- \---------/ Lowest memory address
-
- This then allows WimpExtension to decrease your task's WimpSlot, thus making
- this memory available to any other programs which might need it.
-
- Two garbage collection calls are provided; the Tidy call:
-
- SYS "WimpExt_Heap",5
-
- and the Compact call:
-
- SYS "WimpExt_Heap",6
-
- The Tidy call just tidies the heap a little bit - the heap won't necessarily
- immediately be shuffled into the ideal position, but the call is usually
- quite fast. This call is intended to be called just before you call
- Wimp_Poll. If you set bit 3 of R2 when you called WimpExt_Initialise, then
- the heap will be automatically Tidied once a second, in WimpExt_PrePoll. Most
- of the time, you can just set this bit, and then forget all about garbage
- collection - it will all be handled for you.
-
- The Compact call tidies the heap completely - the heap will immediately be
- shuffled into the ideal position. This call is often slower than the Tidy
- call, however, as it does more work.
-
-
-
- How often should I tidy the heap?
- ---------------------------------
-
- How often you tidy the heap depends on the average size of the blocks your
- program uses. If your program uses lots of little blocks then you should tidy
- the heap quite often. If it uses a smaller number of larger blocks then you
- should tidy it less often.
-
- For a text editor, for example, the once-a-second tidy provided automatically
- should be fine. For something which uses smaller blocks, you should probably
- tidy the heap more often.
-
-
-
- Finding the anchor of a block
- -----------------------------
-
- If you have a pointer to a block, and you want to locate the block's anchor,
- then a call is provided to do this:
-
- SYS "WimpExt_Heap",7,block% TO ,anchor%
-
- An error is produced if block% is not a valid pointer to the start of a
- block.
-
-
-
- Fixing blocks
- -------------
-
- Sometimes you may want to temporarily 'fix' the heap. This makes it so that
- all the blocks are fixed and cannot move. This is useful if you need to rely
- on a block staying put at the same position in memory for a while.
-
- To fix the heap, you would use:
-
- SYS "WimpExt_Heap",8
-
- and to unfix it you would use:
-
- SYS "WimpExt_Heap",10
-
- Note that WimpExtension keeps a count of the number of times you haved fixed
- the heap, and only unfixes the heap when you tell it to the same number of
- times. ie:
-
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",10
-
- would leave the heap fixed. The following, however, would leave the heap
- unfixed, as the number of "unfixings" matches the number of "fixings":
-
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",10
- SYS "WimpExt_Heap",10
-
- You can force WimpExtension to unfix the heap straight away, regardless of
- the number of times it has been fixed, using the following call:
-
- SYS "WimpExt_Heap",9
-
- ie. The following would leave the heap unfixed:
-
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",8
- SYS "WimpExt_Heap",9
-
-
-
- Creating more anchors
- ---------------------
-
- WimpExtension allows you to create more anchors, even while the heap is in
- use. Note that this call has to move the entire heap up in memory, so it can
- be quite slow. For example:
-
- SYS "WimpExt_Heap",11,add%
-
- "add%" extra anchors will be created. All the blocks will be moved.
-
- WimpExtension also provides a call to allocate a block, automatically
- creating more anchors if you've run out:
-
- SYS "WimpExt_Heap",12,,size% TO ,anchor%
-
-
- Freeing all blocks
- ------------------
-
- WimpExtension provides a call to free all the blocks in the heap:
-
- SYS "WimpExt_Heap",13
-
- Every single allocated block will be freed, and all the memory released.
-
-
-
- Describing the heap
- -------------------
-
- WimpExtension provides a call which provides various bits of information
- about the heap:
-
- SYS "WimpExt_Heap",1 TO ,,largest%,free%,heapsize%,anchors%,blocks%
-
- largest% : The size of the largest continuous area of memory in the heap
- free% : The total amount of memory free in the heap
- heapsize% : The total amount of memory used by the heap
- anchors% : The number of anchors which have been created
- blocks% : The number of blocks which are currently allocated
-