Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmemory.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
1.7.6.1
|