📄 memory.c
字号:
}
for (Block = Manager->Head; Block ; Block = Block->Next)
{
/* ENTER CRITICAL SECTION */
critsectEnter ( Manager->CriticalSectionHandle, &NestedContext );
/*
if the current control blcok is allocated or
it is too small to satisfy this request, then
go tho the next block
*/
if( (Block->Flags.Allocated) ||
(EXPAND(Block->Flags.Length) < AlignedLength) )
{
/* LEAVE CRITICAL SECTION */
critsectLeave ( Manager->CriticalSectionHandle, &NestedContext );
continue;
}
/*
Since we are storing the data & the control block
in the same area, there is no point in
alloacting a control block for a buffer size <
sizeof ( control block ). This is what I check
below and if the above is true I allocate the
entire memory block to the application.
*/
if( EXPAND(Block->Flags.Length) > (AlignedLength + 2 * sizeof(MemoryBlock)) )
{
/* allocate a new SHMEM_BLOCK in the free space */
FreeBlock =
(MemoryBlock* )(((UInt8*)Block->Data) + AlignedLength);
/* get the doubly link list pointers set */
FreeBlock->Prev = Block;
FreeBlock->Next = Block->Next;
if( Block->Next)
Block->Next->Prev = FreeBlock;
Block->Next = FreeBlock;
/*
the rest of free memory minus the new block header
we are using to tag the free memory
*/
FreeBlock->Flags.Length =
COLLAPSE( EXPAND(Block->Flags.Length) - ( AlignedLength + sizeof(MemoryBlock) ) );
/* the free block of memory is split into two parts */
Block->Flags.Length = COLLAPSE(AlignedLength);
/* pMemory points to the newly allcoated block */
Block->Flags.Allocated = True;
/* pNew Memory points to the remaining free space */
FreeBlock->Flags.Allocated = False;
FreeBlock->Data = FreeBlock + 1;
halAccessEnable( Manager->HalHandle );
Manager->Control[Object->MemoryNumber].Offset =
halAccess32 ( Manager->HalHandle,
((UInt8*)Block->Data) - ((UInt8*)Manager->MemoryBlock) );
Manager->Control[Object->MemoryNumber].Size =
halAccess32 ( Manager->HalHandle,
AlignedLength );
halAccessDisable( Manager->HalHandle );
//{TRC
Object->ControlOffset =
((UInt8*)Block->Data) - ((UInt8*)Manager->MemoryBlock);
Object->ControlSize = AlignedLength;
//}TRC
Object->Address = ((UInt8*)Block->Data);
halAccessEnable( Manager->HalHandle );
Object->Size =
halAccess32 ( Manager->HalHandle,
Manager->Control[Object->MemoryNumber].Size );
halAccessDisable( Manager->HalHandle );
Manager->MemoryFree -= ( AlignedLength + sizeof(MemoryBlock) );
}
else /* memory too small to allocate another control block */
{
/* return the entire free block */
Block->Flags.Allocated = True;
halAccessEnable( Manager->HalHandle );
Manager->Control[Object->MemoryNumber].Offset =
halAccess32 ( Manager->HalHandle,
((UInt8*)Block->Data) - ((UInt8*)Manager->MemoryBlock) );
Manager->Control[Object->MemoryNumber].Size =
halAccess32 ( Manager->HalHandle,
AlignedLength );
halAccessDisable( Manager->HalHandle );
//{TRC
Object->ControlOffset =
((UInt8*)Block->Data) - ((UInt8*)Manager->MemoryBlock);
Object->ControlSize = AlignedLength;
//}TRC
Object->Address = ((UInt8*)Block->Data);
Object->Size = AlignedLength;
Manager->MemoryFree -= EXPAND(Block->Flags.Length);
}
/* LEAVE CRITICAL SECTION */
critsectLeave ( Manager->CriticalSectionHandle, &NestedContext );
DPF(8,
("tmman:memoryCreate:Block:P[%x]:B[%x]:N[%x]:L[%x]:A[%x]\n",
Block->Prev,
Block,
Block->Next,
EXPAND( Block->Flags.Length),
Manager->MemoryFree ));
/*
DPF(8,
("tmman:memoryCreate:Object:Addr[%x]:Size[%x]:Num[%x]:Offs[%x]:Manager:BlockBase[%x]\n",
Object->Address,
Object->Size,
Object->MemoryNumber,
Manager->Control[Object->MemoryNumber].Offset,
Manager->MemoryBlock ));
*/
*AddressPointer = Object->Address;
*MemoryHandlePointer = (UInt32)Object;
return statusSuccess;
}
return statusMemoryUnavailable;
/*
memoryCreateExit3:
objectlistDelete (
&Manager->List,
Object,
Object->MemoryNumber );
*/
memoryCreateExit3:
namespaceDestroy ( Object->NameSpaceHandle );
memoryCreateExit2:
objectFree ( Object );
memoryCreateExit1:
return StatusCode;
}
TMStatus memoryDestroy (
UInt32 MemoryHandle)
{
MemoryManagerObject* Manager;
MemoryObject* Object =
(MemoryObject*) MemoryHandle;
MemoryBlock* Block;
UInt32 NestedContext;
if ( objectValidate ( Object, MemoryFourCC ) != True )
{
DPF(0,("tmman:memoryDestroy:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
Manager = (MemoryManagerObject* )Object->MemoryManager;
Block = Object->Address;
Block--; /* memory now points to MemoryBlock */
if ( Block->Data != Object->Address )
{
DPF(0,("tmman:memoryDestroy:Block[%x] INVALID BLOCK:FAIL\n",
Object->Address ));
return statusInvalidHandle;
}
if ( ! Block->Flags.Allocated )
{
DPF(0,("tmman:memroyDestroy:Block[%x] NOT ALLOCATED:FAIL\n",
Object->Address ));
return statusInvalidHandle;
}
DPF(8,
("tmman:memoryDestroy:P[%x]:B[%x]:N[%x]:L[%x]:A[%x]\n",
Block->Prev,
Block,
Block->Next,
EXPAND( Block->Flags.Length),
Manager->MemoryFree ));
Block->Flags.Allocated = False;
/* ENTER CRITICAL SECTION */
critsectEnter ( Manager->CriticalSectionHandle, &NestedContext );
Manager->MemoryFree += EXPAND ( Block->Flags.Length );
/* check if we are dealing with the first control block */
if( Block->Prev != Null )
{
/*
if the previous block also free then we combine
the two blocks in to a single one to prevent
fragmentation.
*/
if (Block->Prev->Flags.Allocated == False )
{
/* remove this block from the doubly link list. */
/* adjust the next pointer of the previous block */
Block->Prev->Next = Block->Next;
/*
adjust the previous pointer of the next block
if the block we are freeing is not the last
block in the list
*/
if ( Block->Next )
Block->Next->Prev = Block->Prev;
/*
add the length of the current block to the previous
block, also we are going to get rid of the current
MEMORY_OBJECT so add the size of that to the
previous block and to the memory manager free space
*/
Block->Prev->Flags.Length = COLLAPSE ( EXPAND ( Block->Prev->Flags.Length ) +
EXPAND( Block->Flags.Length) + sizeof ( MemoryBlock ) );
Manager->MemoryFree += sizeof ( MemoryBlock );
/* make the pMemory point to the previous node. */
Block = Block->Prev;
}
}
/*
So far we have combined the length of the block we are trying to free
with the previous block.
At this point if the block previous to the one we are tyring to free was free
then Block is currently pointing to that block.
Not we try to do the same with the next block
*/
/* NOTE : now pMemory points to the previous SHMEM_BLOCK */
/* check if we are dealing with the last control block */
if ( Block->Next != Null )
{
/*
if the next node is free, we have to combine that
too into the previous block. we always combine
with the previous block.
*/
if ( Block->Next->Flags.Allocated == False )
{
/* pMemory always points to the block that has to be removed */
Block = Block->Next;
/* remove this block from the doubly link list. */
Block->Prev->Next = Block->Next;
/* check if there is another block after this block */
if ( Block->Next )
Block->Next->Prev = Block->Prev;
/* adjust the length */
Block->Prev->Flags.Length =
COLLAPSE ( EXPAND( Block->Prev->Flags.Length ) +
EXPAND (Block->Flags.Length) + sizeof ( MemoryBlock ) );
Manager->MemoryFree += sizeof ( MemoryBlock );
}
}
/* LEAVE CRITICAL SECTION */
critsectLeave ( Manager->CriticalSectionHandle, &NestedContext );
/*
DPF(8,("tmman:memoryDestroy:MemorySize[%x]:AvailLen[%x]\n",
Manager->MemorySize, Manager->MemoryFree ));
*/
objectlistDelete (
&Manager->List,
Object,
Object->MemoryNumber );
namespaceDestroy ( Object->NameSpaceHandle );
objectFree ( Object );
return statusSuccess;
}
#else
TMStatus memoryOpen (
UInt32 MemoryManagerHandle,
Pointer ListHead,
Int8* Name,
UInt32* LengthPtr,
Pointer* AddressPointer,
UInt32* MemoryHandlePointer )
{
MemoryManagerObject* Manager =
( MemoryManagerObject* )MemoryManagerHandle;
MemoryObject* Object;
TMStatus StatusCode;
if ( objectValidate ( Manager, MemoryManagerFourCC ) != True )
{
DPF(0,("tmman:memoryOpen:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
if ( ( Object = objectAllocate (
sizeof ( MemoryObject ), MemoryFourCC ) ) == Null )
{
DPF(0,("tmman:memoryOpen:objectAllocate:FAIL\n"));
StatusCode = statusObjectAllocFail;
goto memoryOpenExit1;
}
if ( ( StatusCode = namespaceCreate (
Manager->NameSpaceManagerHandle,
constTMManNameSpaceObjectMemory,
Name,
&Object->MemoryNumber,
&Object->NameSpaceHandle ) ) != statusSuccess )
{
DPF(0,("tmman:memoryOpen:namespceCreate:FAIL[%x]\n", StatusCode ));
goto memoryOpenExit2;
}
if ( objectlistInsert (
&Manager->List,
Object,
Object->MemoryNumber ) != True )
{
DPF(0,("tmman:memoryOpen:objectlistInsert:FAIL\n"));
StatusCode = statusObjectInsertFail;
goto memoryOpenExit3;
}
Object->MemoryManager = Manager;
halAccessEnable( Manager->HalHandle );
Object->Address =
((UInt8*)Manager->MemoryBlock) + halAccess32 ( Manager->HalHandle,
Manager->Control[Object->MemoryNumber].Offset );
Object->Size = halAccess32 ( Manager->HalHandle,
Manager->Control[Object->MemoryNumber].Size );
halAccessDisable( Manager->HalHandle );
Object->ClientHandle = (UInt32)ListHead;
*AddressPointer = Object->Address;
*LengthPtr = Object->Size;
*MemoryHandlePointer = (UInt32)Object;
DPF(8,
("tmman:memoryOpen:Object:Addr[%x]:Size[%x]:Num[%x]:Manager:BlockBase[%x]\n",
Object->Address,
Object->Size,
Object->MemoryNumber,
Manager->MemoryBlock ));
return statusSuccess;
/*
memoryOpenExit4:
objectlistDelete (
&Manager->List,
Object,
Object->MemoryNumber );
*/
memoryOpenExit3:
namespaceDestroy ( Object->NameSpaceHandle );
memoryOpenExit2:
objectFree ( Object );
memoryOpenExit1:
return StatusCode;
}
TMStatus memoryClose (
UInt32 MemoryHandle )
{
MemoryManagerObject* Manager;
MemoryObject* Object =
(MemoryObject*) MemoryHandle;
if ( objectValidate ( Object, MemoryFourCC ) != True )
{
DPF(0,("tmman:memoryClose:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
Manager = (MemoryManagerObject*)Object->MemoryManager;
objectlistDelete (
&Manager->List,
Object,
Object->MemoryNumber );
namespaceDestroy ( Object->NameSpaceHandle );
objectFree ( Object );
return statusSuccess;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -