Virtual Memory: 3.6 Using Virtual Memory: Accessing and Altering VM Blocks

Up: GEOS SDK TechDocs | Up | Prev: 3.5 Attaching Memory Blocks | Next: 3.7 VM Block Information
VMLock(), VMUnlock(), VMDirty(), VMFind(), VMModifyUserID(), VMPreserveBlocksHandle()

Once you have opened a VM file and allocated blocks, you will need to access blocks. The VM library provides many routines for doing this.

If you need to access the data in a VM file, you can use the routine VMLock() . This routine moves a VM block onto the global heap. It does this by allocating a global memory block (if the VM block is not already associated with a memory block), reallocating the global block if it had been discarded, locking the memory block on the global heap, and copying the VM block into the global block, if necessary. (It will copy the VM block to memory only if necessary, i.e. if the memory block is newly-allocated, or had been discarded and reallocated.) VMLock() takes three arguments: the handle of the VM file, the VMBlockHandle of the block to lock, and a pointer to a memHandle variable. It returns a pointer to the start of the block, and writes the global block's handle into the memHandle variable. You can now access the block the same way you would any other block, with one exception: When you are done with the block, you do not call MemUnlock() ; instead, call the routine VMUnlock() , passing it the handle of the global memory block (not the handle of the VM block). This will unlock the global block on the heap.

If you alter the global memory block, you will need to notify the VM manager of this so it will know to copy the changes back to the VM file. You do this by calling the routine VMDirty() . VMDirty() takes one argument, the handle of the global memory block ( not the VM block). It is important to dirty the block while it is still locked on the heap; as soon as you unlock a clean block, the VM manager may choose to discard it. Dirty blocks are copied back to the VM file when it is updated. Note that if an object in a VM block is marked dirty (via ObjMarkDirty() ), the block is automatically dirtied. Similarly, if you attach a global memory block to a VM block (via VMAttach() ), the VM block is automatically dirtied.

You can dynamically resize VM blocks. To do this, lock the VM block with VMLock() ; then resize the global memory block with MemReAlloc() . Be sure to mark the block dirty so the changes will be copied to the disk file. Note that although the global memory block will remain locked, it may move on the global heap when it is resized. You will therefore need to dereference the global memory handle (with MemDeref() ) before accessing the memory.

You can locate VM blocks by their user ID numbers. The routine VMFind() takes three arguments: the VM file handle, a VM block handle, and the user ID for which to look. The routine looks through the block table, starting with the handle after the one passed, until it finds a block with the specified user ID. If it does not find such a block, it returns a null handle; otherwise, it returns the block's VMBlockHandle. Thus, by passing in a block handle of zero, you will get the handle of the first block with the specified ID; by passing back in that block's handle, you will get the next block with that ID; and so on, until you get all the blocks (after which you will be returned a null handle).

You can change a block's user ID number by calling the routine VMModifyUserID() . This routine takes three arguments: the VM file handle, the VM block handle, and the new user ID number. Since user IDs are maintained in the block table, not in the blocks themselves, it doesn't matter whether the block is locked, or even whether it is associated with data in the file. (For example, a block allocated with a size of zero can have its user-ID changed.)

Ordinarily, the VM manager can free any unlocked, clean global block if the space is needed. However, you can instruct the VM manager not to free the global block associated with a specific block by calling the routine VMPreserveBlocksHandle() . The routine takes two arguments, namely the VM file handle and the VM block handle. It sees to it that the specified VM block will remain attached to the same global block until the VM block is specifically detached (or reattached).


Up: GEOS SDK TechDocs | Up | Prev: 3.5 Attaching Memory Blocks | Next: 3.7 VM Block Information