vmAllocate:
PUBLIC
PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, anywhere:
BOOL,raiseSignal:
BOOL]
RETURNS [mappedAddress: vmAddressT ← 0, kernCode: kernReturnT ← -1] ~
TRUSTED {
Grab some VM.
interval: VM.Interval;
interval ← VM.Allocate[count: VM.PagesForBytes[size]];
mappedAddress ← LOOPHOLE[VM.AddressForPageNumber[interval.page]];
kernCode ← KernSuccess;
};
vmAllocateWithPager:
PUBLIC
ENTRY PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, anywhere:
BOOL, pagingObject: pagingObjectT, offset: vmOffsetT, raiseSignal:
BOOL]
RETURNS [mappedAddress: vmAddressT ← 0, kernCode: kernReturnT ← -1] ~
TRUSTED {
Map some externally backed memory into VM.
loai: LIST OF AllocItem;
interval: VM.Interval;
cvmHandle: CountedVM.Handle;
pages: INT ← -1;
firstPage: INT ← -1;
FOR loai ← VMAllocList, loai.rest
UNTIL loai =
NIL
DO
IF loai.first.offset > offset+size THEN LOOP;
IF offset > loai.first.offset+loai.first.size THEN LOOP;
IF loai.first.offset = offset
AND loai.first.size = size
THEN {
IF loai.first.allocated THEN ERROR;
EXIT;
};
ENDLOOP;
cvmHandle ← CountedVM.Allocate[words:size/BYTES[WORD]];
interval ← VM.Allocate[count: VM.PagesForBytes[size]];
mappedAddress ← LOOPHOLE[cvmHandle.pointer];
pages ← FS.PagesForBytes[size];
IF INT[size] # FS.BytesForPages[pages] THEN ERROR;
firstPage ← FS.PagesForBytes[offset];
IF INT[offset] # FS.BytesForPages[firstPage] THEN ERROR;
IF loai = NIL THEN {
where: LONG POINTER ← LOOPHOLE[mappedAddress];
nWordsLeft: CARD32 ← size/PBasics.bytesPerWord;
WHILE nWordsLeft > 0 DO
fillThisTime: CARD32 ← MIN[nWordsLeft, 10000];
PBasics.Fill[where: where, nWords: fillThisTime, value: 0];
where ← where + fillThisTime * UNITS[PBasics.Word];
nWordsLeft ← nWordsLeft - fillThisTime;
ENDLOOP;
VMAllocList ← CONS[[offset: offset, size: size, mappedAddress: mappedAddress, cvmHandle: cvmHandle], VMAllocList];
}
ELSE {
FS.Read[file: CamelotRecoverable.CamelotRecoverableFile, from: firstPage, nPages: pages, to: LOOPHOLE[mappedAddress]];
loai.first.allocated ← TRUE;
loai.first.mappedAddress ← mappedAddress;
loai.first.cvmHandle ← cvmHandle;
};
kernCode ← KernSuccess;
};
vmDeallocate:
PUBLIC ENTRY PROC [targetTask: vmTaskT, address: vmAddressT, size: vmSizeT, raiseSignal:
BOOL]
RETURNS [kernCode: kernReturnT ← -1] ~ {
Unmap some externally backed memory into VM, whether externally backed or not.
FOR loai:
LIST
OF AllocItem ← VMAllocList, loai.rest
UNTIL loai =
NIL
DO
IF loai.first.mappedAddress = address
THEN {
pages: INT ← -1;
firstPage: INT ← -1;
IF size # loai.first.size THEN ERROR;
pages ← FS.PagesForBytes[loai.first.size];
firstPage ← FS.PagesForBytes[loai.first.offset];
FS.Write[file: CamelotRecoverable.CamelotRecoverableFile, to: firstPage, nPages: pages, from: LOOPHOLE[address]];
TRUSTED{VM.Free[interval: loai.first.interval];};
loai.first.allocated ← FALSE;
loai.first.mappedAddress ← 0;
loai.first.cvmHandle ← NIL;
EXIT;
};
REPEAT FINISHED => ERROR;
ENDLOOP;
};