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

cmalloc.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 doxygen 1.7.6.1

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