Author: fireball
Date: Sun Oct 28 21:20:48 2007
New Revision: 29933
URL:
http://svn.reactos.org/svn/reactos?rev=29933&view=rev
Log:
- Fix code that tried to get a KCB from the alloc page.
- Fix code that wasn't using CM_DELAY_ALLOC for delay allocation entries, but was
using CM_DELAYED_CLOSE_ENTRY instead.
- Fix definition of CM_DELAYED_CLOSE_ENTRY.
- Fill out the CmpMachineHiveList.
- Fix various callers of list-entry functions which were sending inverted parameters
(entry instead of head)
- Implement CmpInitializeDelayedCloseTable to do some work that CmpInitializeCache used to
do.
- Implement new locking macro: CmpConvertKcbSharedToExclusive and use it.
- Rename more functions to their real names, expanding "Kcb" to
"KeyControlBlock" when necessary.
- CmpInitializeCache:
Calculate size based on hash table entries, not pointers to key hashes.
The locks need to be initialized, not the whole structure zeroed out.
- CmpFreeKeyControlBlock: Fix code that gets the KCB and removes it from the list -- it
was missing.
- CmpReferenceKeyControlBlock:
* Use DelayedCloseIndex instead of "Delete".
* Do not add + 1 to InterlockedIncrement's result
- CmpDelayDerefKeyControlBlock:
* Insert the entry at the tail, not the head.
* Check if the worker is inactive, not if it's acvice.
* Remove the KCB before freeing it.
* Use DelayedCloseIndex, not delete.
- CmpAllocateKeyControlBlock/CmpAllocateDelayItem:
* Simplify and fix list lookup.
* Simplify algorithm with a goto.
- CmpDereferenceKeyControlBlockWithLock:
* Make it actually decrement the reference count.
* Use Delete flag instead of PrivateAlloc flag.
Modified:
branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h
branches/alex-cm-branch/reactos/ntoskrnl/cm/cmdata.c
branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c
branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c
branches/alex-cm-branch/reactos/ntoskrnl/cm/cmutil.c
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm.h Sun Oct 28 21:20:48 2007
@@ -338,6 +338,15 @@
ULONG Reserved;
PVOID AllocPage;
} CM_ALLOC_PAGE, *PCM_ALLOC_PAGE;
+
+//
+// Allocation Page Entry
+//
+typedef struct _CM_DELAY_ALLOC
+{
+ LIST_ENTRY ListEntry;
+ PCM_KEY_CONTROL_BLOCK Kcb;
+} CM_DELAY_ALLOC, *PCM_DELAY_ALLOC;
//
// Delayed Close Entry
@@ -574,7 +583,6 @@
{
PWCHAR FileName;
PWCHAR BaseName;
- PWCHAR RegRootName;
PCMHIVE CmHive;
ULONG HHiveFlags;
ULONG CmHiveFlags;
@@ -582,7 +590,6 @@
BOOLEAN ThreadFinished;
BOOLEAN ThreadStarted;
BOOLEAN Allocate;
- BOOLEAN WinPERequired;
} HIVE_LIST_ENTRY, *PHIVE_LIST_ENTRY;
//
@@ -853,8 +860,6 @@
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);
-/* NOTE: This function declaration is currently duplicated in both */
-/* cm/cm.h and config/cm.h. TODO: Pick one single place to declare it. */
NTSTATUS
NTAPI
CmpOpenHiveFiles(
@@ -919,7 +924,7 @@
VOID
NTAPI
-CmpDereferenceKcbWithLock(
+CmpDereferenceKeyControlBlockWithLock(
IN PCM_KEY_CONTROL_BLOCK Kcb,
IN BOOLEAN LockHeldExclusively
);
@@ -1285,7 +1290,7 @@
extern ULONG CmpConfigurationAreaSize;
extern PCM_FULL_RESOURCE_DESCRIPTOR CmpConfigurationData;
extern UNICODE_STRING CmTypeName[];
-extern HIVE_LIST_ENTRY CmpMachineHiveList[5];
+extern HIVE_LIST_ENTRY CmpMachineHiveList[];
extern UNICODE_STRING CmSymbolicLinkValueName;
extern UNICODE_STRING CmpSystemStartOptions;
extern UNICODE_STRING CmpLoadOptions;
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cm_x.h Sun Oct 28 21:20:48 2007
@@ -200,6 +200,18 @@
}
//
+// Converts a KCB lock
+//
+FORCEINLINE
+VOID
+CmpConvertKcbSharedToExclusive(IN PCM_KEY_CONTROL_BLOCK k)
+{
+ ASSERT(CmpIsKcbLockedExclusive(k) == FALSE);
+ CmpReleaseKcbLock(k);
+ CmpAcquireKcbLockExclusive(k);
+}
+
+//
// Exclusively acquires an NCB
//
#define CmpAcquireNcbLockExclusive(n) \
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmdata.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmdata.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmdata.c Sun Oct 28 21:20:48 2007
@@ -38,7 +38,30 @@
EX_PUSH_LOCK CmpHiveListHeadLock, CmpLoadHiveLock;
-HIVE_LIST_ENTRY CmpMachineHiveList[5];
+HIVE_LIST_ENTRY CmpMachineHiveList[] =
+{
+ {
+ L"HARDWARE", L"MACHINE\\", NULL, HIVE_VOLATILE, 0, NULL,
FALSE, FALSE, FALSE
+ },
+ {
+ L"SECURITY", L"MACHINE\\", NULL, 0, 0, NULL, FALSE, FALSE,
FALSE
+ },
+ {
+ L"SOFTWARE", L"MACHINE\\", NULL, 0, 0, NULL, FALSE, FALSE,
FALSE
+ },
+ {
+ L"SYSTEM", L"MACHINE\\", NULL, 0, 0, NULL, FALSE, FALSE,
FALSE
+ },
+ {
+ L"DEFAULT", L"USER\\.DEFAULT", NULL, 0, 1, NULL, FALSE,
FALSE, FALSE
+ },
+ {
+ L"SAM", L"MACHINE\\", NULL, HIVE_NOLAZYFLUSH, 0, NULL, FALSE,
FALSE, FALSE
+ },
+ {
+ NULL, NULL, 0, 0, 0, NULL, FALSE, FALSE, FALSE
+ }
+};
UNICODE_STRING CmSymbolicLinkValueName =
RTL_CONSTANT_STRING(L"SymbolicLinkValue");
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cminit.c Sun Oct 28 21:20:48 2007
@@ -31,8 +31,6 @@
BOOLEAN CmSelfHeal, CmpSelfHeal;
KGUARDED_MUTEX CmpSelfHealQueueLock;
LIST_ENTRY CmpSelfHealQueueListHead;
-
-HIVE_LIST_ENTRY CmpMachineHiveList[];
EX_PUSH_LOCK CmpLoadHiveLock;
@@ -335,8 +333,8 @@
ValueName.Length);
Quickie:
- /* Free the buffers */
- RtlFreeUnicodeString(&ValueName);
+ /* Free the buffers */
+ RtlFreeUnicodeString(&ValueName);
/* Close the key and return */
NtClose(KeyHandle);
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmkcbncb.c Sun Oct 28 21:20:48 2007
@@ -71,39 +71,72 @@
ASSERT(CmpDelayCloseWorkItemActive);
/* FIXME: TODO */
-}
-
-VOID
-NTAPI
-CmpInitializeCache(VOID)
-{
- ULONG Length;
-
- /* Calculate length for the table */
- Length = CmpHashTableSize * sizeof(PCM_KEY_HASH);
-
- /* Allocate it */
- CmpCacheTable = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
- if (!CmpCacheTable) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
- RtlZeroMemory(CmpCacheTable, Length);
-
- /* Calculate length for the name cache */
- Length = CmpHashTableSize * sizeof(PCM_NAME_HASH);
-
- /* Now allocate the name cache table */
- CmpNameCacheTable = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
- if (!CmpCacheTable) KeBugCheck(CONFIG_INITIALIZATION_FAILED);
- RtlZeroMemory(CmpNameCacheTable, Length);
+ ASSERT(FALSE);
+}
+
+VOID
+NTAPI
+CmpInitializeDelayedCloseTable(VOID)
+{
/* Setup the delayed close lock */
KeInitializeGuardedMutex(&CmpDelayedCloseTableLock);
/* Setup the work item */
ExInitializeWorkItem(&CmpDelayCloseWorkItem, CmpDelayCloseWorker, NULL);
+
+ /* Setup the list head */
+ InitializeListHead(&CmpDelayedLRUListHead);
/* Setup the DPC and its timer */
KeInitializeDpc(&CmpDelayCloseDpc, CmpDelayCloseDpcRoutine, NULL);
KeInitializeTimer(&CmpDelayCloseTimer);
+}
+
+VOID
+NTAPI
+CmpInitializeCache(VOID)
+{
+ ULONG Length, i;
+
+ /* Calculate length for the table */
+ Length = CmpHashTableSize * sizeof(CM_KEY_HASH_TABLE_ENTRY);
+
+ /* Allocate it */
+ CmpCacheTable = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
+ if (!CmpCacheTable)
+ {
+ /* Take the system down */
+ KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 1, 0, 0);
+ }
+
+ /* Initialize the locks */
+ for (i = 0;i < CmpHashTableSize; i++)
+ {
+ /* Setup the pushlock */
+ ExInitializePushLock((PULONG_PTR)&CmpCacheTable[i].Lock);
+ }
+
+ /* Calculate length for the name cache */
+ Length = CmpHashTableSize * sizeof(CM_NAME_HASH_TABLE_ENTRY);
+
+ /* Now allocate the name cache table */
+ CmpNameCacheTable = ExAllocatePoolWithTag(PagedPool, Length, TAG_CM);
+ if (!CmpNameCacheTable)
+ {
+ /* Take the system down */
+ KeBugCheckEx(CONFIG_INITIALIZATION_FAILED, 3, 3, 0, 0);
+ }
+
+ /* Initialize the locks */
+ for (i = 0;i < CmpHashTableSize; i++)
+ {
+ /* Setup the pushlock */
+ ExInitializePushLock((PULONG_PTR)&CmpNameCacheTable[i].Lock);
+ }
+
+ /* Setup the delayed close table */
+ CmpInitializeDelayedCloseTable();
}
VOID
@@ -153,6 +186,7 @@
ASSERT(CmpDelayDerefKCBWorkItemActive);
/* FIXME: TODO */
+ ASSERT(FALSE);
}
VOID
@@ -340,7 +374,7 @@
VOID
NTAPI
-CmpRemoveKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
+CmpRemoveKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
/* Make sure that the registry and KCB are utterly locked */
ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
@@ -352,7 +386,7 @@
VOID
NTAPI
-CmpFreeKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
+CmpFreeKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
ULONG i;
PCM_ALLOC_PAGE AllocPage;
@@ -367,43 +401,47 @@
{
/* Free it from the pool */
ExFreePool(Kcb);
- }
- else
- {
- /* Acquire the private allocation lock */
- KeAcquireGuardedMutex(&CmpAllocBucketLock);
-
- /* Sanity check on lock ownership */
- ASSERT((GET_HASH_ENTRY(CmpCacheTable, Kcb->ConvKey).Owner ==
- KeGetCurrentThread()) ||
- (CmpTestRegistryLockExclusive() == TRUE));
-
- /* Remove us from the list */
- RemoveEntryList(&CmpFreeKCBListHead);
-
- /* Get the allocation page */
- AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)Kcb & 0xFFFFF000);
-
- /* Sanity check */
- ASSERT(AllocPage->FreeCount != CM_KCBS_PER_PAGE);
-
- /* Increase free count */
- if (++AllocPage->FreeCount == CM_KCBS_PER_PAGE)
- {
- /* Loop all the entries */
- for (i = CM_KCBS_PER_PAGE; i; i--)
- {
- /* Remove the entry
- RemoveEntryList(& */
- }
-
- /* Free the page */
- ExFreePool(AllocPage);
- }
-
- /* Release the lock */
- KeReleaseGuardedMutex(&CmpAllocBucketLock);
- }
+ return;
+ }
+
+ /* Acquire the private allocation lock */
+ KeAcquireGuardedMutex(&CmpAllocBucketLock);
+
+ /* Sanity check on lock ownership */
+ ASSERT((GET_HASH_ENTRY(CmpCacheTable, Kcb->ConvKey).Owner ==
+ KeGetCurrentThread()) ||
+ (CmpTestRegistryLockExclusive() == TRUE));
+
+ /* Add us to the free list */
+ InsertTailList(&CmpFreeKCBListHead, &Kcb->FreeListEntry);
+
+ /* Get the allocation page */
+ AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)Kcb & 0xFFFFF000);
+
+ /* Sanity check */
+ ASSERT(AllocPage->FreeCount != CM_KCBS_PER_PAGE);
+
+ /* Increase free count */
+ if (++AllocPage->FreeCount == CM_KCBS_PER_PAGE)
+ {
+ /* Loop all the entries */
+ for (i = CM_KCBS_PER_PAGE; i; i--)
+ {
+ /* Get the KCB */
+ Kcb = (PVOID)((ULONG_PTR)AllocPage +
+ FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
+ i * sizeof(CM_KEY_CONTROL_BLOCK));
+
+ /* Remove the entry */
+ RemoveEntryList(&Kcb->FreeListEntry);
+ }
+
+ /* Free the page */
+ ExFreePool(AllocPage);
+ }
+
+ /* Release the lock */
+ KeReleaseGuardedMutex(&CmpAllocBucketLock);
}
VOID
@@ -455,6 +493,7 @@
/* Get the entry and lock the table */
Entry = Kcb->DelayCloseEntry;
+ ASSERT(Entry);
KeAcquireGuardedMutex(&CmpDelayedCloseTableLock);
/* Remove the entry */
@@ -487,12 +526,11 @@
/* Set new delay size and remove the delete flag */
Kcb->DelayedCloseIndex = CmpDelayedCloseSize;
- Kcb->Delete = FALSE;
}
BOOLEAN
NTAPI
-CmpReferenceKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
+CmpReferenceKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
/* Check if this is the KCB's first reference */
if (Kcb->RefCount == 0)
@@ -503,36 +541,36 @@
/* Convert it to exclusive */
if (!CmpTryToConvertKcbSharedToExclusive(Kcb))
{
- /* Set the delete flag */
- Kcb->Delete = TRUE;
+ /* Set the delayed close index so that we can be ignored */
+ Kcb->DelayedCloseIndex = 1;
/* Increase the reference count while we release the lock */
InterlockedIncrement((PLONG)&Kcb->RefCount);
-
- /* Sanity check, KCB should still be shared */
- ASSERT(CmpIsKcbLockedExclusive(Kcb) == FALSE);
-
- /* Release the current lock */
- CmpReleaseKcbLock(Kcb);
-
- /* Now acquire the lock in exclusive mode */
- CmpAcquireKcbLockExclusive(Kcb);
+
+ /* Go from shared to exclusive */
+ CmpConvertKcbSharedToExclusive(Kcb);
/* Decrement the reference count; the lock is now held again */
InterlockedDecrement((PLONG)&Kcb->RefCount);
-
- /* Sanity check */
- ASSERT((Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ||
- (Kcb->DelayedCloseIndex == 0));
-
- /* Remove the delete flag */
- Kcb->Delete = FALSE;
+
+ /* Check if we still control the index */
+ if (Kcb->DelayedCloseIndex == 1)
+ {
+ /* Reset it */
+ Kcb->DelayedCloseIndex = 0;
+ }
+ else
+ {
+ /* Sanity check */
+ ASSERT((Kcb->DelayedCloseIndex == CmpDelayedCloseSize) ||
+ (Kcb->DelayedCloseIndex == 0));
+ }
}
}
}
/* Increase the reference count */
- if ((InterlockedIncrement((PLONG)&Kcb->RefCount) + 1) == 0)
+ if (InterlockedIncrement((PLONG)&Kcb->RefCount) == 0)
{
/* We've overflown to 64K references, bail out */
InterlockedDecrement((PLONG)&Kcb->RefCount);
@@ -548,14 +586,8 @@
/* Convert it to exclusive */
if (!CmpTryToConvertKcbSharedToExclusive(Kcb))
{
- /* Sanity check, KCB should still be shared */
- ASSERT(CmpIsKcbLockedExclusive(Kcb) == FALSE);
-
- /* Release the current lock */
- CmpReleaseKcbLock(Kcb);
-
- /* Now acquire the lock in exclusive mode */
- CmpAcquireKcbLockExclusive(Kcb);
+ /* Go from shared to exclusive */
+ CmpConvertKcbSharedToExclusive(Kcb);
}
}
@@ -569,7 +601,7 @@
VOID
NTAPI
-CmpDelayDerefKcb(IN PCM_KEY_CONTROL_BLOCK Kcb)
+CmpDelayDerefKeyControlBlock(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
USHORT OldRefCount, NewRefCount;
LARGE_INTEGER Timeout;
@@ -596,10 +628,10 @@
KeAcquireGuardedMutex(&CmpDelayDerefKCBLock);
/* Insert the entry into the list */
- InsertHeadList(&CmpDelayDerefKCBListHead, &Entry->ListEntry);
+ InsertTailList(&CmpDelayDerefKCBListHead, &Entry->ListEntry);
/* Check if we need to enable anything */
- if (CmpDelayDerefKCBWorkItemActive)
+ if (!CmpDelayDerefKCBWorkItemActive)
{
/* Yes, we have no work item, setup the interval */
Timeout.QuadPart = CmpDelayDerefKCBIntervalInSeconds * -10000000;
@@ -651,7 +683,7 @@
}
/* Dereference the KCB */
- CmpDelayDerefKcb(Kcb->ValueCache.RealKcb);
+ CmpDelayDerefKeyControlBlock(Kcb->ValueCache.RealKcb);
Kcb->ExtFlags &= ~ CM_KCB_SYM_LINK_FOUND;
}
}
@@ -680,15 +712,18 @@
/* Check if we were already deleted */
Parent = Kcb->ParentKcb;
- if (!Kcb->Delete) CmpFreeKcb(Kcb);
+ if (!Kcb->Delete) CmpRemoveKeyControlBlock(Kcb);
+
+ /* Free the KCB as well */
+ CmpFreeKeyControlBlock(Kcb);
/* Check if we have a parent */
if (Parent)
{
/* Dereference the parent */
- LockHeldExclusively ? CmpDereferenceKcbWithLock(Kcb,
- LockHeldExclusively) :
- CmpDelayDerefKcb(Kcb);
+ LockHeldExclusively ?
+ CmpDereferenceKeyControlBlockWithLock(Kcb,LockHeldExclusively) :
+ CmpDelayDerefKeyControlBlock(Kcb);
}
}
@@ -748,8 +783,8 @@
OldRefCount);
if (NewRefCount != OldRefCount) ASSERT(FALSE);
- /* Remove the delete flag */
- Kcb->Delete = FALSE;
+ /* Reset the delayed close index */
+ Kcb->DelayedCloseIndex = 0;
/* Set up the close entry */
Kcb->DelayCloseEntry = Entry;
@@ -778,9 +813,9 @@
PCM_KEY_CONTROL_BLOCK
NTAPI
-CmpAllocateKcb(VOID)
-{
- PLIST_ENTRY ListHead, NextEntry;
+CmpAllocateKeyControlBlock(VOID)
+{
+ PLIST_ENTRY NextEntry;
PCM_KEY_CONTROL_BLOCK CurrentKcb;
PCM_ALLOC_PAGE AllocPage;
ULONG i;
@@ -792,13 +827,12 @@
/* They are, acquire the bucket lock */
KeAcquireGuardedMutex(&CmpAllocBucketLock);
- /* Loop the free KCB list */
- ListHead = &CmpFreeKCBListHead;
- NextEntry = ListHead->Flink;
- while (NextEntry != ListHead)
+ /* See if there's something on the free KCB list */
+SearchKcbList:
+ if (!IsListEmpty(&CmpFreeKCBListHead))
{
/* Remove the entry */
- RemoveEntryList(NextEntry);
+ NextEntry = RemoveHeadList(&CmpFreeKCBListHead);
/* Get the KCB */
CurrentKcb = CONTAINING_RECORD(NextEntry,
@@ -833,39 +867,20 @@
for (i = 0; i < CM_KCBS_PER_PAGE; i++)
{
/* Get this entry */
- CurrentKcb = (PCM_KEY_CONTROL_BLOCK)(AllocPage + 1);
+ CurrentKcb = (PVOID)((ULONG_PTR)AllocPage +
+ FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
+ i * sizeof(CM_KEY_CONTROL_BLOCK));
/* Set it up */
CurrentKcb->PrivateAlloc = TRUE;
CurrentKcb->DelayCloseEntry = NULL;
- InsertHeadList(&CurrentKcb->FreeListEntry,
- &CmpFreeKCBListHead);
- }
-
- /* Get the KCB */
- CurrentKcb = CONTAINING_RECORD(NextEntry,
- CM_KEY_CONTROL_BLOCK,
- FreeListEntry);
-
- /* Get the allocation page */
- AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)CurrentKcb & 0xFFFFF000);
-
- /* Decrease the free count */
- ASSERT(AllocPage->FreeCount != 0);
- AllocPage->FreeCount--;
-
- /* Make sure this KCB is privately allocated */
- ASSERT(CurrentKcb->PrivateAlloc == 1);
-
- /* Release the allocation lock */
- KeReleaseGuardedMutex(&CmpAllocBucketLock);
-
- /* Return the KCB */
- return CurrentKcb;
- }
-
- /* Release the lock */
- KeReleaseGuardedMutex(&CmpAllocBucketLock);
+ InsertHeadList(&CmpFreeKCBListHead,
+ &CurrentKcb->FreeListEntry);
+ }
+
+ /* Now go back and search the list */
+ goto SearchKcbList;
+ }
}
/* Allocate a KCB only */
@@ -885,33 +900,37 @@
VOID
NTAPI
-CmpDereferenceKcbWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb,
- IN BOOLEAN LockHeldExclusively)
+CmpDereferenceKeyControlBlockWithLock(IN PCM_KEY_CONTROL_BLOCK Kcb,
+ IN BOOLEAN LockHeldExclusively)
{
/* Sanity check */
ASSERT((CmpIsKcbLockedExclusive(Kcb) == TRUE) ||
(CmpTestRegistryLockExclusive() == TRUE));
- /* Check if we should do a direct delete */
- if (((CmpHoldLazyFlush) &&
- !(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) &&
- !(Kcb->Flags & KEY_SYM_LINK)) ||
- (Kcb->ExtFlags & CM_KCB_NO_DELAY_CLOSE) ||
- (Kcb->PrivateAlloc))
- {
- /* Clean up the KCB*/
- CmpCleanUpKcbCacheWithLock(Kcb, LockHeldExclusively);
- }
- else
- {
- /* Otherwise, use delayed close */
- CmpAddToDelayedClose(Kcb, LockHeldExclusively);
- }
-}
-
-VOID
-NTAPI
-CmpInitializeKcbKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb)
+ /* Check if this is the last reference */
+ if (InterlockedDecrement((PLONG)&Kcb->RefCount) == 0)
+ {
+ /* Check if we should do a direct delete */
+ if (((CmpHoldLazyFlush) &&
+ !(Kcb->ExtFlags & CM_KCB_SYM_LINK_FOUND) &&
+ !(Kcb->Flags & KEY_SYM_LINK)) ||
+ (Kcb->ExtFlags & CM_KCB_NO_DELAY_CLOSE) ||
+ (Kcb->Delete))
+ {
+ /* Clean up the KCB*/
+ CmpCleanUpKcbCacheWithLock(Kcb, LockHeldExclusively);
+ }
+ else
+ {
+ /* Otherwise, use delayed close */
+ CmpAddToDelayedClose(Kcb, LockHeldExclusively);
+ }
+ }
+}
+
+VOID
+NTAPI
+InitializeKCBKeyBodyList(IN PCM_KEY_CONTROL_BLOCK Kcb)
{
/* Initialize the list */
InitializeListHead(&Kcb->KeyBodyListHead);
@@ -939,6 +958,7 @@
PWCHAR p;
/* Make sure we own this hive */
+ ASSERT(FALSE);
if (((PCMHIVE)Hive)->CreatorOwner != KeGetCurrentThread()) return NULL;
/* Check if this is a fake KCB */
@@ -977,11 +997,11 @@
}
/* Allocate the KCB */
- Kcb = CmpAllocateKcb();
+ Kcb = CmpAllocateKeyControlBlock();
if (!Kcb) return NULL;
/* Initailize the key list */
- CmpInitializeKcbKeyBodyList(Kcb);
+ InitializeKCBKeyBodyList(Kcb);
/* Set it up */
Kcb->Delete = FALSE;
@@ -1007,9 +1027,9 @@
ASSERT(!FoundKcb->Delete);
/* Free the one we allocated and reference this one */
- CmpFreeKcb(Kcb);
+ CmpFreeKeyControlBlock(Kcb);
Kcb = FoundKcb;
- if (!CmpReferenceKcb(Kcb))
+ if (!CmpReferenceKeyControlBlock(Kcb))
{
/* We got too many handles */
ASSERT(Kcb->RefCount + 1 != 0);
@@ -1054,7 +1074,8 @@
if (Parent)
{
/* Reference the parent */
- if (((Parent->TotalLevels + 1) < 512) &&
(CmpReferenceKcb(Parent)))
+ if (((Parent->TotalLevels + 1) < 512) &&
+ (CmpReferenceKeyControlBlock(Parent)))
{
/* Link it */
Kcb->ParentKcb = Parent;
@@ -1063,8 +1084,8 @@
else
{
/* Remove the KCB and free it */
- CmpRemoveKcb(Kcb);
- CmpFreeKcb(Kcb);
+ CmpRemoveKeyControlBlock(Kcb);
+ CmpFreeKeyControlBlock(Kcb);
Kcb = NULL;
}
}
@@ -1103,11 +1124,11 @@
else
{
/* Dereference the KCB */
- CmpDereferenceKcbWithLock(Parent, FALSE);
+ CmpDereferenceKeyControlBlockWithLock(Parent, FALSE);
/* Remove the KCB and free it */
- CmpRemoveKcb(Kcb);
- CmpFreeKcb(Kcb);
+ CmpRemoveKeyControlBlock(Kcb);
+ CmpFreeKeyControlBlock(Kcb);
Kcb = NULL;
}
}
Modified: branches/alex-cm-branch/reactos/ntoskrnl/cm/cmutil.c
URL:
http://svn.reactos.org/svn/reactos/branches/alex-cm-branch/reactos/ntoskrnl…
==============================================================================
--- branches/alex-cm-branch/reactos/ntoskrnl/cm/cmutil.c (original)
+++ branches/alex-cm-branch/reactos/ntoskrnl/cm/cmutil.c Sun Oct 28 21:20:48 2007
@@ -55,7 +55,7 @@
NTAPI
CmpAllocateDelayItem(VOID)
{
- PCM_DELAYED_CLOSE_ENTRY Entry;
+ PCM_DELAY_ALLOC Entry;
PCM_ALLOC_PAGE AllocPage;
ULONG i;
PLIST_ENTRY NextEntry;
@@ -63,70 +63,69 @@
/* Lock the allocation buckets */
KeAcquireGuardedMutex(&CmpDelayAllocBucketLock);
- while (TRUE)
+
+ /* Look for an item on the free list */
+SearchList:
+ if (!IsListEmpty(&CmpFreeDelayItemsListHead))
{
/* Get the current entry in the list */
- NextEntry = CmpFreeDelayItemsListHead.Flink;
-
- /* Check if we need to allocate an entry */
- if (((NextEntry) && (CmpFreeDelayItemsListHead.Blink) &&
- IsListEmpty(&CmpFreeDelayItemsListHead)) ||
- (!(NextEntry) && !(CmpFreeDelayItemsListHead.Blink)))
+ NextEntry = RemoveHeadList(&CmpFreeDelayItemsListHead);
+
+ /* Grab the item */
+ Entry = CONTAINING_RECORD(NextEntry, CM_DELAY_ALLOC, ListEntry);
+
+ /* Clear the list */
+ Entry->ListEntry.Flink = Entry->ListEntry.Blink = NULL;
+
+ /* Grab the alloc page */
+ AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)Entry & 0xFFFFF000);
+
+ /* Decrease free entries */
+ ASSERT(AllocPage->FreeCount != 0);
+ AllocPage->FreeCount--;
+
+ /* Release the lock */
+ KeReleaseGuardedMutex(&CmpDelayAllocBucketLock);
+ return Entry;
+ }
+
+ /* Allocate an allocation page */
+ AllocPage = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
+ if (AllocPage)
+ {
+ /* Set default entries */
+ AllocPage->FreeCount = CM_DELAYS_PER_PAGE;
+
+ /* Loop each entry */
+ for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
{
- /* Allocate an allocation page */
- AllocPage = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
- if (AllocPage)
- {
- /* Set default entries */
- AllocPage->FreeCount = CM_DELAYS_PER_PAGE;
-
- /* Loop each entry */
- for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
- {
- /* Get this entry and link it */
- Entry = (PCM_DELAYED_CLOSE_ENTRY)(&AllocPage[i]);
- InsertHeadList(&Entry->DelayedLRUList,
- &CmpFreeDelayItemsListHead);
-
- /* Clear the KCB pointer */
- Entry->KeyControlBlock = NULL;
- }
- }
- else
- {
- /* Release the lock */
- KeReleaseGuardedMutex(&CmpDelayAllocBucketLock);
- return NULL;
- }
+ /* Get this entry and link it */
+ Entry = (PVOID)((ULONG_PTR)AllocPage +
+ FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
+ i * sizeof(CM_DELAY_ALLOC));
+ InsertTailList(&CmpFreeDelayItemsListHead,
+ &Entry->ListEntry);
+
+ /* Clear the KCB pointer */
+ Entry->Kcb = NULL;
}
}
-
- /* Set the next item in the list */
- CmpFreeDelayItemsListHead.Flink = NextEntry->Flink;
- NextEntry->Flink->Blink = &CmpFreeDelayItemsListHead;
- NextEntry->Blink = NULL;
-
- /* Get the entry and the alloc page */
- Entry = CONTAINING_RECORD(NextEntry,
- CM_DELAYED_CLOSE_ENTRY,
- DelayedLRUList);
- AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)Entry & 0xFFFFF000);
-
- /* Decrease free entries */
- ASSERT(AllocPage->FreeCount != 0);
- AllocPage->FreeCount--;
-
- /* Release the lock */
- KeReleaseGuardedMutex(&CmpDelayAllocBucketLock);
- return Entry;
+ else
+ {
+ /* Release the lock */
+ KeReleaseGuardedMutex(&CmpDelayAllocBucketLock);
+ return NULL;
+ }
+
+ /* Do the search again */
+ goto SearchList;
}
VOID
NTAPI
CmpFreeDelayItem(PVOID Entry)
{
- PCM_DELAYED_CLOSE_ENTRY AllocEntry = (PCM_DELAYED_CLOSE_ENTRY)Entry;
- PCM_DELAYED_CLOSE_ENTRY *AllocTable;
+ PCM_DELAY_ALLOC AllocEntry = (PCM_DELAY_ALLOC)Entry;
PCM_ALLOC_PAGE AllocPage;
ULONG i;
PAGED_CODE();
@@ -135,7 +134,7 @@
KeAcquireGuardedMutex(&CmpDelayAllocBucketLock);
/* Add the entry at the end */
- InsertTailList(&CmpFreeDelayItemsListHead, &AllocEntry->DelayedLRUList);
+ InsertTailList(&CmpFreeDelayItemsListHead, &AllocEntry->ListEntry);
/* Get the alloc page */
AllocPage = (PCM_ALLOC_PAGE)((ULONG_PTR)Entry & 0xFFFFF000);
@@ -145,12 +144,13 @@
if (++AllocPage->FreeCount == CM_DELAYS_PER_PAGE)
{
/* Page is totally free now, loop each entry */
- AllocTable = (PCM_DELAYED_CLOSE_ENTRY*)&AllocPage->AllocPage;
- for (i = CM_DELAYS_PER_PAGE; i; i--)
+ for (i = 0; i < CM_DELAYS_PER_PAGE; i++)
{
/* Get the entry and unlink it */
- AllocEntry = AllocTable[i];
- RemoveEntryList(&AllocEntry->DelayedLRUList);
+ AllocEntry = (PVOID)((ULONG_PTR)AllocPage +
+ FIELD_OFFSET(CM_ALLOC_PAGE, AllocPage) +
+ i * sizeof(CM_DELAY_ALLOC));
+ RemoveEntryList(&AllocEntry->ListEntry);
}
/* Now free the page */