📄 flmalloc.c
字号:
/******************************************************************************/
/* */
/* Copyright (C), 1995-2006, msystems Ltd. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* 1. Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* 3. Neither the name of msystems nor the names of its contributors may be */
/* used to endorse or promote products derived from this software without */
/* specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/******************************************************************************/
/*
* $Log: V:/PVCSDB/DiskOnChip/archives/Testing/TrueFFS 6.3/Drop 2.5/3/common/flmalloc.c-arc $
*
* Rev 1.10 Sep 11 2006 13:45:22 yaniv.iarovici
* Legal header added
*
* Rev 1.9 Aug 09 2006 16:52:50 Polina.Marimont
* initial for DOC Driver 1.0
*/
/******************************/
/* Internal compilation flags */
/******************************/
/* Do not compile the heap integrity code */
/* #define FL_DO_NOT_CHECK_HEAP_INTEGRITY */
/* Allow you to plant your debug routine, while traversing the heap */
/* #define FL_HEAP_WALK */
/* Report the various memory chunks while traversing the heap */
/* #define FL_DISPLAY_HEAP */
/* Compile flBiggestFreeMemoryChunk(), reporting the biggest free memory chunk */
/* #define FL_REPORT_BIGGEST_MEMCHUNK */
#include "flbase.h" /* Heap size and system API */
#include "flmalloc.h"
/* Code is compiled only when FL_TRUEFFS_HEAP_SIZE is defined */
#if (FL_TRUEFFS_HEAP_SIZE > 0)
/* Internal macros and defintions */
#ifndef flHeapPrint
#define flHeapPrint(str) DBG_PRINT_WRN(FLZONE_STATISTICS,str)
#endif /* flHeapPrint */
#define FL_REST_HEAP_SIZE (FL_TRUEFFS_HEAP_SIZE - sizeof(flMemChunk))
#define wasMallocInitDone if(flMallocInitDone == FALSE) flInitTFFSMalloc()
/* Internal global variables */
#ifndef FL_TRUEFFS_HEAP_POINTER
static flMemChunk HUGE flHeap[(FL_TRUEFFS_HEAP_SIZE+sizeof(flMemChunk)-1)/sizeof(flMemChunk)];
#else
static flMemChunk * HUGE flHeap;
#endif /* FL_TRUEFFS_HEAP_POINTER */
static FLDword BytesFree;
static FLBoolean flMallocInitDone = FALSE; /* Initialization not done yet */
/* ------------------------------------------------------------------------- */
void flInitTFFSMalloc(void)
{
/* Set heap pointer */
#ifdef FL_TRUEFFS_HEAP_POINTER
flHeap = (flMemChunk *)(FL_TRUEFFS_HEAP_POINTER);
#endif /* FL_TRUEFFS_HEAP_POINTER */
/* Initialize the first entry */
flHeap->flBackOffset = 0;
flHeap->flSize = FL_REST_HEAP_SIZE;
flHeap->flFree = TRUE;
flHeap->flLastBlock = TRUE;
/* Initialize the heap free space */
BytesFree = FL_REST_HEAP_SIZE;
flMallocInitDone = TRUE;
}
/* ------------------------------------------------------------------------- */
FLDword flTotalMemoryLeft(void)
{
wasMallocInitDone;
return BytesFree;
}
/* ------------------------------------------------------------------------- */
#ifndef FL_DO_NOT_CHECK_HEAP_INTEGRITY
static FLBoolean checkLump(flMemChunk * Lump)
{
if (Lump->flBackOffset)
{
FLDword A = ((flMemChunk *)(subFromFarPointer(Lump, Lump->flBackOffset)))->flSize + sizeof(flMemChunk);
return (A == Lump->flBackOffset);
}
return TRUE;
}
#endif /* FL_DO_NOT_CHECK_HEAP_INTEGRITY */
/* ------------------------------------------------------------------------- */
#ifdef FL_HEAP_WALK
FLBoolean flHeapWalk(flInpectHeapFunction reportHeap, void * extraInfo)
{
flMemChunk * CurrLump;
FLDword SizeLeft;
FLBoolean LastBlock;
FLBoolean Status;
FLDword ShiftToNext;
wasMallocInitDone;
CurrLump = (flMemChunk *)flHeap;
SizeLeft = FL_TRUEFFS_HEAP_SIZE;
LastBlock = FALSE;
Status = TRUE;
while (SizeLeft)
{
if (LastBlock)
{
flHeapPrint("FLHEAP: Wrong Last Block!\r\n"); /* do not stop */
Status = FALSE;
}
#ifndef FL_DO_NOT_CHECK_HEAP_INTEGRITY
if (!checkLump(CurrLump))
{
flHeapPrint("FLHEAP: Block damaged\r\n");
return FALSE;
}
#endif /* FL_DO_NOT_CHECK_HEAP_INTEGRITY */
if (reportHeap)
{
reportHeap(CurrLump, extraInfo);
}
if (CurrLump->flLastBlock)
{
LastBlock = TRUE;
}
ShiftToNext = CurrLump->flSize + sizeof(flMemChunk);
if (ShiftToNext > SizeLeft) {
flHeapPrint("FLHEAP: Block damaged - block length exceeds Heap!\r\n");
return FALSE;
}
SizeLeft -= ShiftToNext;
CurrLump = (flMemChunk *)addToFarPointer(CurrLump, ShiftToNext);
}
if (!LastBlock) {
flHeapPrint("FLHEAP: Absent Last Block mark!\r\n");
Status = FALSE;
}
return Status;
}
/* ------------------------------------------------------------------------- */
#ifdef FL_DISPLAY_HEAP
static void printfMemChunk(flMemChunk * mch, void * dummyPtr)
{
DBG_PRINT_ERR_PRM(FLZONE_STATISTICS,(FLTXT("%p - %lu, %s\r\n"),
addToFarPointer(mch, sizeof(flMemChunk)),mch->flSize,
mch->flFree ? "Free" : "Used"));
}
/* ------------------------------------------------------------------------- */
FLBoolean flDisplayHeap(void)
{
wasMallocInitDone;
return flHeapWalk(printfMemChunk, NULL);
}
#endif /* FL_DISPLAY_HEAP */
/* ------------------------------------------------------------------------- */
#ifdef FL_REPORT_BIGGEST_MEMCHUNK
static void findBiggestFreeflMemChunk(flMemChunk * mch, void * biggestSoFar)
{
if (mch->flFree && (mch->flSize > *(FLDword *)biggestSoFar))
*(FLDword *)biggestSoFar = mch->flSize;
}
/* ------------------------------------------------------------------------- */
FLDword flBiggestFreeMemoryChunk(void)
{
FLDword largestChunk = 0;
if (!flHeapWalk(findBiggestFreeflMemChunk, &largestChunk))
return 0;
return largestChunk;
}
#endif /* FL_REPORT_BIGGEST_M2EMCHUNK */
#endif /* FL_HEAP_WALK */
/* ------------------------------------------------------------------------- */
static void * AllocFrom(flMemChunk * FromLump, FLDword Length)
{
flMemChunk * NextLump;
FLDword RestSize = FromLump->flSize - Length;
if (RestSize > sizeof(flMemChunk)) {
FromLump->flSize = Length;
NextLump = (flMemChunk *)addToFarPointer(FromLump, Length + sizeof(flMemChunk));
NextLump->flFree = TRUE;
NextLump->flSize = RestSize - sizeof(flMemChunk);
NextLump->flBackOffset = Length + sizeof(flMemChunk);
NextLump->flLastBlock = FromLump->flLastBlock;
FromLump->flLastBlock = FALSE;
if (!NextLump->flLastBlock) {
flMemChunk * NextAfter = (flMemChunk *)addToFarPointer(NextLump, NextLump->flSize + sizeof(flMemChunk));
NextAfter->flBackOffset = NextLump->flSize + sizeof (flMemChunk);
}
BytesFree -= (Length + sizeof(flMemChunk));
}
else
BytesFree -= FromLump->flSize;
FromLump->flFree = FALSE;
return (void *)addToFarPointer(FromLump, sizeof(flMemChunk));
}
/* ------------------------------------------------------------------ */
/* ------------------------------------------- */
void * flMalloc(FLDword Length)
{
flMemChunk * CurrLump;
FLDword ShiftToNext;
FLDword SizeLeft = FL_TRUEFFS_HEAP_SIZE;
wasMallocInitDone;
CurrLump = (flMemChunk *)flHeap;
if (Length == 0)
{
Length = 1;
}
else /* works if sizeof (flMemChunk) is power of 2 */
{
Length = (Length + sizeof (flMemChunk) - 1) & (FLDword)(-((FLSDword)sizeof (flMemChunk))) ;
}
while (SizeLeft > Length) {
#ifndef FL_DO_NOT_CHECK_HEAP_INTEGRITY
if (!checkLump(CurrLump)) {
flHeapPrint("FLHEAP: Block damaged\r\n");
return NULL;
}
#endif /* FL_DO_NOT_CHECK_HEAP_INTEGRITY */
if (CurrLump->flFree && (CurrLump->flSize >= Length))
return AllocFrom(CurrLump, Length);
ShiftToNext = CurrLump->flSize + sizeof(flMemChunk);
if (ShiftToNext > SizeLeft) {
flHeapPrint("FLHEAP: Block damaged - block length exceeds Heap!\r\n");
return NULL;
}
SizeLeft -= ShiftToNext;
CurrLump = (flMemChunk *)addToFarPointer(CurrLump, ShiftToNext);
}
return NULL;
}
/* ------------------------------------------- */
static void Concat(flMemChunk * CurrLump, flMemChunk * NextLump)
{
#ifndef FL_DO_NOT_CHECK_HEAP_INTEGRITY
if (!checkLump(NextLump)) {
flHeapPrint("FLHEAP: Block damaged\r\n");
return;
}
#endif /* FL_DO_NOT_CHECK_HEAP_INTEGRITY */
CurrLump->flSize += sizeof(flMemChunk) + NextLump->flSize;
CurrLump->flLastBlock = NextLump->flLastBlock;
BytesFree += sizeof(flMemChunk);
}
/* ------------------------------------------- */
FLBoolean flFree(void * ChunkToDelete)
{
flMemChunk * CurrLump;
flMemChunk * NewStart;
flMemChunk * PrevLump;
flMemChunk * NextAfter;
if (ChunkToDelete == NULL) {
/* flHeapPrint("FLHEAP: Deleting NULL pointer\r\n"); */
return FALSE;
}
wasMallocInitDone;
CurrLump = (flMemChunk *)subFromFarPointer(ChunkToDelete, sizeof(flMemChunk));
#ifndef FL_DO_NOT_CHECK_HEAP_INTEGRITY
if (!checkLump(CurrLump)) {
flHeapPrint("FLHEAP: Not Heap Block or Heap damaged\r\n");
return FALSE;
}
#endif /* FL_DO_NOT_CHECK_HEAP_INTEGRITY */
if (CurrLump->flFree) {
flHeapPrint("FLHEAP: Attempt to Free already free block!\r\n");
return FALSE;
}
CurrLump->flFree = TRUE;
BytesFree += CurrLump->flSize;
/* Concatting three adjacent blocks... */
NewStart = CurrLump; /* the next after all must be corrected Back! */
if (CurrLump->flBackOffset) {
PrevLump = (flMemChunk *)subFromFarPointer(CurrLump, CurrLump->flBackOffset);
if (PrevLump->flFree) {
Concat(PrevLump, CurrLump);
NewStart = PrevLump;
}
}
NextAfter = (flMemChunk *)addToFarPointer(NewStart, NewStart->flSize + sizeof(flMemChunk));
if ((!NewStart->flLastBlock) && (NextAfter->flFree)) {
Concat(NewStart, NextAfter);
NextAfter = (flMemChunk *)addToFarPointer(NewStart, NewStart->flSize + sizeof(flMemChunk));
}
if (!NewStart->flLastBlock)
NextAfter->flBackOffset = NewStart->flSize + sizeof (flMemChunk);
return TRUE;
}
/* ------------------------------------------------------------------------- */
#endif /* FL_TRUEFFS_HEAP_SIZE > 0 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -