Author: sir_richard
Date: Fri Jun 17 12:54:05 2011
New Revision: 52311
URL:
http://svn.reactos.org/svn/reactos?rev=52311&view=rev
Log:
Patch by Anton Yarotsky:
[SACDRV]: Implement memory manager.
[SACDRV]: Define debugging macros.
Modified:
trunk/reactos/drivers/sac/driver/data.c
trunk/reactos/drivers/sac/driver/memory.c
trunk/reactos/drivers/sac/driver/sacdrv.h
Modified: trunk/reactos/drivers/sac/driver/data.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/data.c?…
==============================================================================
--- trunk/reactos/drivers/sac/driver/data.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/sac/driver/data.c [iso-8859-1] Fri Jun 17 12:54:05 2011
@@ -11,6 +11,8 @@
#include "sacdrv.h"
/* GLOBALS ********************************************************************/
+
+ULONG SACDebug;
/* FUNCTIONS ******************************************************************/
Modified: trunk/reactos/drivers/sac/driver/memory.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/memory.…
==============================================================================
--- trunk/reactos/drivers/sac/driver/memory.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/sac/driver/memory.c [iso-8859-1] Fri Jun 17 12:54:05 2011
@@ -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 @@
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 @@
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 @@
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;
}
Modified: trunk/reactos/drivers/sac/driver/sacdrv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/sac/driver/sacdrv.…
==============================================================================
--- trunk/reactos/drivers/sac/driver/sacdrv.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/sac/driver/sacdrv.h [iso-8859-1] Fri Jun 17 12:54:05 2011
@@ -8,6 +8,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
{
@@ -116,3 +156,6 @@
PKEVENT RedrawEvent;
GUID ChannelId;
} SAC_CHANNEL_ATTRIBUTES, *PSAC_CHANNEL_ATTRIBUTES;
+
+extern ULONG SACDebug;
+