Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350/* * PROJECT: ReactOS Drivers * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/sac/driver/memory.c * PURPOSE: Driver for the Server Administration Console (SAC) for EMS * PROGRAMMERS: ReactOS Portable Systems Group */
/* INCLUDES *******************************************************************/
#include "sacdrv.h"
/* GLOBALS ********************************************************************/
LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated;KSPIN_LOCK MemoryLock;PSAC_MEMORY_LIST GlobalMemoryList;
/* FUNCTIONS ******************************************************************/
BOOLEANNTAPIInitializeMemoryManagement(VOID){ PSAC_MEMORY_ENTRY Entry; SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
/* Allocate a nonpaged heap for us to use */ GlobalMemoryList = ExAllocatePoolWithTagPriority(NonPagedPool, SAC_MEMORY_LIST_SIZE, INITIAL_BLOCK_TAG, HighPoolPriority); if (GlobalMemoryList) { /* Initialize a lock for it */ KeInitializeSpinLock(&MemoryLock);
/* Initialize the head of the list */ GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE; GlobalMemoryList->LocalDescriptor = (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1); GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST); GlobalMemoryList->Next = NULL;
/* Initialize the first free entry */ Entry = GlobalMemoryList->LocalDescriptor; Entry->Signature = LOCAL_MEMORY_SIGNATURE; Entry->Tag = FREE_POOL_TAG; Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
/* All done */ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n"); return TRUE; }
/* No pool available to manage our heap */ SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n"); return FALSE;}
VOIDNTAPIFreeMemoryManagement(VOID){ PSAC_MEMORY_LIST Next; KIRQL OldIrql; SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
/* Acquire the memory lock while freeing the list(s) */ KeAcquireSpinLock(&MemoryLock, &OldIrql); while (GlobalMemoryList) { ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
/* While outside of the lock, save the next list and free this one */ KeReleaseSpinLock(&MemoryLock, OldIrql); Next = GlobalMemoryList->Next; ExFreePoolWithTag(GlobalMemoryList, 0);
/* Reacquire the lock and see if there was another list to free */ KeAcquireSpinLock(&MemoryLock, &OldIrql); GlobalMemoryList = Next; }
/* All done */ KeReleaseSpinLock(&MemoryLock, OldIrql); SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");}
PVOIDNTAPIMyAllocatePool(IN SIZE_T PoolSize, IN ULONG Tag, IN PCHAR File, IN ULONG Line){ PVOID p; p = ExAllocatePoolWithTag(NonPagedPool, PoolSize, 'HACK'); RtlZeroMemory(p, PoolSize); SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", p); return p;#if 0 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");
/* Acquire the memory allocation lock and align the size request */ KeAcquireSpinLock(&MemoryLock, &OldIrql); PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
#if _USE_SAC_HEAP_ALLOCATOR_ 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(NonPagedPool, 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; } }#else /* Shut the compiler up */ NewDescriptor = GlobalDescriptor = NULL; GlobalSize = (ULONG)NewDescriptor; ActualSize = GlobalSize; NextDescriptor = (PVOID)ActualSize; NewDescriptor = (PVOID)NextDescriptor;
/* Use the NT pool allocator */ LocalDescriptor = ExAllocatePoolWithTag(NonPagedPool, PoolSize + sizeof(*LocalDescriptor), Tag); LocalDescriptor->Size = PoolSize;#endif /* Set the tag, and release the lock */ LocalDescriptor->Tag = Tag; KeReleaseSpinLock(&MemoryLock, OldIrql);
/* Update our performance counters */ InterlockedIncrement(&TotalAllocations); InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
/* Return the buffer and zero it */ SAC_DBG(SAC_DBG_MM, "Returning block 0x%X.\n", LocalDescriptor); Buffer = LocalDescriptor + 1; RtlZeroMemory(Buffer, PoolSize); return Buffer;#endif}
VOIDNTAPIMyFreePool(IN PVOID *Block){#if 0 PSAC_MEMORY_ENTRY NextDescriptor; PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor; PSAC_MEMORY_ENTRY LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY)); ULONG GlobalSize, LocalSize; PSAC_MEMORY_LIST GlobalDescriptor; KIRQL OldIrql; SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
/* Make sure this was a valid entry */ ASSERT(LocalDescriptor->Size > 0); ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
/* Update performance counters */ InterlockedIncrement(&TotalFrees); InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
/* Acquire the memory allocation lock */ GlobalDescriptor = GlobalMemoryList; KeAcquireSpinLock(&MemoryLock, &OldIrql);
#if _USE_SAC_HEAP_ALLOCATOR_ 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)); }#else /* Shut the compiler up */ LocalSize = GlobalSize = 0; ThisDescriptor = (PVOID)LocalSize; NextDescriptor = (PVOID)GlobalSize; GlobalDescriptor = (PVOID)ThisDescriptor; FoundDescriptor = (PVOID)GlobalDescriptor; GlobalDescriptor = (PVOID)NextDescriptor; NextDescriptor = (PVOID)FoundDescriptor;
/* Use the NT pool allocator*/ ExFreePool(LocalDescriptor);#endif
/* Release the lock, delete the address, and return */ KeReleaseSpinLock(&MemoryLock, OldIrql);#endif SAC_DBG(SAC_DBG_MM, "exiting: 0x%p.\n", *Block); ExFreePoolWithTag(*Block, 'HACK'); *Block = NULL;}