[ros-diffs] [sir_richard] 52311: Patch by Anton Yarotsky: [SACDRV]: Implement memory manager. [SACDRV]: Define debugging macros.

sir_richard at svn.reactos.org sir_richard at svn.reactos.org
Fri Jun 17 12:54:06 UTC 2011


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?rev=52311&r1=52310&r2=52311&view=diff
==============================================================================
--- 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.c?rev=52311&r1=52310&r2=52311&view=diff
==============================================================================
--- 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.h?rev=52311&r1=52310&r2=52311&view=diff
==============================================================================
--- 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;
+




More information about the Ros-diffs mailing list