mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 01:45:40 +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 ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
ULONG SACDebug;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -12,11 +12,43 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated;
|
||||||
|
KSPIN_LOCK MemoryLock;
|
||||||
|
PSAC_MEMORY_LIST GlobalMemoryList;
|
||||||
|
|
||||||
/* FUNCTIONS ******************************************************************/
|
/* FUNCTIONS ******************************************************************/
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
InitializeMemoryManagement(VOID)
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +57,28 @@ FreeMemoryManagement(
|
||||||
VOID
|
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
|
PVOID
|
||||||
|
@ -36,13 +89,218 @@ MyAllocatePool(
|
||||||
IN ULONG Line
|
IN ULONG Line
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
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;
|
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
|
VOID
|
||||||
MyFreePool(
|
MyFreePool(
|
||||||
IN PVOID *Block
|
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 *******************************************************************/
|
/* INCLUDES *******************************************************************/
|
||||||
#include <ntddk.h>
|
#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
|
typedef enum _SAC_CHANNEL_TYPE
|
||||||
{
|
{
|
||||||
VtUtf8,
|
VtUtf8,
|
||||||
|
@ -116,3 +156,6 @@ typedef struct _SAC_CHANNEL_ATTRIBUTES
|
||||||
PKEVENT RedrawEvent;
|
PKEVENT RedrawEvent;
|
||||||
GUID ChannelId;
|
GUID ChannelId;
|
||||||
} SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
|
} SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
|
||||||
|
|
||||||
|
extern ULONG SACDebug;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue