📄 davmem.c
字号:
return status;
}
/*#################################################################
### MEM_CalcBeginningOfFreePoolInParaSpace
###
### DESCRIPTION:
### This function will calculate a handle to the beginning of
### the free pool in paragraph space.
###
### PARAMETERS:
###
### RETURNS:
### Error status.
###*/
ERR_CODE MEM_CalcBeginningOfFreePoolInParaSpace(FDI_HandlePtr aFreePoolHandlePtr)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
HDR_FixedHeader lastHeader;
UINT32 currOffset = 0;
UINT32 candidateOffset = 0;
HDR_InitHeaderAttr1(currHeader.Attr1);
HDR_InitHeaderAttr2(currHeader.Attr2);
HDR_InitHeaderAttr1(lastHeader.Attr1);
HDR_InitHeaderAttr2(lastHeader.Attr2);
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, FALSE);
/* if the header points to a real user object, dirty chunk, or free chunk in page space */
if (
(status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) == HDR_HEADER_VALID) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_NOT_ABSORBED) &&
(FHDR_IsParaObject(&currHeader))
)
{
/* compare the offset in this header with the current offset */
/* save it if it's higher */
candidateOffset = FHDR_GetHeaderIndexOffset(&currHeader);
if ((candidateOffset > currOffset) || (currOffset == 0))
{
/* this object exists in para space above the current object */
/* and it's above than any previous objects found */
currOffset = candidateOffset;
lastHeader.Attr1 = currHeader.Attr1;
lastHeader.Attr2 = currHeader.Attr2;
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
} while ((status == ERR_NONE) && (FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED));
ExitOnError(status);
if (currOffset == 0 && FHDR_GetHeaderStatus(&lastHeader) == HDR_HEADER_UNUSED)
{
/* the paragraph space is empty except for the headers */
*aFreePoolHandlePtr = FDI_ParaSpaceAddressBottom;
}
else
{
*aFreePoolHandlePtr = FHDR_CalcObjectHandle(&lastHeader) +
FHDR_CalcObjectSize(&lastHeader);
}
return status;
}
/*#################################################################
### MEM_CalcSizeAndHandleOfFreePoolInParaSpace
###
### DESCRIPTION:
### This function will calculate the size in bytes and the
### handle of the free pool in paragraph space.
###
### PARAMETERS:
###
### RETURNS:
### Error status.
###*/
ERR_CODE MEM_CalcSizeAndHandleOfFreePoolInParaSpace(UINT32* sizeInBytes,
FDI_HandlePtr aFreePoolHandlePtr)
{
ERR_CODE status = ERR_NONE;
status = MEM_CalcBeginningOfFreePoolInParaSpace(aFreePoolHandlePtr);
ExitOnError(status);
*sizeInBytes = FDI_LastHeaderEntry - *aFreePoolHandlePtr;
return status;
}
/*#################################################################
### MEM_FindLargestFreeChunkInPageSpace
###
### DESCRIPTION:
### This function will the largest contiguous free chunk
### in page space. If the free pool in page space is larger,
### then a handle to it will be returned.
###
### PARAMETERS:
###
### RETURNS:
### Error status.
###*/
ERR_CODE MEM_FindLargestFreeChunkInPageSpace(FDI_HandlePtr aFreeChunkHandlePtr,
UINT32* sizeInPages)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
FDI_Handle tempHandle;
HDR_FixedHeader currHeader;
UINT32 currSize = 0;
UINT32 candidateSize;
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, FALSE);
/* if the header points to a free chunk in page space */
if (
(status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) == HDR_HEADER_VALID) &&
(FHDR_GetAllocationStatus(&currHeader) == HDR_ALLOC_EMPTY) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_NOT_ABSORBED) &&
(FHDR_GetHeaderIndexOffset(&currHeader) != HDR_INDEX_OFFSET_UNUSED) &&
(FHDR_IsPageObject(&currHeader))
)
{
/* compare the size in this header with the largest size found so far */
/* save it if it's higher */
candidateSize = FHDR_GetSize(&currHeader);
if (candidateSize > currSize)
{
/* this object is larger than any previously found */
currSize = candidateSize;
*aFreeChunkHandlePtr = FHDR_CalcObjectHandle(&currHeader);
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
} while ((status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED));
ExitOnError(status);
status = MEM_CalcSizeAndHandleOfFreePoolInPageSpace(sizeInPages, &tempHandle);
ExitOnError(status);
if (*sizeInPages < currSize)
{
/* don't return free pool size if smaller than largest free chunk found */
*sizeInPages = currSize;
}
else
{
/* free pool is the largest, so return a handle to the free pool */
*aFreeChunkHandlePtr = tempHandle;
}
return status;
}
/*#################################################################
### MEM_FindLargestUnpinnedFreeChunkInPageSpace
###
### DESCRIPTION:
### This function will the largest contiguous free chunk
### in page space. If the free pool in page space is larger,
### then a handle to it will be returned.
###
### PARAMETERS:
###
### RETURNS:
### Error status.
###*/
ERR_CODE MEM_FindLargestUnpinnedFreeChunkInPageSpace(FDI_HandlePtr aFreeChunkHandlePtr,
UINT32* sizeInPages)
{
ERR_CODE status = ERR_NONE;
BOOLEAN found = FALSE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
UINT32 candidateSize;
UINT32 freePoolSizeInPages = 0;
FDI_Handle freePoolHandle;
FDI_Handle blockAlignedFreePoolHandle;
UINT32 blockAlignedFreePoolSizeInPages;
*aFreeChunkHandlePtr = FDI_InvalidObjAddress;
*sizeInPages = 0;
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, FALSE);
/* if the header points to a free chunk in page space */
if (
(status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) == HDR_HEADER_VALID) &&
(FHDR_GetAllocationStatus(&currHeader) == HDR_ALLOC_EMPTY) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_NOT_ABSORBED) &&
(FHDR_GetHeaderIndexOffset(&currHeader) != HDR_INDEX_OFFSET_UNUSED) &&
(FHDR_IsPageObject(&currHeader))
)
{
/* only consider this candidate if it is completely unpinned */
if (PIN_LIST_IsObjectPinned(FHDR_GetHeaderIndexOffset(
&currHeader), FHDR_GetSize(&currHeader)) == enNotPinned)
{
/* compare the size in this header with the largest size found so far */
/* save it if it's higher */
candidateSize = FHDR_GetSize(&currHeader);
if (candidateSize > *sizeInPages)
{
/* this object is larger than any previously found */
found = TRUE;
*sizeInPages = candidateSize;
*aFreeChunkHandlePtr = FHDR_CalcObjectHandle(&currHeader);
}
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
} while ((status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED));
/* is free pool larger? */
status = MEM_CalcSizeAndHandleOfFreePoolInPageSpace(&freePoolSizeInPages, &freePoolHandle);
ExitOnError(status);
if (PIN_LIST_IsObjectPinned(FHDR_CalcObjectOffset(freePoolHandle), 1) != enNotPinned)
{
/* lower boundary of free pool is pinned */
if (freePoolSizeInPages > (FDI_BlockSize/FDI_PageSize))
{
/* if block-aligning the free pool will still give us a chunk larger than any other free chunk */
if ((freePoolSizeInPages - (freePoolSizeInPages % (FDI_BlockSize/FDI_PageSize))) > *sizeInPages)
{
/* create a free chunk to block align the lower boundary of the free pool */
/* compute blockAlignedFreePoolHandle based on next block boundary */
blockAlignedFreePoolHandle = FDI_FirstObjectAddress +
((UTIL_CalcBlockNumberForOffset(FHDR_CalcObjectOffset(freePoolHandle))+1) * FDI_BlockSize);
/* compute blockAlignedFreePoolSizeInPages based on new handle */
blockAlignedFreePoolSizeInPages =
(FDI_ParaSpaceAddressBottom - blockAlignedFreePoolHandle) / FDI_PageSize;
/* create a free chunk to fill in between the last object */
/* and the beginning of the block-aligned free pool */
FDI_LastHeaderEntry = FDI_NextFreeHeaderEntry;
FDI_NextFreeHeaderEntry -= FHDR_CalcHeaderSize();
status = FHDR_CreateFreeChunkHeader(
FDI_LastHeaderEntry,
FHDR_CalcObjectOffset(freePoolHandle),
freePoolSizeInPages - blockAlignedFreePoolSizeInPages);
ExitOnError(status);
found = TRUE;
*aFreeChunkHandlePtr = blockAlignedFreePoolHandle;
*sizeInPages = blockAlignedFreePoolSizeInPages;
}
}
}
else
{
/* if free pool is larger than any other free chunk and isn't pinned, return the handle to it */
if (freePoolSizeInPages > *sizeInPages)
{
found = TRUE;
*aFreeChunkHandlePtr = freePoolHandle;
*sizeInPages = freePoolSizeInPages;
}
}
if (!found)
{
status = ERR_NO_MORE_ENTRIES;
ExitOnError(status);
}
return status;
}
/*#################################################################
### MEM_FindFirstFitFreeChunkInPageSpace
###
### DESCRIPTION:
### This function will the first contiguous free chunk
### in page space that is larger than the requested size.
### If one is not found, a hanlde to the free pool in page
### space will be returned if the free pool is large enough.
### If not, then an error will be returned.
###
### PARAMETERS:
###
### RETURNS:
### Error status.
###*/
ERR_CODE MEM_FindFirstFitFreeChunkInPageSpace(FDI_HandlePtr aFreeChunkHandlePtr,
UINT32 aRequestedSizeInPages,
UINT32* aReturnedSizeInPages)
{
ERR_CODE status = ERR_NONE;
FDI_Handle currHeaderHandle = DAV_MEM_FirstHeaderAddr;
HDR_FixedHeader currHeader;
UINT32 maxFreeChunkSizeInPages = 0;
UINT32 freePoolSizeInPages = 0;
FDI_Handle freePoolHandle;
BOOLEAN foundFit = FALSE;
do
{
status = FHDR_ReadFixedHeader(currHeaderHandle, &currHeader, FALSE);
/* if the header points to a free chunk in page space */
if (
(status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) == HDR_HEADER_VALID) &&
(FHDR_GetAllocationStatus(&currHeader) == HDR_ALLOC_EMPTY) &&
(FHDR_GetAbsorbStatus(&currHeader) == HDR_NOT_ABSORBED) &&
(FHDR_GetHeaderIndexOffset(&currHeader) != HDR_INDEX_OFFSET_UNUSED) &&
(FHDR_IsPageObject(&currHeader))
)
{
/* compare the size in this header with the requested size */
if (FHDR_GetSize(&currHeader) > aRequestedSizeInPages)
{
foundFit = TRUE;
}
}
currHeaderHandle = SEARCH_CalcNextHdrAddr(currHeaderHandle);
} while ((status == ERR_NONE) &&
(FHDR_GetHeaderStatus(&currHeader) != HDR_HEADER_UNUSED) &&
(foundFit == FALSE));
ExitOnError(status);
if (foundFit == TRUE)
{
*aFreeChunkHandlePtr = FHDR_CalcObjectHandle(&currHeader);
*aReturnedSizeInPages = FHDR_GetSize(&currHeader);
}
else
{
/* try to allocate in the free pool in page space*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -