ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

memory.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:      ReactOS Boot Loader
00003  * LICENSE:      BSD - See COPYING.ARM in the top level directory
00004  * FILE:         drivers/sac/driver/memory.c
00005  * PURPOSE:      Driver for the Server Administration Console (SAC) for EMS
00006  * PROGRAMMERS:  ReactOS Portable Systems Group
00007  */
00008 
00009 /* INCLUDES *******************************************************************/
00010 
00011 #include "sacdrv.h"
00012 
00013 /* GLOBALS ********************************************************************/
00014 
00015 LONG TotalFrees, TotalBytesFreed, TotalAllocations, TotalBytesAllocated;
00016 KSPIN_LOCK MemoryLock;
00017 PSAC_MEMORY_LIST GlobalMemoryList;
00018 
00019 /* FUNCTIONS ******************************************************************/
00020 
00021 BOOLEAN
00022 InitializeMemoryManagement(VOID)
00023 {
00024     PSAC_MEMORY_ENTRY Entry;
00025 
00026     SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
00027 
00028     GlobalMemoryList = ExAllocatePoolWithTagPriority(
00029         NonPagedPool,
00030         SAC_MEMORY_LIST_SIZE,
00031         INITIAL_BLOCK_TAG,
00032         HighPoolPriority);
00033     if (GlobalMemoryList)
00034     {
00035         KeInitializeSpinLock(&MemoryLock);
00036 
00037         GlobalMemoryList->Signature = GLOBAL_MEMORY_SIGNATURE;
00038         GlobalMemoryList->LocalDescriptor =
00039             (PSAC_MEMORY_ENTRY)(GlobalMemoryList + 1);
00040         GlobalMemoryList->Size = SAC_MEMORY_LIST_SIZE - sizeof(SAC_MEMORY_LIST);
00041 
00042         Entry = GlobalMemoryList->LocalDescriptor;
00043         Entry->Signature = LOCAL_MEMORY_SIGNATURE;
00044         Entry->Tag = FREE_POOL_TAG;
00045         Entry->Size = GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
00046 
00047         SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with TRUE.\n");
00048         return TRUE;
00049     }
00050 
00051     SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting with FALSE. No pool.\n");
00052     return FALSE;
00053 }
00054 
00055 VOID
00056 FreeMemoryManagement(
00057     VOID
00058     )
00059 {
00060     PSAC_MEMORY_LIST Next;
00061     KIRQL OldIrql;
00062 
00063     SAC_DBG(SAC_DBG_ENTRY_EXIT, "Entering\n");
00064 
00065     KeAcquireSpinLock(&MemoryLock, &OldIrql);
00066     while (GlobalMemoryList)
00067     {
00068         ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
00069 
00070         KeReleaseSpinLock(&MemoryLock, OldIrql);
00071 
00072         Next = GlobalMemoryList->Next;
00073 
00074         ExFreePoolWithTag(GlobalMemoryList, 0);
00075 
00076         KeAcquireSpinLock(&MemoryLock, &OldIrql);
00077         GlobalMemoryList = Next;
00078     }
00079 
00080     KeReleaseSpinLock(&MemoryLock, OldIrql);
00081     SAC_DBG(SAC_DBG_ENTRY_EXIT, "Exiting\n");
00082 }
00083 
00084 PVOID
00085 MyAllocatePool(
00086     IN SIZE_T PoolSize,
00087     IN ULONG Tag,
00088     IN PCHAR File,
00089     IN ULONG Line
00090     )
00091 {
00092     KIRQL OldIrql;
00093     PSAC_MEMORY_LIST GlobalDescriptor, NewDescriptor;
00094     PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
00095     ULONG GlobalSize, ActualSize;
00096     PVOID Buffer;
00097 
00098     ASSERT("Tag != FREE_POOL_TAG");
00099 
00100     SAC_DBG(SAC_DBG_MM, "Entering.\n");
00101 
00102     OldIrql = KfAcquireSpinLock(&MemoryLock);
00103     PoolSize = ALIGN_UP(PoolSize, ULONGLONG);
00104 
00105     GlobalDescriptor = GlobalMemoryList;
00106     KeAcquireSpinLock(&MemoryLock, &OldIrql);
00107     while (GlobalDescriptor)
00108     {
00109         ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
00110 
00111         LocalDescriptor = GlobalDescriptor->LocalDescriptor;
00112 
00113         GlobalSize = GlobalDescriptor->Size;
00114         while (GlobalSize)
00115         {
00116             ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
00117 
00118             if ((LocalDescriptor->Tag == FREE_POOL_TAG) &&
00119                 (LocalDescriptor->Size >= PoolSize))
00120             {
00121                 break;
00122             }
00123 
00124             GlobalSize -= (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
00125 
00126             LocalDescriptor =
00127                 (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
00128                 LocalDescriptor->Size +
00129                 sizeof(SAC_MEMORY_ENTRY));
00130         }
00131 
00132         GlobalDescriptor = GlobalDescriptor->Next;
00133     }
00134 
00135     if (!GlobalDescriptor)
00136     {
00137         KeReleaseSpinLock(&MemoryLock, OldIrql);
00138 
00139         ActualSize = min(
00140             PAGE_SIZE,
00141             PoolSize + sizeof(SAC_MEMORY_ENTRY) + sizeof(SAC_MEMORY_LIST));
00142 
00143         SAC_DBG(SAC_DBG_MM, "Allocating new space.\n");
00144 
00145         NewDescriptor = ExAllocatePoolWithTagPriority(
00146             0,
00147             ActualSize,
00148             ALLOC_BLOCK_TAG,
00149             HighPoolPriority);
00150         if (!NewDescriptor)
00151         {
00152             SAC_DBG(SAC_DBG_MM, "No more memory, returning NULL.\n");
00153             return NULL;
00154         }
00155 
00156         KeAcquireSpinLock(&MemoryLock, &OldIrql);
00157 
00158         NewDescriptor->Signature = GLOBAL_MEMORY_SIGNATURE;
00159         NewDescriptor->LocalDescriptor = (PSAC_MEMORY_ENTRY)(NewDescriptor + 1);
00160         NewDescriptor->Size = ActualSize - 16;
00161         NewDescriptor->Next = GlobalMemoryList;
00162 
00163         GlobalMemoryList = NewDescriptor;
00164 
00165         LocalDescriptor = NewDescriptor->LocalDescriptor;
00166         LocalDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
00167         LocalDescriptor->Tag = FREE_POOL_TAG;
00168         LocalDescriptor->Size =
00169             GlobalMemoryList->Size - sizeof(SAC_MEMORY_ENTRY);
00170     }
00171 
00172     SAC_DBG(SAC_DBG_MM, "Found a good sized block.\n");
00173     ASSERT(LocalDescriptor->Tag == FREE_POOL_TAG);
00174     ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
00175 
00176     if (LocalDescriptor->Size > (PoolSize + sizeof(SAC_MEMORY_ENTRY)))
00177     {
00178         NextDescriptor =
00179             (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
00180             PoolSize +
00181             sizeof(SAC_MEMORY_ENTRY));
00182         if (NextDescriptor->Tag == FREE_POOL_TAG)
00183         {
00184             NextDescriptor->Tag = FREE_POOL_TAG;
00185             NextDescriptor->Signature = LOCAL_MEMORY_SIGNATURE;
00186             NextDescriptor->Size =
00187                 (LocalDescriptor->Size - PoolSize - sizeof(SAC_MEMORY_ENTRY));
00188 
00189             LocalDescriptor->Size = PoolSize;
00190         }
00191     }
00192 
00193     LocalDescriptor->Tag = Tag;
00194     KeReleaseSpinLock(&MemoryLock, OldIrql);
00195 
00196     InterlockedIncrement(&TotalAllocations);
00197     InterlockedExchangeAdd(&TotalBytesAllocated, LocalDescriptor->Size);
00198     SAC_DBG(1, "Returning block 0x%X.\n", LocalDescriptor);
00199 
00200     Buffer = LocalDescriptor + 1;
00201     RtlZeroMemory(Buffer, PoolSize);
00202     return Buffer;
00203 }
00204 
00205 VOID
00206 MyFreePool(
00207     IN PVOID *Block
00208     )
00209 {
00210     PSAC_MEMORY_ENTRY LocalDescriptor, NextDescriptor;
00211     PSAC_MEMORY_ENTRY ThisDescriptor, FoundDescriptor;
00212     ULONG GlobalSize, LocalSize;
00213     PSAC_MEMORY_LIST GlobalDescriptor;
00214     KIRQL OldIrql;
00215 
00216     LocalDescriptor = (PVOID)((ULONG_PTR)(*Block) - sizeof(SAC_MEMORY_ENTRY));
00217 
00218     SAC_DBG(SAC_DBG_MM, "Entering with block 0x%X.\n", LocalDescriptor);
00219 
00220     ASSERT(LocalDescriptor->Size > 0);
00221     ASSERT(LocalDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
00222 
00223     InterlockedIncrement(&TotalFrees);
00224 
00225     InterlockedExchangeAdd(&TotalBytesFreed, LocalDescriptor->Size);
00226 
00227     GlobalDescriptor = GlobalMemoryList;
00228     KeAcquireSpinLock(&MemoryLock, &OldIrql);
00229     while (GlobalDescriptor)
00230     {
00231         ASSERT(GlobalMemoryList->Signature == GLOBAL_MEMORY_SIGNATURE);
00232 
00233         FoundDescriptor = NULL;
00234 
00235         ThisDescriptor = GlobalDescriptor->LocalDescriptor;
00236 
00237         GlobalSize = GlobalDescriptor->Size;
00238         while (GlobalSize)
00239         {
00240             ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
00241 
00242             if (ThisDescriptor == LocalDescriptor) break;
00243 
00244             GlobalSize -= (ThisDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
00245 
00246             ThisDescriptor =
00247                 (PSAC_MEMORY_ENTRY)((ULONG_PTR)ThisDescriptor +
00248                 ThisDescriptor->Size +
00249                 sizeof(SAC_MEMORY_ENTRY));
00250         }
00251 
00252         if (ThisDescriptor == LocalDescriptor) break;
00253 
00254         GlobalDescriptor = GlobalDescriptor->Next;
00255     }
00256 
00257     if (!GlobalDescriptor)
00258     {
00259         KeReleaseSpinLock(&MemoryLock, OldIrql);
00260         SAC_DBG(SAC_DBG_MM, "Could not find block.\n");
00261         return;
00262     }
00263 
00264     ASSERT(ThisDescriptor->Signature == LOCAL_MEMORY_SIGNATURE);
00265 
00266     if (LocalDescriptor->Tag == FREE_POOL_TAG)
00267     {
00268         KeReleaseSpinLock(&MemoryLock, OldIrql);
00269         SAC_DBG(SAC_DBG_MM, "Attempted to free something twice.\n");
00270         return;
00271     }
00272 
00273     LocalSize = LocalDescriptor->Size;
00274     LocalDescriptor->Tag = FREE_POOL_TAG;
00275 
00276     if (GlobalSize > (LocalSize + sizeof(SAC_MEMORY_ENTRY)))
00277     {
00278         NextDescriptor =
00279             (PSAC_MEMORY_ENTRY)((ULONG_PTR)LocalDescriptor +
00280             LocalSize +
00281             sizeof(SAC_MEMORY_ENTRY));
00282         if (NextDescriptor->Tag == FREE_POOL_TAG)
00283         {
00284             NextDescriptor->Tag = 0;
00285             NextDescriptor->Signature = 0;
00286 
00287             LocalDescriptor->Size +=
00288                 (NextDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
00289         }
00290     }
00291 
00292     if ((FoundDescriptor) && (FoundDescriptor->Tag == FREE_POOL_TAG))
00293     {
00294         LocalDescriptor->Signature = 0;
00295         LocalDescriptor->Tag = 0;
00296 
00297         FoundDescriptor->Size +=
00298             (LocalDescriptor->Size + sizeof(SAC_MEMORY_ENTRY));
00299     }
00300 
00301     KeReleaseSpinLock(&MemoryLock, OldIrql);
00302     *Block = NULL;
00303 
00304     SAC_DBG(SAC_DBG_MM, "exiting.\n");
00305     return;
00306 }

Generated on Mon May 28 2012 04:18:01 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.