home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *+
- ** Module Name: Vmm.C
- **
- ** Description: Virtual Memory Manager
- **
- ** Supports limited virtual memory management.
- **
- ** Performs cacheing of data and swapping to/from disk file.
- **
- **
- ** Written by: John Tal
- **
- **
- **
- ** Modification History:
- **
- ** Date Programmer Mod# Modification
- ** ---------------------------------------------------------------------------
- ** 17-FEB-1992 J. Tal V1.0-000 New
- **
- *-
- */
-
- #ifdef C_ANSI
- #include <string.h>
- #include <stdlib.h>
- #endif
-
- #ifdef C_UNIX
- #include <sys/types.h>
- #endif
-
- #include <time.h>
-
- #include <stdio.h>
-
- #include <memlib.h>
-
- #include <vmm.h>
-
-
-
- VMM_MGR_T stVmmMgr;
- VMM_MGR_P pstVmmMgr = &stVmmMgr;
-
-
-
- /*
- ** VmmInit
- **
- ** Initialize virtual memory manager
- */
-
- #ifdef C_ANSI
- SHORT
- VmmInit(SHORT sMemoryBytes,PCHAR pcSwapFile)
- #else
- SHORT
- VmmInit(sMemoryBytes,pcSwapFile)
- SHORT sMemoryBytes;
- PCHAR pcSwapFile;
- #endif
- {
- C_DEF_MODULE("VmmInit")
-
- static BOOL fVmmInit;
- VMM_BLOCK_P pstNewBlock;
-
- if(fVmmInit)
- C_LEAVE(VMM_ERR_INIT)
-
- memset(&stVmmMgr,0,sizeof(VMM_MGR_T));
-
- pstVmmMgr -> pvBlock = (PVOID) calloc(sMemoryBytes,1);
- pstVmmMgr -> lTotalBytes = sMemoryBytes;
- pstVmmMgr -> lSwapBytes = 0;
-
- if(pstVmmMgr -> pvBlock == NULL)
- C_LEAVE(VMM_ERR_MEM_EXCEEDED)
-
- strcpy(pstVmmMgr -> szSwapFile,pcSwapFile);
-
-
- pstVmmMgr -> fpSwapFile = fopen(pstVmmMgr -> szSwapFile,"w+b");
-
- if(pstVmmMgr -> fpSwapFile == NULL)
- C_LEAVE(VMM_ERR_INIT)
-
-
- /* create logical block for all of memory */
-
- C_STATUS = VmmCreateBlock(VMM_MEMORY,sMemoryBytes,VMM_OWNER_NONE,pstVmmMgr -> pvBlock,0L,&pstNewBlock);
-
-
- if(pstVmmMgr -> fpSwapFile == NULL)
- C_LEAVE(VMM_ERR_SWAP_FILE)
-
- fVmmInit = C_TRUE;
-
- C_MODULE_EXIT:
-
- C_RETURN
- }
-
-
- /*
- ** VmmCompress
- **
- ** Compress Internal memory. Called when there is enough space
- ** but not in a single continuous block.
- */
-
- #ifdef C_ANSI
- SHORT
- VmmCompress(VOID)
- #else
- SHORT
- VmmCompress()
- #endif
- {
- C_DEF_MODULE("VmmCompress")
-
- VMM_BLOCK_P pstNewBlock;
- VMM_BLOCK_P pstBlock;
- PVOID pvNewBlock;
- PVOID pvPtr;
- LLIST_P pstMember;
- LONG lUseBytes = 0;
- LONG lRemBytes;
- LLIST_P pstMemberNext;
-
- /* get new block of memory */
-
- pvNewBlock = (PVOID) calloc(1,(SHORT) pstVmmMgr -> lTotalBytes);
-
- if(pvNewBlock == NULL)
- C_LEAVE(VMM_ERR_MEM_EXCEEDED)
-
- pvPtr = pvNewBlock;
-
- /* look at all memory blocks */
-
- pstMember = pstVmmMgr -> pstMemList;
-
- while(pstMember != NULL)
- {
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- pstMemberNext = pstMember -> psNext;
-
- /* if active, copy into new master block
- reset block pointer
- increment current pointer into new block
- increment used bytes
- */
-
- if(pstBlock -> sOwner != VMM_OWNER_NONE)
- {
- if(pstBlock -> sState == VMM_STATE_MEMORY)
- {
- /* retain by copying into new master bloc */
-
- memcpy(pvPtr,pstBlock -> pvBlock, pstBlock -> sBytes);
- pstBlock -> pvBlock = pvPtr;
- pvPtr = (PVOID) ((long) pvPtr + (long) pstBlock -> sBytes);
- lUseBytes += pstBlock -> sBytes;
- }
- }
- else
- {
- /* free block and remove control list member */
-
- free(pstBlock);
-
- MemLstDeleteMember(pstVmmMgr -> pstMemList,
- pstMember,
- &(pstVmmMgr -> pstMemList));
-
- }
-
- pstMember = pstMemberNext;
- }
-
- /* free old block and make Vmm point to new */
-
- free(pstVmmMgr -> pvBlock);
- pstVmmMgr -> pvBlock = pvNewBlock;
-
- lRemBytes = pstVmmMgr -> lTotalBytes - lUseBytes;
-
-
- C_STATUS = VmmCreateBlock((SHORT) VMM_MEMORY,
- (SHORT) lRemBytes,
- (SHORT) VMM_OWNER_NONE,
- pvPtr,
- (LONG) 0,
- &pstNewBlock);
-
- C_MODULE_EXIT:
-
- ;
-
- C_RETURN
- }
-
-
-
-
- /*
- ** VmmAlloc - Process wants a memory block
- */
-
- #ifdef C_ANSI
- SHORT
- VmmAlloc(SHORT sOwner,SHORT sTotalBytes,PLONG plHandle)
- #else
- SHORT
- VmmAlloc(sOwner,sTotalBytes,plHandle)
- SHORT sOwner;
- SHORT sTotalBytes;
- PLONG plHandle;
- #endif
- {
- C_DEF_MODULE("VmmAlloc")
-
- VMM_BLOCK_P pstBlock = (VMM_BLOCK_P) NULL;
-
-
- if((LONG) sTotalBytes > pstVmmMgr -> lTotalBytes)
- C_LEAVE(VMM_ERR_MEM_EXCEEDED)
-
- while(pstBlock == NULL)
- {
- VmmAssignBlock(VMM_MEMORY,sTotalBytes,sOwner,&pstBlock);
- if(pstBlock == NULL)
- VmmSizeSwapToDisk(sTotalBytes,sOwner,&pstBlock);
- }
-
- /* update access time */
-
- pstBlock -> lTimeLastAccess = VmmCurTime();
-
-
- *plHandle = pstBlock -> lDescriptor;
-
- C_MODULE_EXIT:
-
- ;
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmPrep
- **
- ** Setup Memory block before access to ensure is in memory
- ** Also call before each access to update access times used
- ** in cacheing decisions.
- */
-
- #ifdef C_ANSI
- SHORT
- VmmPrep(LONG lHandle,PPVOID ppvVirtualPtr)
- #else
- SHORT
- VmmPrep(lHandle,ppvVirtualPtr)
- LONG lHandle;
- PPVOID ppvVirtualPtr;
- #endif
- {
-
- C_DEF_MODULE("VmmPrep")
-
- LLIST_P pstMember;
- VMM_BLOCK_P pstVmmBlock;
-
- MemLstFindMember(pstVmmMgr -> pstMemList,
- (PVOID) &lHandle,
- VmmCompareHandle,
- &pstMember);
-
- if(pstMember != NULL)
- {
- pstVmmBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if(pstVmmBlock -> sState == VMM_STATE_DISK)
- {
- pstVmmMgr -> pstReloadBlock = pstVmmBlock;
-
- VmmLoadFromDisk(pstVmmBlock,pstVmmBlock -> sOwner);
-
- pstVmmMgr -> pstReloadBlock = (VMM_BLOCK_P) NULL;
-
- }
-
- /* update access time */
-
- pstVmmBlock -> lTimeLastAccess = VmmCurTime();
-
- *ppvVirtualPtr = pstVmmBlock -> pvBlock;
-
- }
-
- C_RETURN
- }
-
-
- /*
- ** VmmFree
- **
- ** Process is freeing an allocated block
- */
-
- #ifdef C_ANSI
- SHORT
- VmmFree(LONG lDescriptor)
- #else
- SHORT
- VmmFree(lDescriptor)
- LONG lDescriptor;
- #endif
- {
- C_DEF_MODULE("VmmFree")
-
- LLIST_P pstMember;
- VMM_BLOCK_P pstBlock;
-
- pstMember = pstVmmMgr -> pstMemList;
-
- while(pstMember != NULL)
- {
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if(pstBlock -> lDescriptor == lDescriptor)
- {
- pstBlock -> sOwner = VMM_OWNER_NONE;
-
- /* take care of disk block if swapped out */
-
- if(pstBlock -> pstMate != NULL)
- {
- pstBlock -> pstMate -> sOwner = VMM_OWNER_NONE;
- }
-
- break;
- }
-
- pstMember = pstMember -> psNext;
- }
-
-
- if(pstMember == NULL)
- C_SET_STATUS(C_NOTOK)
-
- C_RETURN
- }
-
-
- /*
- ** VmmTerm
- **
- ** Terminate Small Memory Manager
- */
-
- #ifdef C_ANSI
- SHORT VmmTerm(VOID)
- #else
- SHORT VmmTerm()
- #endif
- {
- C_DEF_MODULE("VmmTerm")
-
-
- LLIST_P pstMember;
- LLIST_P pstMemberNext;
- VMM_BLOCK_P pstBlock;
-
-
- fclose(pstVmmMgr -> fpSwapFile);
-
-
- /* free main memory block */
-
- free(pstVmmMgr -> pvBlock);
-
-
- /* free all sub-alloc memory blocks */
-
- pstMember = pstVmmMgr -> pstMemList;
-
- while(pstMember != NULL)
- {
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- pstMemberNext = pstMember -> psNext;
-
- free(pstBlock);
-
- pstMember = pstMemberNext;
- }
-
-
-
- /* free all disk swap blocks */
-
- pstMember = pstVmmMgr -> pstFreeDiskBlocks;
-
- while(pstMember != NULL)
- {
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- pstMemberNext = pstMember -> psNext;
-
- free(pstBlock);
-
- pstMember = pstMemberNext;
- }
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmLoadFromDisk
- **
- ** A block has been swapped to disk, load it back into memory
- */
-
- #ifdef C_ANSI
- SHORT
- VmmLoadFromDisk(VMM_BLOCK_P pstVmmBlock,SHORT sOwner)
- #else
- SHORT
- VmmLoadFromDisk(pstVmmBlock,sOwner)
- VMM_BLOCK_P pstVmmBlock;
- SHORT sOwner;
- #endif
- {
- C_DEF_MODULE("VmmLoadFromDisk")
-
- VMM_BLOCK_P pstBlock = NULL;
-
-
-
- while(pstBlock == NULL)
- {
- VmmAssignBlock(VMM_MEMORY,pstVmmBlock -> sBytes,sOwner,&pstBlock);
- if(pstBlock == NULL)
- VmmSizeSwapToDisk(pstVmmBlock -> sBytes,sOwner,&pstBlock);
- }
-
-
- if(pstBlock != pstVmmBlock)
- {
- /* problem here, another block has been created, must merge two
- together. All we really need is the pvBlock ptr */
-
- pstVmmBlock -> pvBlock = pstBlock -> pvBlock;
-
- /* remove newly created block */
- VmmVanishBlock(VMM_MEMORY,pstBlock);
- }
-
-
- fseek(pstVmmMgr -> fpSwapFile,
- pstVmmBlock -> lOffset,
- 0);
-
- fread(pstVmmBlock -> pvBlock,
- 1,
- pstVmmBlock -> sBytes,
- pstVmmMgr -> fpSwapFile);
-
- pstVmmBlock -> sState = VMM_STATE_MEMORY;
-
-
- /* free up disk block for other use */
-
- if(pstVmmBlock -> pstMate != NULL)
- {
- pstVmmBlock -> pstMate -> sOwner = VMM_OWNER_NONE;
- pstVmmBlock -> pstMate = NULL;
- }
-
- C_RETURN
- }
-
-
- /*
- ** VmmVanishBlock
- **
- ** A new block has been created during processing and is not needed
- ** (pvBlock was probably copied before this call)
- */
-
- #ifdef C_ANSI
- SHORT
- VmmVanishBlock(SHORT sType,VMM_BLOCK_P pstVanishBlock)
- #else
- SHORT
- VmmVanishBlock(sType,pstVanishBlock)
- SHORT sType;
- VMM_BLOCK_P pstVanishBlock;
- #endif
- {
- C_DEF_MODULE("VmmVanishBlock")
-
- LLIST_P pstMember;
- VMM_BLOCK_P pstBlock;
-
- if(sType == VMM_STATE_MEMORY)
- pstMember = pstVmmMgr -> pstMemList;
- else
- pstMember = pstVmmMgr -> pstFreeDiskBlocks;
-
- while(pstMember != NULL)
- {
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if(pstBlock == pstVanishBlock)
- {
- if(sType == VMM_MEMORY)
- {
- C_STATUS = MemLstDeleteMember(pstVmmMgr -> pstMemList,
- pstMember,
- &(pstVmmMgr -> pstMemList));
- }
- else
- {
- C_STATUS = MemLstDeleteMember(pstVmmMgr -> pstFreeDiskBlocks,
- pstMember,
- &(pstVmmMgr -> pstFreeDiskBlocks));
- }
-
- break;
- }
-
- pstMember = pstMember -> psNext;
-
- }
-
-
- free(pstVanishBlock);
-
- C_RETURN
- }
-
-
- /*
- ** VmmCheckFreeBlocks
- **
- ** Check total bytes available across all free fragments
- */
-
- #ifdef C_ANSI
- SHORT
- VmmCheckFreeBlocks(SHORT * pAvail)
- #else
- SHORT
- VmmCheckFreeBlocks(pAvail)
- SHORT * pAvail;
- #endif
- {
- C_DEF_MODULE("VmmCheckFreeBlocks")
-
- LLIST_P pstMember;
- VMM_BLOCK_P pstBlock;
- SHORT sFreeBytes = 0;
-
- pstMember = pstVmmMgr -> pstMemList;
-
- /* find oldest available block */
-
- while(pstMember != NULL)
- {
- /* if unused block, count it */
-
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if((pstBlock -> sOwner == VMM_OWNER_NONE) &&
- (pstBlock -> sState == VMM_STATE_MEMORY))
- {
- sFreeBytes += pstBlock -> sBytes;
- }
-
- pstMember = pstMember -> psNext;
-
- }
-
- *pAvail = sFreeBytes;
-
- return(C_OK);
- }
-
-
- /*
- ** VmmFindStaleBlock
- */
-
- #ifdef C_ANSI
- SHORT
- VmmFindStaleBlock(VMM_BLOCK_P * ppstRetBlock)
- #else
- SHORT
- VmmFindStaleBlock(ppstRetBlock)
- VMM_BLOCK_P * ppstRetBlock;
- #endif
- {
- C_DEF_MODULE("VmmFindStaleBlock")
-
- LLIST_P pstMember;
- LLIST_P pstMemberNext;
-
- VMM_BLOCK_P pstBlock;
- VMM_BLOCK_P pstOldBlock = (VMM_BLOCK_P) NULL;
- LONG lTimeLastAccess;
-
-
- lTimeLastAccess = VmmCurTime();
-
- *ppstRetBlock = (VMM_BLOCK_P) NULL;
-
- pstMember = pstVmmMgr -> pstMemList;
-
- /* find oldest available block */
-
- while(pstMember != NULL)
- {
- pstMemberNext = pstMember -> psNext;
-
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if((pstBlock -> sOwner != VMM_OWNER_NONE) &&
- (pstBlock -> sState != VMM_STATE_DISK))
- {
- if(pstBlock -> lTimeLastAccess <= lTimeLastAccess)
- {
- pstOldBlock = pstBlock;
- lTimeLastAccess = pstBlock -> lTimeLastAccess;
- }
- }
-
- pstMember = pstMemberNext;
- }
-
- *ppstRetBlock = pstOldBlock;
-
- return(C_OK);
- }
-
-
-
- /*
- ** VmmAssignBlock
- **
- ** Find and assign a block for either memory or disk allocation
- ** Can return NULL in the return block if none found
- */
-
- #ifdef C_ANSI
- SHORT
- VmmAssignBlock(SHORT sType,
- SHORT sBlockSize,
- SHORT sOwner,
- VMM_BLOCK_P * ppstRetBlock)
- #else
- SHORT
- VmmAssignBlock(sType,
- sBlockSize,
- sOwner,
- ppstRetBlock)
- SHORT sType;
- SHORT sBlockSize;
- SHORT sOwner;
- VMM_BLOCK_P * ppstRetBlock;
- #endif
- {
- C_DEF_MODULE("VmmAssignBlock")
-
- LLIST_P pstMember;
- LLIST_P pstMemberNext;
- LLIST_P pstMemberBlock;
-
- VMM_BLOCK_P pstBlock;
- BOOL fFoundBlock = C_FALSE;
- SHORT sByteDiff;
-
-
- VMM_BLOCK_P pstSmallBlock = (VMM_BLOCK_P) NULL;
- SHORT sSmallBytes = 0;
-
- *ppstRetBlock = (VMM_BLOCK_P) NULL;
-
- if(sType == VMM_STATE_MEMORY)
- pstMember = pstVmmMgr -> pstMemList;
- else
- pstMember = pstVmmMgr -> pstFreeDiskBlocks;
-
- /* find smallest available block */
-
- while(pstMember != NULL)
- {
- pstMemberNext = pstMember -> psNext;
-
- pstBlock = (VMM_BLOCK_P) pstMember -> pvData;
-
- if((pstBlock -> sOwner == VMM_OWNER_NONE) &&
- (pstBlock -> sBytes >= sBlockSize))
- {
- if(pstBlock -> sBytes == sBlockSize) /* exact match */
- {
- pstMemberBlock = pstMember;
- pstSmallBlock = pstBlock;
- sSmallBytes = pstBlock -> sBytes;
- break;
- }
-
- /* initialize for first block found >= required size */
-
- if(sSmallBytes == 0)
- {
- pstMemberBlock = pstMember;
- pstSmallBlock = pstBlock;
- sSmallBytes = pstBlock -> sBytes;
- }
- }
-
- pstMember = pstMemberNext;
- }
-
-
- /* found candidate block */
-
- if(pstSmallBlock != NULL)
- {
- fFoundBlock = C_TRUE;
-
- pstBlock = pstSmallBlock;
-
- /* check if must split */
-
- sByteDiff = pstBlock -> sBytes - sBlockSize;
-
- if(sByteDiff > 0)
- {
- /* split current block into two */
-
- VmmSplitBlock(sType,pstBlock,sOwner,sBlockSize,ppstRetBlock);
- }
- else
- {
- /* found exact match */
-
- if(pstVmmMgr -> pstReloadBlock != NULL)
- {
- /* if reloading from disk, remove this empty block */
-
- pstVmmMgr -> pstReloadBlock -> pvBlock = pstBlock -> pvBlock;
-
- /* different handling for disk vs memory */
-
- if(sType == VMM_DISK)
- {
- /* if disk, am reusing block out there */
-
- pstBlock -> sOwner = sOwner;
-
- *ppstRetBlock = pstBlock;
- }
- else
- {
- /* if memory, a new block will be thrown away,
- Reloading into existing block = ReloadBlock */
-
- *ppstRetBlock = pstVmmMgr -> pstReloadBlock;
- free(pstBlock);
-
- MemLstDeleteMember(pstVmmMgr -> pstMemList,
- pstMemberBlock,
- &(pstVmmMgr -> pstMemList));
-
- }
-
- }
- else
- {
- pstBlock -> sOwner = sOwner;
-
- *ppstRetBlock = pstBlock;
- }
- }
-
- }
-
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmSizeSwapToDisk
- **
- ** Need sBytes of room for memory, swap whatever it takes
- */
-
- #ifdef C_ANSI
- SHORT
- VmmSizeSwapToDisk(SHORT sBytes,SHORT sOwner,VMM_BLOCK_P * ppstBlock)
- #else
- SHORT
- VmmSizeSwapToDisk(sBytes,sOwner,ppstBlock)
- SHORT sBytes;
- SHORT sOwner;
- VMM_BLOCK_P * ppstBlock;
- #endif
- {
- C_DEF_MODULE("VmmSizeSwapToDisk")
-
- LLIST_P pstMember;
- VMM_BLOCK_P pstBlock;
-
- SHORT sAvailBytes = 0; /* total available bytes in memory block */
- SHORT sByte2 = 0;
- SHORT sEnoughBytes = 0; /* size of available contingous block */
-
- VMM_BLOCK_P pstEnoughBlock; /* the block itself */
- VMM_BLOCK_P pstNewBlock;
-
-
- *ppstBlock = (VMM_BLOCK_P) NULL;
-
- pstMember = pstVmmMgr -> pstMemList;
-
- while(sAvailBytes < sBytes)
- {
- VmmFindStaleBlock(&pstBlock); /* find oldest block to swap out */
-
- if(pstBlock == NULL)
- {
- VmmCheckFreeBlocks(&sByte2);
- sAvailBytes += sByte2;
- if(sAvailBytes >= sBytes)
- break;
- }
-
- VmmSwapToDisk(pstBlock,sOwner); /* move block out to swap */
- sAvailBytes += pstBlock -> sBytes; /* increment available */
-
- if(pstBlock -> sBytes >= sBytes) /* see if big enough */
- {
- if(sEnoughBytes == 0)
- {
- sEnoughBytes = pstBlock->sBytes;
- pstEnoughBlock = pstBlock;
- }
- else if(pstBlock->sBytes < sEnoughBytes) /* remember smallest */
- {
- sEnoughBytes = pstBlock->sBytes;
- pstEnoughBlock = pstBlock;
- }
- }
-
- }
-
-
-
- /* have swapped out everything to get available memory */
-
- if(sAvailBytes >= sBytes)
- {
- if(sEnoughBytes < sBytes) /* enough, but not contiguous, re-organize */
- VmmCompress();
- else
- {
- if(sEnoughBytes == sBytes) /* exact match on size */
- {
- VmmCreateBlock((SHORT) VMM_MEMORY,
- sBytes,
- sOwner,
- pstEnoughBlock -> pvBlock, /* re-use memory */
- 0L,
- &pstNewBlock);
-
- *ppstBlock = pstNewBlock;
-
- }
- else
- {
- /* too big, break off a chunk */
-
- VmmSplitBlock((SHORT) VMM_MEMORY,
- pstEnoughBlock,
- sOwner,
- sBytes,
- ppstBlock);
- }
-
- }
- }
- else
- C_SET_STATUS(C_NOTOK);
-
- C_RETURN
- }
-
-
- /*
- ** VmmSwapToDisk
- **
- ** A specific block must be swapped to disk.
- ** Locate an available disk block large enough or create one.
- */
-
- #ifdef C_ANSI
- SHORT
- VmmSwapToDisk(VMM_BLOCK_P pstVmmBlock,SHORT sOwner)
- #else
- SHORT
- VmmSwapToDisk(pstVmmBlock,sOwner)
- VMM_BLOCK_P pstVmmBlock;
- SHORT sOwner;
- #endif
- {
- C_DEF_MODULE("VmmSwapToDisk")
-
- VMM_BLOCK_P pstBlock = NULL;
-
-
- /* try and find existing vacant disk block to use */
-
- VmmAssignBlock(VMM_DISK,pstVmmBlock -> sBytes,sOwner,&pstBlock);
-
- /* if none, create new one */
-
- if(pstBlock == NULL)
- {
- VmmCreateDiskBlock(pstVmmBlock -> sBytes,&pstBlock);
- pstBlock -> sOwner = sOwner;
- pstBlock -> lDescriptor = pstVmmBlock -> lDescriptor;
-
- }
-
-
- /* remember disk block so can remove ownership
- when swapped back to memory */
-
- pstVmmBlock -> pstMate = pstBlock;
-
-
-
- /* give block in memory chain same offset as block in disk chain */
- pstVmmBlock -> lOffset = pstBlock -> lOffset;
-
-
- fseek(pstVmmMgr -> fpSwapFile,
- pstVmmBlock -> lOffset,
- 0);
-
- fwrite(pstVmmBlock -> pvBlock,
- 1,
- pstVmmBlock -> sBytes,
- pstVmmMgr -> fpSwapFile);
-
- pstVmmBlock -> sState = VMM_STATE_DISK;
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmCreateDiskBlock
- **
- ** Create a new disk block of a given size
- */
-
- #ifdef C_ANSI
- SHORT
- VmmCreateDiskBlock(SHORT sBytes,VMM_BLOCK_P * ppstBlock)
- #else
- SHORT
- VmmCreateDiskBlock(sBytes,ppstBlock)
- SHORT sBytes;
- VMM_BLOCK_P * ppstBlock;
- #endif
- {
- C_DEF_MODULE("VmmCreateDiskBlock")
-
- VMM_BLOCK_P pstBlock;
- LLIST_P pstMember;
-
- pstBlock = (VMM_BLOCK_P) calloc(1,sizeof(VMM_BLOCK_T));
-
- pstBlock -> sBytes = sBytes;
- pstBlock -> sOwner = VMM_OWNER_NONE;
- pstBlock -> sState = VMM_DISK;
- pstBlock -> lOffset = pstVmmMgr -> lSwapBytes;
-
- pstVmmMgr -> lSwapBytes += (LONG) sBytes;
-
-
- MemLstAllocMember(&pstMember);
-
- pstMember -> pvData = (PVOID) pstBlock;
-
- MemLstInsertMember(pstVmmMgr -> pstFreeDiskBlocks,
- pstMember,
- VmmCompareBlockSize,
- &(pstVmmMgr -> pstFreeDiskBlocks));
-
-
- *ppstBlock = pstBlock;
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmSplitBlock
- **
- ** Split an existing block which is larger than needed into 2 blocks
- ** One will be the exact size needed, the remaining bytes will be
- ** allocated from a new block.
- */
-
- #ifdef C_ANSI
- SHORT
- VmmSplitBlock(SHORT sType,
- VMM_BLOCK_P pstOrigBlock,
- SHORT sOwner,
- SHORT sBlockSize,
- VMM_BLOCK_P *ppstNewBlock)
- #else
- SHORT
- VmmSplitBlock(sType,
- pstOrigBlock,
- sOwner,
- sBlockSize,
- ppstNewBlock)
- SHORT sType;
- VMM_BLOCK_P pstOrigBlock;
- SHORT sOwner;
- SHORT sBlockSize;
- VMM_BLOCK_P *ppstNewBlock;
- #endif
- {
- C_DEF_MODULE("VmmSplitBlock")
-
- SHORT sRemBytes;
- PVOID pvPtr;
- LONG lOffset;
-
-
- /* find size of remaining/new block */
-
- sRemBytes = pstOrigBlock -> sBytes - sBlockSize;
-
- /* calc new/reduced size of original block */
-
- pstOrigBlock -> sBytes = sRemBytes;
-
- if(sType == VMM_MEMORY)
- {
- pvPtr = (PVOID) ( (LONG) pstOrigBlock -> pvBlock +
- (LONG) sRemBytes);
-
- if(pstVmmMgr -> pstReloadBlock != NULL)
- {
- pstVmmMgr -> pstReloadBlock -> pvBlock = pvPtr;
- *ppstNewBlock = pstVmmMgr -> pstReloadBlock;
- }
- else
- VmmCreateBlock(sType,sBlockSize,sOwner,pvPtr,0L,ppstNewBlock);
- }
- else
- {
- lOffset = pstOrigBlock -> lOffset + sBlockSize;
-
- VmmCreateBlock(sType,sBlockSize,sOwner,(PVOID) 0,lOffset,ppstNewBlock);
- }
-
- C_RETURN
-
- }
-
-
- /*
- ** VmmCreateBlock
- **
- ** Create a new block (either disk or memory).
- ** Either the lOffset or pvPtr will be assigned
- */
-
- #ifdef C_ANSI
- SHORT VmmCreateBlock(SHORT sType,
- SHORT sBlockSize,
- SHORT sOwner,
- PVOID pvPtr,
- LONG lOffset,
- VMM_BLOCK_P * ppstNewBlock)
- #else
- SHORT VmmCreateBlock(sType,
- sBlockSize,
- sOwner,
- pvPtr,
- lOffset,
- ppstNewBlock)
- SHORT sType;
- SHORT sBlockSize;
- SHORT sOwner;
- PVOID pvPtr;
- LONG lOffset;
- VMM_BLOCK_P * ppstNewBlock;
- #endif
- {
- C_DEF_MODULE("VmmCreateBlock")
-
- VMM_BLOCK_P pstBlock;
- LLIST_P pstMember;
-
-
- pstBlock = (VMM_BLOCK_P) calloc(1,sizeof(VMM_BLOCK_T));
-
-
- pstBlock -> lDescriptor = pstVmmMgr -> lDescriptor;
-
- pstVmmMgr -> lDescriptor++;
-
-
- pstBlock -> sBytes = sBlockSize;
- pstBlock -> sOwner = sOwner;
- pstBlock -> sState = sType;
-
- pstBlock -> lTimeLastAccess = VmmCurTime();
-
- if(sType = VMM_MEMORY)
- pstBlock -> pvBlock = pvPtr;
- else
- pstBlock -> lOffset = lOffset;
-
-
- MemLstAllocMember(&pstMember);
-
- pstMember -> pvData = (PVOID) pstBlock;
-
- if(sType == VMM_DISK)
- {
- MemLstInsertMember(pstVmmMgr -> pstFreeDiskBlocks,
- pstMember,
- VmmCompareBlockSize,
- &(pstVmmMgr -> pstFreeDiskBlocks));
- }
- else
- {
- MemLstInsertMember(pstVmmMgr -> pstMemList,
- pstMember,
- VmmCompareBlockSize,
- &(pstVmmMgr -> pstMemList));
- }
-
-
- *ppstNewBlock = pstBlock;
-
- C_RETURN
- }
-
-
-
- /*
- ** VmmCompareBlockSize
- **
- ** Compare function for use by MemLst for comparing memory blocks
- */
-
- #ifdef C_ANSI
- SHORT
- VmmCompareBlockSize(PVOID pvData1, PVOID pvData2)
- #else
- SHORT
- VmmCompareBlockSize(pvData1,pvData2)
- PVOID pvData1;
- PVOID pvData2;
- #endif
- {
- VMM_BLOCK_P pstBlock1;
- VMM_BLOCK_P pstBlock2;
-
-
- pstBlock1 = (VMM_BLOCK_P) pvData1;
- pstBlock2 = (VMM_BLOCK_P) pvData2;
-
- if(pstBlock1 -> sBytes == pstBlock2 -> sBytes)
- return(0);
- else if(pstBlock1 -> sBytes > pstBlock2 -> sBytes)
- return(-1);
- else
- return(1);
-
- }
-
-
- /*
- ** VmmCompareHandle
- **
- ** Compare function for use by MemLst for comparing memory blocks
- */
-
- #ifdef C_ANSI
- SHORT
- VmmCompareHandle(PVOID pvData1, PVOID pvData2)
- #else
- SHORT
- VmmCompareHandle(pvData1,pvData2)
- PVOID pvData1;
- PVOID pvData2;
- #endif
- {
- VMM_BLOCK_P pstBlock1;
- VMM_BLOCK_P pstBlock2;
-
-
- pstBlock1 = (VMM_BLOCK_P) pvData1;
- pstBlock2 = (VMM_BLOCK_P) pvData2;
-
- if(pstBlock1 -> lDescriptor == pstBlock2 -> lDescriptor)
- return(0);
- else if(pstBlock1 -> lDescriptor > pstBlock2 -> lDescriptor)
- return(-1);
- else
- return(1);
-
- }
-
-
-
- /*
- ** VmmCurTime
- **
- ** Get the current time, used in updated block access times
- */
-
- #ifdef C_ANSI
- LONG
- VmmCurTime(VOID)
- #else
- LONG
- VmmCurTime()
- #endif
- {
- time_t lTime;
-
- time(&lTime);
-
- return((LONG) lTime);
- }
-
-
-
-
-
- /* *******************************************************************
-
- T E S T C O D E
-
- ******************************************************************* */
-
-
- #ifdef TEST
-
- #define TEST_3
-
- #define MAX_HANDLES 512
-
- main()
- {
- LONG lHandle1;
- LONG lHandle2;
- PCHAR pcData;
- SHORT sCnt;
- LONG lHandle[MAX_HANDLES];
- SHORT sCnt2;
-
- VmmInit(1024,"swap.dat");
-
- #ifdef TEST_1
-
- VmmAlloc(1,100,&lHandle1);
- VmmPrep(lHandle1,(PPVOID) &pcData);
-
- strcpy(pcData,"Testing 123");
-
- VmmAlloc(1,100,&lHandle2);
- VmmPrep(lHandle2,(PPVOID) &pcData);
-
- strcpy(pcData,"Testing 456");
-
- VmmPrep(lHandle1,(PPVOID) &pcData);
- printf("%s\n", pcData);
-
- VmmPrep(lHandle2,(PPVOID) &pcData);
- printf("%s\n", pcData);
-
- VmmFree(lHandle1);
- VmmFree(lHandle2);
-
- #endif
-
- #ifdef TEST_2
-
- VmmAlloc(1,100,&lHandle1);
- VmmAlloc(1,1000,&lHandle2);
-
- VmmPrep(lHandle1, (PPVOID) &pcData);
- strcpy(pcData,"lHandle1");
-
- VmmPrep(lHandle2, (PPVOID) &pcData);
- strcpy(pcData,"lHandle2");
-
- for(sCnt = 0; sCnt < 10; sCnt++)
- {
- VmmPrep(lHandle1,(PPVOID) &pcData);
- printf("%s\n", pcData);
- sprintf(pcData,"Handle1 - %d", sCnt);
-
- VmmPrep(lHandle2,(PPVOID) &pcData);
- printf("%s\n", pcData);
- sprintf(pcData,"Handle2 - %d", sCnt);
- }
-
- VmmFree(lHandle1);
- VmmFree(lHandle2);
-
- VmmTerm();
-
- #endif
-
- #ifdef TEST_3
-
- for(sCnt = 0; sCnt < MAX_HANDLES; sCnt++)
- VmmAlloc(1,16,&lHandle[sCnt]);
-
- for(sCnt2 = 0; sCnt2 < MAX_HANDLES; sCnt2++)
- {
- printf("Writing...\n");
- for(sCnt = 0; sCnt < MAX_HANDLES; sCnt++)
- {
- VmmPrep(lHandle[sCnt],&pcData);
- sprintf(pcData,"Handle %d %d",sCnt,sCnt2);
- }
-
-
- printf("Retrieve Ascending...\n");
- for(sCnt = 0; sCnt < MAX_HANDLES; sCnt++)
- {
- VmmPrep(lHandle[sCnt],&pcData);
- printf("%s\n",pcData);
- }
- printf("Retrieve Descending...\n");
- for(sCnt = MAX_HANDLES-1; sCnt > 0; sCnt--)
- {
- VmmPrep(lHandle[sCnt],&pcData);
- printf("%s\n",pcData);
- }
- }
- for(sCnt = 0; sCnt < MAX_HANDLES; sCnt++)
- VmmFree(lHandle[sCnt]);
-
- VmmTerm();
-
- #endif
-
- }
- #endif
-
-
-
-