Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencmalloc.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/config/cmalloc.c 00005 * PURPOSE: Routines for allocating and freeing registry structures 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* GLOBALS *******************************************************************/ 00016 00017 BOOLEAN CmpAllocInited; 00018 KGUARDED_MUTEX CmpAllocBucketLock, CmpDelayAllocBucketLock; 00019 00020 LIST_ENTRY CmpFreeKCBListHead; 00021 KGUARDED_MUTEX CmpDelayAllocBucketLock; 00022 LIST_ENTRY CmpFreeDelayItemsListHead; 00023 00024 /* FUNCTIONS *****************************************************************/ 00025 00026 VOID 00027 NTAPI 00028 INIT_FUNCTION 00029 CmpInitCmPrivateAlloc(VOID) 00030 { 00031 /* Make sure we didn't already do this */ 00032 if (!CmpAllocInited) 00033 { 00034 /* Setup the lock and list */ 00035 KeInitializeGuardedMutex(&CmpAllocBucketLock); 00036 InitializeListHead(&CmpFreeKCBListHead); 00037 CmpAllocInited = TRUE; 00038 } 00039 } 00040 00041 VOID 00042 NTAPI 00043 INIT_FUNCTION 00044 CmpInitCmPrivateDelayAlloc(VOID) 00045 { 00046 /* Initialize the delay allocation list and lock */ 00047 KeInitializeGuardedMutex(&CmpDelayAllocBucketLock); 00048 InitializeListHead(&CmpFreeDelayItemsListHead); 00049 } 00050 00051 VOID 00052 NTAPI 00053 CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb) 00054 { 00055 ULONG i; 00056 PCM_ALLOC_PAGE AllocPage; 00057 PAGED_CODE(); 00058 00059 /* Sanity checks */ 00060 ASSERT(IsListEmpty(&Kcb->KeyBodyListHead) == TRUE); 00061 for (i = 0; i < 4; i++) ASSERT(Kcb->KeyBodyArray[i] == NULL); 00062 00063 /* Check if it wasn't privately allocated */ 00064 if (!Kcb->PrivateAlloc) 00065 { 00066 /* Free it from the pool */ 00067 CmpFree(Kcb, 0); 00068 return; 00069 } 00070 00071 /* Acquire the private allocation lock */ 00072 KeAcquireGuardedMutex(&CmpAllocBucketLock); 00073 00074 /* Sanity check on lock ownership */ 00075 CMP_ASSERT_HASH_ENTRY_LOCK(Kcb->ConvKey); 00076 00077 /* Add us to the free list */ 00078 InsertTailList(&CmpFreeKCBListHead, &Kcb->FreeListEntry); 00079 00080 /* Get the allocation page */ 00081 AllocPage = CmpGetAllocPageFromKcb(Kcb); 00082 00083 /* Sanity check */ 00084 ASSERT(AllocPage->FreeCount != CM_KCBS_PER_PAGE); 00085 00086 /* Increase free count */ 00087 if (++AllocPage->FreeCount == CM_KCBS_PER_PAGE) 00088 { 00089 /* Loop all the entries */ 00090 for (i = 0; i < CM_KCBS_PER_PAGE; i++) 00091 { 00092 /* Get the KCB */ 00093 Kcb = (PVOID)((ULONG_PTR)AllocPage + 00094 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) + 00095 i * sizeof(CM_KEY_CONTROL_BLOCK)); 00096 00097 /* Remove the entry */ 00098 RemoveEntryList(&Kcb->FreeListEntry); 00099 } 00100 00101 /* Free the page */ 00102 CmpFree(AllocPage, 0); 00103 } 00104 00105 /* Release the lock */ 00106 KeReleaseGuardedMutex(&CmpAllocBucketLock); 00107 } 00108 00109 PCM_KEY_CONTROL_BLOCK 00110 NTAPI 00111 CmpAllocateKeyControlBlock(VOID) 00112 { 00113 PLIST_ENTRY NextEntry; 00114 PCM_KEY_CONTROL_BLOCK CurrentKcb; 00115 PCM_ALLOC_PAGE AllocPage; 00116 ULONG i; 00117 PAGED_CODE(); 00118 00119 /* Check if private allocations are initialized */ 00120 if (CmpAllocInited) 00121 { 00122 /* They are, acquire the bucket lock */ 00123 KeAcquireGuardedMutex(&CmpAllocBucketLock); 00124 00125 /* See if there's something on the free KCB list */ 00126 SearchKcbList: 00127 if (!IsListEmpty(&CmpFreeKCBListHead)) 00128 { 00129 /* Remove the entry */ 00130 NextEntry = RemoveHeadList(&CmpFreeKCBListHead); 00131 00132 /* Get the KCB */ 00133 CurrentKcb = CONTAINING_RECORD(NextEntry, 00134 CM_KEY_CONTROL_BLOCK, 00135 FreeListEntry); 00136 00137 /* Get the allocation page */ 00138 AllocPage = CmpGetAllocPageFromKcb(CurrentKcb); 00139 00140 /* Decrease the free count */ 00141 ASSERT(AllocPage->FreeCount != 0); 00142 AllocPage->FreeCount--; 00143 00144 /* Make sure this KCB is privately allocated */ 00145 ASSERT(CurrentKcb->PrivateAlloc == 1); 00146 00147 /* Release the allocation lock */ 00148 KeReleaseGuardedMutex(&CmpAllocBucketLock); 00149 00150 /* Return the KCB */ 00151 return CurrentKcb; 00152 } 00153 00154 /* Allocate an allocation page */ 00155 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_CM); 00156 if (AllocPage) 00157 { 00158 /* Set default entries */ 00159 AllocPage->FreeCount = CM_KCBS_PER_PAGE; 00160 00161 /* Loop each entry */ 00162 for (i = 0; i < CM_KCBS_PER_PAGE; i++) 00163 { 00164 /* Get this entry */ 00165 CurrentKcb = (PVOID)((ULONG_PTR)AllocPage + 00166 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) + 00167 i * sizeof(CM_KEY_CONTROL_BLOCK)); 00168 00169 /* Set it up */ 00170 CurrentKcb->PrivateAlloc = TRUE; 00171 CurrentKcb->DelayCloseEntry = NULL; 00172 InsertTailList(&CmpFreeKCBListHead, 00173 &CurrentKcb->FreeListEntry); 00174 } 00175 00176 /* Now go back and search the list */ 00177 goto SearchKcbList; 00178 } 00179 } 00180 00181 /* Allocate a KCB only */ 00182 CurrentKcb = CmpAllocate(sizeof(CM_KEY_CONTROL_BLOCK), TRUE, TAG_CM); 00183 if (CurrentKcb) 00184 { 00185 /* Set it up */ 00186 CurrentKcb->PrivateAlloc = 0; 00187 CurrentKcb->DelayCloseEntry = NULL; 00188 } 00189 00190 /* Return it */ 00191 return CurrentKcb; 00192 } 00193 00194 PVOID 00195 NTAPI 00196 CmpAllocateDelayItem(VOID) 00197 { 00198 PCM_DELAY_ALLOC Entry; 00199 PCM_ALLOC_PAGE AllocPage; 00200 ULONG i; 00201 PLIST_ENTRY NextEntry; 00202 PAGED_CODE(); 00203 00204 /* Lock the allocation buckets */ 00205 KeAcquireGuardedMutex(&CmpDelayAllocBucketLock); 00206 00207 /* Look for an item on the free list */ 00208 SearchList: 00209 if (!IsListEmpty(&CmpFreeDelayItemsListHead)) 00210 { 00211 /* Get the current entry in the list */ 00212 NextEntry = RemoveHeadList(&CmpFreeDelayItemsListHead); 00213 00214 /* Grab the item */ 00215 Entry = CONTAINING_RECORD(NextEntry, CM_DELAY_ALLOC, ListEntry); 00216 00217 /* Clear the list */ 00218 Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL; 00219 00220 /* Grab the alloc page */ 00221 AllocPage = CmpGetAllocPageFromDelayAlloc(Entry); 00222 00223 /* Decrease free entries */ 00224 ASSERT(AllocPage->FreeCount != 0); 00225 AllocPage->FreeCount--; 00226 00227 /* Release the lock */ 00228 KeReleaseGuardedMutex(&CmpDelayAllocBucketLock); 00229 return Entry; 00230 } 00231 00232 /* Allocate an allocation page */ 00233 AllocPage = CmpAllocate(PAGE_SIZE, TRUE, TAG_CM); 00234 if (AllocPage) 00235 { 00236 /* Set default entries */ 00237 AllocPage->FreeCount = CM_DELAYS_PER_PAGE; 00238 00239 /* Loop each entry */ 00240 for (i = 0; i < CM_DELAYS_PER_PAGE; i++) 00241 { 00242 /* Get this entry and link it */ 00243 Entry = (PVOID)((ULONG_PTR)AllocPage + 00244 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) + 00245 i * sizeof(CM_DELAY_ALLOC)); 00246 InsertTailList(&CmpFreeDelayItemsListHead, 00247 &Entry->ListEntry); 00248 00249 /* Clear the KCB pointer */ 00250 Entry->Kcb = NULL; 00251 } 00252 } 00253 else 00254 { 00255 /* Release the lock */ 00256 KeReleaseGuardedMutex(&CmpDelayAllocBucketLock); 00257 return NULL; 00258 } 00259 00260 /* Do the search again */ 00261 goto SearchList; 00262 } 00263 00264 VOID 00265 NTAPI 00266 CmpFreeDelayItem(PVOID Entry) 00267 { 00268 PCM_DELAY_ALLOC AllocEntry = (PCM_DELAY_ALLOC)Entry; 00269 PCM_ALLOC_PAGE AllocPage; 00270 ULONG i; 00271 PAGED_CODE(); 00272 00273 /* Lock the table */ 00274 KeAcquireGuardedMutex(&CmpDelayAllocBucketLock); 00275 00276 /* Add the entry at the end */ 00277 InsertTailList(&CmpFreeDelayItemsListHead, &AllocEntry->ListEntry); 00278 00279 /* Get the alloc page */ 00280 AllocPage = CmpGetAllocPageFromDelayAlloc(Entry); 00281 ASSERT(AllocPage->FreeCount != CM_DELAYS_PER_PAGE); 00282 00283 /* Increase the number of free items */ 00284 if (++AllocPage->FreeCount == CM_DELAYS_PER_PAGE) 00285 { 00286 /* Page is totally free now, loop each entry */ 00287 for (i = 0; i < CM_DELAYS_PER_PAGE; i++) 00288 { 00289 /* Get the entry and unlink it */ 00290 AllocEntry = (PVOID)((ULONG_PTR)AllocPage + 00291 FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) + 00292 i * sizeof(CM_DELAY_ALLOC)); 00293 RemoveEntryList(&AllocEntry->ListEntry); 00294 } 00295 00296 /* Now free the page */ 00297 CmpFree(AllocPage, 0); 00298 } 00299 00300 /* Release the lock */ 00301 KeReleaseGuardedMutex(&CmpDelayAllocBucketLock); 00302 } Generated on Sun May 27 2012 04:37:05 for ReactOS by
1.7.6.1
|