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;
+


Reply via email to