home *** CD-ROM | disk | FTP | other *** search
-
- Virtual Memory library
-
- V0.0 (The virtuosity is V0.0. The code is v1.2)
-
- by David Le Blanc (david@mlb.geomechanics.csiro.au)
-
- Functions in this library are designed for efficient use of a large number
- of memory allocation within or without memory constraints.
-
- =================== FILE STORAGE IMPLEMENTATION. ========================
-
- A single flat file is created and managed, in no special format.
-
- ======================== MEMORY MANAGEMENT. =============================
-
- After initialising, memory may be asked for with the function
- VM_AllocMem(). This function partitions off a chunk of file (whether
- appending to the file, or re-using a previously free'd block).
-
- Before using the memory, you must make sure it is mapped to physical
- memory. Doing this involves the VM_Lock() call, which will allocate
- memory and read the necessary file segment if needed.
-
- Once you are finished, you allow the VM routines to take control of the
- block by releasing it with the VM_UnLock() function call.
-
- While a segment is Lock'ed, it is guaranteed to NOT be flushed from memory
- while the inverse if NOT true. An UnLock'ed segment may remain in
- memory for as long as the VM routines feel it may be in use.
-
- Refinements. To explain the last statement, let me explain what happens
- when a Lock is UnLocked. The lock is placed on a 'Reserved' list, where
- it remains. If the list has grown to a maximum (currently 10 locks)
- the the oldest lock is flushed for real, (writing it to disk if needed),
- and marked INVALID.
-
- Since without an MMU it is impossible to know whether a particular memmory
- address has been changed, the function VM_ReadOnly() may be called on a
- lock to indicate that it is not going to be modified, and hence will
- not be written back to disk when flushed.
-
- The file allocation functions are very smart about where to squeeze blocks
- into a file. A request for a block will be placed into the smallest hole
- larger than the requested size. Freeing a block will automatically merge
- it with adjacent free blocks in the free pool.
-
- You may test the effectiveness of the reserved list method of caching
- by setting the maximum list length to zero, and checking just how much
- longer it takes to execute.
-
- If you write a program with this, changing the value of the maximum
- reserved list can greatly affect program performance, and should either
- be tuned to your program, or left open for the user to adjust depending
- on memory capacity and disk speed.
-
- This implementation makes it a tiny bit hard to manage linked lists unless
- you remember that it is acceptable to use pointers to the actual locks
- instead of the memory. Hence as you follow the list, you should call
- next = VM_Lock(ll->Next), then Unlock(ll). Depending on the size of the
- list, it may or may not spend a lot of time accessing the disk.
-
- Due to the overhead in terms of LOCKS and Reserved list caches etc, it
- would be very unwise to use this system for allocating blocks of under
- say about 2k. (3meg of 2K blocks approx 1500 blocks, hence the overhead
- would be about 1500*sizeof(lock) (+ 10 * 2k reserved list). or just over
- 60K overhead. (for 3meg, not too bad... Just use large memory allocations)
-
- OH ALMOST FORGOT. These routines are hard wired to use my resource tracking
- library 'track.library'. You MUST declare TrackBase, and
- open track.library to be able to use these functions.
- (You also require track.h for prototypes (supplied))
- For more info on track.library, mail me, or look for
- tracklib.lzh on AB20.
- NOTE that the track.library support is for debugging
- purposes, and can be removed painlessly.
-
- NOTE: The idea and functionality of the caching is stolen from the paging
- algorithm used by the good old VAX. As locks are used then freed,
- they go to the head of the 'reserved' list. Only the oldest lock is
- actually ever flushed. This allows for a amount of time saving where
- an unlocked memory allocation is re-locked within a certain amount of
- time, ie before it is ever actually written to disk, hence saving the
- cost of memory allocations, seeking, writing and reading. Note that
- it is a given that the caching code executes at LEAST and order of
- magnitude faster than a single disk access.
-
- ============================ DISCLAIMER. ================================
-
- I DO NOT GUARANTEE THAT THIS CODE WORKS PERFECTLY AS PERFORMED, although
- If you find problems be sure to throw them at me.
-
- I ACCEPT NO RESPONSIBILITY FOR DAMAGE CAUSED DIRECTLY OR INDIRECTLY BY
- THIS CORRECT OR INCORRECT USE OF THIS PACKAGE.
-
- If you can read the source code, then I had better stop writing comments.
-
- =========================== LIMITATIONS. ================================
-
- Currently the only limitations are that a single memory segment MUST fit
- within your physical memory, AND that memory can be allocated whether
- there is filesystem space to hold it or not!
-
- ========================== IMPLEMENTATION. ==============================
-
- =========================================================================
-
- FUNCTION
-
- struct VM_Construct *VM_Open(char *VM_Filename) ;
-
- INPUTS
-
- VM_Filename : filename to use as the virtual memory file.
-
- RETURNS
-
- A pointer to a VM_Construct structure.
-
- NOTES
-
- This will fail if it runs out of memory, or the file cannot be
- created. A NULL pointer is returned on failure.
-
- =========================================================================
-
- FUNCTION
-
- ULONG VM_Close(struct VM_Construct *VM_C) ;
-
- INPUTS
-
- The VM_Construct structure returned from VM_Open().
-
- RETURNS
-
- An Error is returned (-1).
-
- NOTES
-
- This function will return FAIL if it cannot flush all locks on
- the reserved list, and close the file.
-
- =========================================================================
-
- FUNCTION
-
- struct VM_Lock *VM_AllocMem(struct VM_Construct *VM_C, LONG Size) ;
-
- INPUTS
-
- VM_C : The VM_Construct structure returned from VM_Open().
- Size : The size of the memory segment wanted.
-
- RETURNS
-
- struct VM_Lock. A pointer to a lock structure that can be used
- with VM_Lock() and VM_UnLock().
-
- NOTES
-
- This will fail on a lack of memory.
-
- =========================================================================
-
- FUNCTION
-
- ULONG VM_FreeMem(struct VM_Lock *VM_L) ;
-
- INPUTS
-
- VM_L : The VM_Lock structure returned by VM_AllocMem()
-
- RETURNS
-
- Zero is returned on success.
-
- NOTES
-
- This function may fail (and return -1) if it is unable to flush
- the lock. It will, in general, UnLock any currently Lock'ed locks
- before freeing them.
-
- =========================================================================
-
- FUNCTION
-
- void *VM_Lock(struct VM_Lock *VM_L) ;
-
- INPUTS
-
- VM_L : The VM_Lock structure returned by VM_AllocMem()
-
- RETURNS
-
- A (void *) pointer to the memory that has been allocated and locked
- for you!
-
- Note, this pointer is equivalent to VM_L->VM_Addr (Now don't you go
- and use VM_L->VM_Addr without first locking it! That would be
- naughty)
-
- NOTES
-
- The will fail if memory is not available for the segment, or if the
- seek to the correct position in the file (or the read) fails.
-
- =========================================================================
-
- FUNCTION
-
- ULONG VM_UnLock(struct VM_Lock *VM_L) ;
-
- INPUTS
-
- VM_L : The VM_Lock structure returned by VM_AllocMem()
-
- RETURNS
-
- Zero is returned on success.
-
- NOTES
-
- This function will fail if it tries to flush a lock (either the one
- you passed, or an old one from the reserved list) and cannot seek
- or write successfully.
-
- =========================================================================
-
- FUNCTION
-
- void VM_ReadOnly(struct VM_Lock *VM_L) ;
-
- INPUTS
-
- VM_L : The VM_Lock structure returned by VM_AllocMem()
-
- RETURNS
-
- None.
-
- NOTES
-
- This function sets the 'ReadOnly' flag in the lock, so that when the
- lock is next UnLocked it will not be written to file. Note that the
- lock may still be placed on the reserved list, to prevent it being
- re-read.
-
- =========================================================================
-
-