mirror of
https://github.com/reactos/reactos.git
synced 2025-06-01 15:38:37 +00:00
Patch by Anton Yarotsky:
[SACDRV]: Implement memory manager. [SACDRV]: Define debugging macros. svn path=/trunk/; revision=52311
This commit is contained in:
parent
5a372e009b
commit
08542a70e0
3 changed files with 305 additions and 2 deletions
|
@ -12,6 +12,8 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
ULONG SACDebug;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
VOID
|
||||
|
|
|
@ -12,11 +12,43 @@
|
|||
|
||||
/* GLOBALS ********************************************************************/
|
||||
|
||||
LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated;
|
||||
KSPIN_LOCK MemoryLock;
|
||||
PSAC_MEMORY_LIST GlobalMemoryList;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
InitializeMemoryManagement(VOID)
|
||||
{
|
||||
PSAC_MEMORY_ENTRY Entry;
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
|
||||
GlobalMemoryList = ExAllocatePoolWithTagPriority(
|
||||
NonPagedPool,
|
||||
SAC_MEMORY_LIST_SIZE,
|
||||
INITIAL_BLOCK_TAG,
|
||||
HighPoolPriority);
|
||||
if (GlobalMemoryList)
|
||||
{
|
||||
KeInitializeSpinLock(&MemoryLock);
|
||||
|
||||
GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE;
|
||||
GlobalMemoryList->LocalDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1);
|
||||
GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST);
|
||||
|
||||
Entry = GlobalMemoryList->LocalDescriptor;
|
||||
Entry->Signature = LOCAL_MEMORY_SIGNATURE;
|
||||
Entry->Tag = FREE_POOL_TAG;
|
||||
Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -25,7 +57,28 @@ FreeMemoryManagement(
|
|||
VOID
|
||||
)
|
||||
{
|
||||
|
||||
PSAC_MEMORY_LIST Next;
|
||||
KIRQL OldIrql;
|
||||
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
|
||||
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalMemoryList)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
|
||||
Next = GlobalMemoryList->Next;
|
||||
|
||||
ExFreePoolWithTag(GlobalMemoryList, 0);
|
||||
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
GlobalMemoryList = Next;
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");
|
||||
}
|
||||
|
||||
PVOID
|
||||
|
@ -36,7 +89,117 @@ MyAllocatePool(
|
|||
IN ULONG Line
|
||||
)
|
||||
{
|
||||
return NULL;
|
||||
KIRQL OldIrql;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
|
||||
ULONG GlobalSize, ActualSize;
|
||||
PVOID Buffer;
|
||||
|
||||
ASSERT("Tag != FREE_POOL_TAG");
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Entering.\n");
|
||||
|
||||
OldIrql = KfAcquireSpinLock(&MemoryLock);
|
||||
PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
|
||||
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalDescriptor)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
|
||||
LocalDescriptor = GlobalDescriptor->LocalDescriptor;
|
||||
|
||||
GlobalSize = GlobalDescriptor->Size;
|
||||
while (GlobalSize)
|
||||
{
|
||||
ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
if ((LocalDescriptor->Tag == FREE_POOL_TAG) &&
|
||||
(LocalDescriptor->Size >= PoolSize))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
GlobalSize -= (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
|
||||
|
||||
LocalDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
|
||||
LocalDescriptor->Size +
|
||||
sizeof(SAC_MEMORY_ENTRY));
|
||||
}
|
||||
|
||||
GlobalDescriptor = GlobalDescriptor->Next;
|
||||
}
|
||||
|
||||
if (!GlobalDescriptor)
|
||||
{
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
|
||||
ActualSize = min(
|
||||
PAGE_SIZE,
|
||||
PoolSize + sizeof(SAC_MEMORY_ENTRY) + sizeof(SAC_MEMORY_LIST));
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Allocating new space.\n");
|
||||
|
||||
NewDescriptor = ExAllocatePoolWithTagPriority(
|
||||
0,
|
||||
ActualSize,
|
||||
ALLOC_BLOCK_TAG,
|
||||
HighPoolPriority);
|
||||
if (!NewDescriptor)
|
||||
{
|
||||
SAC_DBG(SAC_DBG_MM, "No more memory, returning NULL.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
|
||||
NewDescriptor->Signature = GLOBAL_MEMORY_SIGNATURE;
|
||||
NewDescriptor->LocalDescriptor = (PSAC_MEMORY_ENTRY)(NewDescriptor + 1);
|
||||
NewDescriptor->Size = ActualSize - 16;
|
||||
NewDescriptor->Next = GlobalMemoryList;
|
||||
|
||||
GlobalMemoryList = NewDescriptor;
|
||||
|
||||
LocalDescriptor = NewDescriptor->LocalDescriptor;
|
||||
LocalDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
|
||||
LocalDescriptor->Tag = FREE_POOL_TAG;
|
||||
LocalDescriptor->Size =
|
||||
GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
|
||||
}
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Found a good sized block.\n");
|
||||
ASSERT(LocalDescriptor->Tag == FREE_POOL_TAG);
|
||||
ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
if (LocalDescriptor->Size > (PoolSize + sizeof(SAC_MEMORY_ENTRY)))
|
||||
{
|
||||
NextDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
|
||||
PoolSize +
|
||||
sizeof(SAC_MEMORY_ENTRY));
|
||||
if (NextDescriptor->Tag == FREE_POOL_TAG)
|
||||
{
|
||||
NextDescriptor->Tag = FREE_POOL_TAG;
|
||||
NextDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
|
||||
NextDescriptor->Size =
|
||||
(LocalDescriptor->Size - PoolSize - sizeof(SAC_MEMORY_ENTRY));
|
||||
|
||||
LocalDescriptor->Size = PoolSize;
|
||||
}
|
||||
}
|
||||
|
||||
LocalDescriptor->Tag = Tag;
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
|
||||
InterlockedIncrement(&TotalAllocations);
|
||||
InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
|
||||
SAC_DBG(1, "Returning block 0x%X.\n", LocalDescriptor);
|
||||
|
||||
Buffer = LocalDescriptor + 1;
|
||||
RtlZeroMemory(Buffer, PoolSize);
|
||||
return Buffer;
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -44,5 +207,100 @@ MyFreePool(
|
|||
IN PVOID *Block
|
||||
)
|
||||
{
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
|
||||
PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
|
||||
ULONG GlobalSize, LocalSize;
|
||||
PSAC_MEMORY_LIST GlobalDescriptor;
|
||||
KIRQL OldIrql;
|
||||
|
||||
LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
|
||||
|
||||
ASSERT(LocalDescriptor->Size > 0);
|
||||
ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
InterlockedIncrement(&TotalFrees);
|
||||
|
||||
InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
|
||||
|
||||
GlobalDescriptor = GlobalMemoryList;
|
||||
KeAcquireSpinLock(&MemoryLock, &OldIrql);
|
||||
while (GlobalDescriptor)
|
||||
{
|
||||
ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
|
||||
|
||||
FoundDescriptor = NULL;
|
||||
|
||||
ThisDescriptor = GlobalDescriptor->LocalDescriptor;
|
||||
|
||||
GlobalSize = GlobalDescriptor->Size;
|
||||
while (GlobalSize)
|
||||
{
|
||||
ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
if (ThisDescriptor == LocalDescriptor) break;
|
||||
|
||||
GlobalSize -= (ThisDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
|
||||
|
||||
ThisDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)((ULONG_PTR)ThisDescriptor +
|
||||
ThisDescriptor->Size +
|
||||
sizeof(SAC_MEMORY_ENTRY));
|
||||
}
|
||||
|
||||
if (ThisDescriptor == LocalDescriptor) break;
|
||||
|
||||
GlobalDescriptor = GlobalDescriptor->Next;
|
||||
}
|
||||
|
||||
if (!GlobalDescriptor)
|
||||
{
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_MM, "Could not find block.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
|
||||
|
||||
if (LocalDescriptor->Tag == FREE_POOL_TAG)
|
||||
{
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
SAC_DBG(SAC_DBG_MM, "Attempted to free something twice.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
LocalSize = LocalDescriptor->Size;
|
||||
LocalDescriptor->Tag = FREE_POOL_TAG;
|
||||
|
||||
if (GlobalSize > (LocalSize + sizeof(SAC_MEMORY_ENTRY)))
|
||||
{
|
||||
NextDescriptor =
|
||||
(PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
|
||||
LocalSize +
|
||||
sizeof(SAC_MEMORY_ENTRY));
|
||||
if (NextDescriptor->Tag == FREE_POOL_TAG)
|
||||
{
|
||||
NextDescriptor->Tag = 0;
|
||||
NextDescriptor->Signature = 0;
|
||||
|
||||
LocalDescriptor->Size +=
|
||||
(NextDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
|
||||
}
|
||||
}
|
||||
|
||||
if ((FoundDescriptor) && (FoundDescriptor->Tag == FREE_POOL_TAG))
|
||||
{
|
||||
LocalDescriptor->Signature = 0;
|
||||
LocalDescriptor->Tag = 0;
|
||||
|
||||
FoundDescriptor->Size +=
|
||||
(LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&MemoryLock, OldIrql);
|
||||
*Block = NULL;
|
||||
|
||||
SAC_DBG(SAC_DBG_MM, "exiting.\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,46 @@
|
|||
/* INCLUDES *******************************************************************/
|
||||
#include <ntddk.h>
|
||||
|
||||
#define SAC_DBG_ENTRY_EXIT 0x01
|
||||
#define SAC_DBG_MM 0x1000
|
||||
|
||||
#define SAC_DBG(x, ...) \
|
||||
if (SACDebug & x) \
|
||||
{ \
|
||||
DbgPrint("SAC %s: ", __FUNCTION__); \
|
||||
DbgPrint(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
//Rcp? - sacdrv.sys - SAC Driver (Headless)
|
||||
//RcpA - sacdrv.sys - Internal memory mgr alloc block
|
||||
//RcpI - sacdrv.sys - Internal memory mgr initial heap block
|
||||
//RcpS - sacdrv.sys - Security related block
|
||||
#define GENERIC_TAG '?pcR'
|
||||
#define ALLOC_BLOCK_TAG 'ApcR'
|
||||
#define INITIAL_BLOCK_TAG 'IpcR'
|
||||
#define SECURITY_BLOCK_TAG 'SpcR'
|
||||
#define FREE_POOL_TAG 'FpcR'
|
||||
|
||||
#define LOCAL_MEMORY_SIGNATURE 'SSEL'
|
||||
#define GLOBAL_MEMORY_SIGNATURE 'DAEH'
|
||||
|
||||
#define SAC_MEMORY_LIST_SIZE (1 * 1024 * 1024)
|
||||
|
||||
typedef struct _SAC_MEMORY_ENTRY
|
||||
{
|
||||
ULONG Signature;
|
||||
ULONG Tag;
|
||||
ULONG Size;
|
||||
} SAC_MEMORY_ENTRY, *PSAC_MEMORY_ENTRY;
|
||||
|
||||
typedef struct _SAC_MEMORY_LIST
|
||||
{
|
||||
ULONG Signature;
|
||||
PSAC_MEMORY_ENTRY LocalDescriptor;
|
||||
ULONG Size;
|
||||
struct _SAC_MEMORY_LIST* Next;
|
||||
} SAC_MEMORY_LIST, *PSAC_MEMORY_LIST;
|
||||
|
||||
typedef enum _SAC_CHANNEL_TYPE
|
||||
{
|
||||
VtUtf8,
|
||||
|
@ -116,3 +156,6 @@ typedef struct _SAC_CHANNEL_ATTRIBUTES
|
|||
PKEVENT RedrawEvent;
|
||||
GUID ChannelId;
|
||||
} SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
|
||||
|
||||
extern ULONG SACDebug;
|
||||
|
||||
|
|
Loading…
Reference in a new issue