📄 memory.c
字号:
/*----------------------------------------------------------------------------
COPYRIGHT (c) 1995 by Philips Semiconductors
THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED AND COPIED IN
ACCORDANCE WITH THE TERMS AND CONDITIONS OF SUCH A LICENSE AND WITH THE
INCLUSION OF THE THIS COPY RIGHT NOTICE. THIS SOFTWARE OR ANY OTHER COPIES
OF THIS SOFTWARE MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
PERSON. THE OWNERSHIP AND TITLE OF THIS SOFTWARE IS NOT TRANSFERRED.
THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT ANY PRIOR NOTICE
AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY Philips Semiconductor.
PHILIPS ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE
ON PLATFORMS OTHER THAN THE ONE ON WHICH THIS SOFTWARE IS FURNISHED.
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
#define TR Tilakraj Roy
940424 TR Created
940827 TR Documented new algorithms
960925 TR Pulled in sources for tmman
960927 TR Created interfaces for tmman
010828 Wim de Haan Changed code to remove compiler warning:
Line 341: '=' : 'unsigned long ' differs in levels
of indirection from 'void *'
ABOUT
This file contains the dynamic memory allocation
routines required by the application to allocate
and free memory as and when required. With the
current implementation the kernel data structures
are statically allocated. This is done to maintain
alogorithm simplicity. Since we are manipulating
linked lists. These functions have to acquire the
lock to the memory manager data structure.This is
not implemented currently.
MEM_BLOCK
+----------+ <--------MEM_MGR_OBJECT.pHead
+------>| pPrev |---> NULL
| | pNext |---+
| +--| pData | |
| | | Length | |
| | +----------+ |
| +->| | |
| | | |
| | Allocated| |
| | Block | |
| | | |
| | | |
| +----------+ |
+-------| pPrev |<--+
| pNext |---> NULL
+--| pData |
| | Length |
| +----------+
+->| |
| |
| Free |
| Block |
| |
| |
+----------+
The above diagram shows the me memory layout after the calls to memCreate()
and memAlloc().
MEM_MGR_OBJECT points to the first SHMEM_BLOCK after the call to
memCreate(). SHMEM_BLOCK points to the entire free memory.
After the first call to memAllocate() a new memory block is created that
points to the remaining free space and the original SHMEM_BLOCK points
to the memory that was allocated as a result of this call to memAlloc().
----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------
DRIVER SPECIFIC INCLUDE FILES
----------------------------------------------------------------------------*/
#include "tmmanlib.h"
#define MemoryManagerFourCC tmmanOBJECTID ( 'M', 'E', 'M', 'M' )
#define MemoryFourCC tmmanOBJECTID ( 'M', 'E', 'M', 'O' )
#define COLLAPSE(x) ((x)>>2)
#define EXPAND(x) ((x)<<2)
typedef struct tagMemoryBlock
{
struct tagMemoryBlock* Prev;
struct tagMemoryBlock* Next;
Pointer Data;
struct
{
UInt32 Length :30;
UInt32 Allocated :1;
UInt32 Contig :1;
} Flags;
} MemoryBlock;
typedef struct tagMemoryControl
{
UInt32 volatile Offset;
UInt32 volatile Size;
} MemoryControl;
typedef struct tagMemoryObject
{
GenericObject Object;
Pointer MemoryManager;
UInt32 MemoryNumber;
UInt32 Size;
Pointer Address;
UInt32 NameSpaceHandle;
UInt32 ClientHandle;
UInt32 ControlOffset;
UInt32 ControlSize;
} MemoryObject;
typedef struct tagMemoryManagerObject
{
GenericObject Object;
ObjectList List;
UInt32 MemoryCount;
UInt32 MemorySize;
Pointer MemoryBlock;
Pointer SharedData;
UInt32 HalHandle;
MemoryControl* Control;
/* required ony on the host */
UInt32 MemoryFree;
Pointer Head;
UInt32 NameSpaceManagerHandle;
UInt32 CriticalSectionHandle;
} MemoryManagerObject;
UInt32 memorySharedDataSize (
UInt32 MemoryCount )
{
return ( sizeof ( MemoryControl ) * MemoryCount );
}
TMStatus memoryManagerReset (
UInt32 MemoryManagerHandle )
{
MemoryManagerObject* Manager =
( MemoryManagerObject* )MemoryManagerHandle;
MemoryObject* Object;
UInt32 Idx;
if ( objectValidate ( Manager, MemoryManagerFourCC ) != True )
{
DPF(0,("tmman:memoryManagerReset:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
for ( Idx = 0 ; Idx < Manager->MemoryCount ; Idx ++ )
{
halAccessEnable( Manager->HalHandle );
Manager->Control[Idx].Offset =
halAccess32 ( Manager->HalHandle, 0 );
Manager->Control[Idx].Size =
halAccess32 ( Manager->HalHandle, 0 );
halAccessDisable( Manager->HalHandle );
}
for ( Idx = 0 ; Idx < Manager->MemoryCount ; Idx ++ )
{
if ( ( Object = objectlistGetObject (
&Manager->List,
Idx ) ) != Null )
{
halAccessEnable( Manager->HalHandle );
Manager->Control[Object->MemoryNumber].Offset =
halAccess32 ( Manager->HalHandle,
Object->ControlOffset );
Manager->Control[Object->MemoryNumber].Size =
halAccess32 ( Manager->HalHandle,
Object->ControlSize );
halAccessDisable( Manager->HalHandle );
}
}
return statusSuccess;
}
TMStatus memoryManagerCreate (
memoryManagerParameters* Parameters,
UInt32* MemoryManagerHandlePointer )
{
MemoryManagerObject* Manager;
MemoryBlock* Block;
TMStatus StatusCode;
if ( ( Manager = objectAllocate (
sizeof ( MemoryManagerObject ),
MemoryManagerFourCC ) ) == Null )
{
DPF(0,("tmman:memoryManagerCreate:objectAllocate:FAIL\n"));
StatusCode = statusObjectAllocFail;
goto memoryManagerCreateExit1;
}
Manager->MemoryCount = Parameters->MemoryCount;
Manager->SharedData = Parameters->SharedData;
Manager->HalHandle = Parameters->HalHandle;
Manager->MemorySize = Parameters->MemorySize;
Manager->MemoryBlock = Parameters->MemoryBlock;
Manager->Control = Parameters->SharedData;
Manager->MemoryFree = Manager->MemorySize - sizeof(MemoryBlock);
Manager->NameSpaceManagerHandle = Parameters->NameSpaceManagerHandle;
if ( objectlistCreate ( &Manager->List,
Manager->MemoryCount ) != True )
{
DPF(0,("tmman:memoryManagerCreate:objectlistCreate:FAIL\n"));
StatusCode = statusObjectListAllocFail;
goto memoryManagerCreateExit2;
}
#ifdef TMMAN_HOST
/* initialize the free memory block pointer */
Block = (MemoryBlock* )Manager->MemoryBlock;
Block->Prev = Null;
Block->Next = Null;
Block->Flags.Allocated = False;
Block->Flags.Length = COLLAPSE(Manager->MemoryFree);
Block->Data = Block + 1 ;
Manager->Head = Block;
#endif
if ( critsectCreate ( &Manager->CriticalSectionHandle ) == False )
{
DPF(0,("tmman:memoryManagerCreate:critSectCreate:FAIL\n"));
StatusCode = statusCriticalSectionCreateFail;
goto memoryManagerCreateExit3;
}
/* memoryManagerReset((UInt32)Manager); */
*MemoryManagerHandlePointer = (UInt32)Manager;
return statusSuccess;
/*
memoryManagerCreateExit4:
critsectDestroy ( Manager->CriticalSectionHandle );
*/
memoryManagerCreateExit3:
objectlistDestroy ( &Manager->List );
memoryManagerCreateExit2:
objectFree ( Manager );
memoryManagerCreateExit1:
return StatusCode;
}
TMStatus memoryManagerDestroy (
UInt32 MemoryManagerHandle )
{
MemoryManagerObject* Manager =
( MemoryManagerObject* )MemoryManagerHandle;
if ( objectValidate ( Manager, MemoryManagerFourCC ) != True )
{
DPF(0,("tmman:memoryManagerDestroy:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
critsectDestroy ( Manager->CriticalSectionHandle );
objectlistDestroy ( &Manager->List );
objectFree ( Manager );
return statusSuccess;
}
TMStatus memoryManagerDestroyMemoryByClient (
UInt32 MemoryManagerHandle,
UInt32 ClientHandle )
{
MemoryManagerObject* Manager =
( MemoryManagerObject* )MemoryManagerHandle;
MemoryObject* Object;
UInt32 Idx;
if ( objectValidate ( Manager, MemoryManagerFourCC ) != True )
{
DPF(0,("tmman:memoryManagerDestroyMemoryByClient:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
for ( Idx = 0 ; Idx < Manager->MemoryCount ; Idx++ )
{
Object = objectlistGetObject (
&Manager->List,
Idx );
if ( ( Object ) && Object->ClientHandle == ClientHandle )
{
#ifdef TMMAN_HOST
memoryDestroy ( (UInt32) Object );
#else
memoryClose ( (UInt32) Object );
#endif
}
}
return statusSuccess;
}
TMStatus memoryGetAddress (
UInt32 MemoryHandle,
UInt32* AddressPointer )
{
MemoryObject* Object = (MemoryObject*) MemoryHandle;
MemoryManagerObject* Manager;
Manager = (MemoryManagerObject* )Object->MemoryManager;
if ( objectValidate ( Object, MemoryFourCC ) != True )
{
DPF(0,("tmman:memoryGetAddress:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
*AddressPointer = (UInt32)Object->Address;
return statusSuccess;
}
TMStatus memoryGetHalHandle (
UInt32 MemoryHandle,
UInt32* HalHandle )
{
MemoryObject* Object = (MemoryObject*) MemoryHandle;
MemoryManagerObject* Manager;
if ( objectValidate ( Object, MemoryFourCC ) != True )
{
DPF(0,("tmman:memoryGetAddress:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
Manager = (MemoryManagerObject* )Object->MemoryManager;
*HalHandle = Manager->HalHandle;
return statusSuccess;
}
#ifdef TMMAN_HOST
TMStatus memoryCreate(
UInt32 MemoryManagerHandle,
Pointer ListHead,
Int8* Name,
UInt32 Length,
Pointer* AddressPointer,
UInt32* MemoryHandlePointer )
{
MemoryManagerObject* Manager =
( MemoryManagerObject* )MemoryManagerHandle;
MemoryObject* Object;
TMStatus StatusCode;
MemoryBlock* Block;
MemoryBlock* FreeBlock;
UInt32 AlignedLength;
UInt32 NestedContext;
if ( objectValidate ( Manager, MemoryManagerFourCC ) != True )
{
DPF(0,("tmman:memoryCreate:objectValidate:FAIL\n"));
return statusInvalidHandle;
}
AlignedLength = ( Length + 0x3 ) & 0xfffffffc;
DPF(8,("tmman:memoryCreate:ReqLen[%x]:AlignedSize[%x]:AvailLen[%x]\n",
Length,AlignedLength, Manager->MemoryFree ));
/* decide if we have enough left for this block */
if ((AlignedLength + sizeof( MemoryBlock)) > Manager->MemoryFree)
{
DPF(0,("tmman:memoryCreate:Length[%x] OUT OF MEMORY:FAIL\n",
AlignedLength ));
return statusMemoryUnavailable;
}
if ( ( Object = objectAllocate (
sizeof ( MemoryObject ), MemoryFourCC ) ) == Null )
{
DPF(0,("tmman:memoryCreate:objectAllocate:FAIL\n"));
StatusCode = statusObjectAllocFail;
goto memoryCreateExit1;
}
if ( ( StatusCode = namespaceCreate (
Manager->NameSpaceManagerHandle,
constTMManNameSpaceObjectMemory,
Name,
&Object->MemoryNumber,
&Object->NameSpaceHandle ) ) != statusSuccess )
{
DPF(0,("tmman:memoryCreate:namespaceCreate:FAIL[%x]\n",
StatusCode ));
goto memoryCreateExit2;
}
Object->MemoryManager = Manager;
Object->ClientHandle = (UInt32)ListHead;
if ( objectlistInsert (
&Manager->List,
Object,
Object->MemoryNumber ) != True )
{
DPF(0,("tmman:memoryCreate:objectlistInsert:FAIL\n"));
StatusCode = statusObjectInsertFail;
goto memoryCreateExit3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -