Author: fireball Date: Tue Apr 1 15:07:36 2008 New Revision: 32812
URL: http://svn.reactos.org/svn/reactos?rev=32812&view=rev Log: - Lock only the object header for an object instead of the entire object type, for better contention. Implement exclusive/shared lock and release routines around the existing lock slots in the object type (this allows up to 4 different objects to be locked in the same time, instead of locking the entire type). - Thanks to Alex for reporting this.
Modified: trunk/reactos/ntoskrnl/include/internal/ob_x.h trunk/reactos/ntoskrnl/ob/obhandle.c trunk/reactos/ntoskrnl/ob/oblife.c trunk/reactos/ntoskrnl/ob/oblink.c trunk/reactos/ntoskrnl/ob/obname.c
Modified: trunk/reactos/ntoskrnl/include/internal/ob_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob_x.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/ob_x.h [iso-8859-1] Tue Apr 1 15:07:36 2008 @@ -14,6 +14,68 @@ #define OBP_LOCK_STATE_POST_ACQUISITION_SHARED 0xDDDD1234 #define OBP_LOCK_STATE_RELEASED 0xEEEE1234 #define OBP_LOCK_STATE_INITIALIZED 0xFFFF1234 + +ULONG +FORCEINLINE +ObpSelectObjectLockSlot(IN POBJECT_HEADER ObjectHeader) +{ + /* We have 4 locks total, this will return a 0-index slot */ + return (((ULONG_PTR)ObjectHeader) >> 8) & 3; +} + +VOID +FORCEINLINE +ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&ObjectType->ObjectLocks[Slot], TRUE); +} + +VOID +FORCEINLINE +ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + KeEnterCriticalRegion(); + ExAcquireResourceSharedLite(&ObjectType->ObjectLocks[Slot], TRUE); +} + +VOID +FORCEINLINE +ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader) +{ + ULONG Slot; + POBJECT_TYPE ObjectType = ObjectHeader->Type; + + /* Pick a slot */ + Slot = ObpSelectObjectLockSlot(ObjectHeader); + + /* Enter a critical region and acquire the resource */ + ExReleaseResourceLite(&ObjectType->ObjectLocks[Slot]); + KeLeaveCriticalRegion(); + + /* Sanity check */ + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); +}
POBJECT_HEADER_NAME_INFO FORCEINLINE
Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c [iso-8859-1] Tue Apr 1 15:07:36 2008 @@ -495,8 +495,8 @@ ObjectHeader->HandleCount, ObjectHeader->PointerCount);
- /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader);
/* Set default counts */ SystemHandleCount = ObjectHeader->HandleCount; @@ -571,7 +571,7 @@ }
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader);
/* Check if we have a close procedure */ if (ObjectType->TypeInfo.CloseProcedure) @@ -796,8 +796,8 @@ ProbeMode = AccessMode; }
- /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader);
/* Charge quota and remove the creator info flag */ Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); @@ -922,7 +922,7 @@ }
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader);
/* Check if we have an open procedure */ Status = STATUS_SUCCESS; @@ -988,7 +988,7 @@
Quickie: /* Release lock and return */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); return Status; }
@@ -1049,7 +1049,7 @@ ObjectHeader->PointerCount);
/* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + ObpAcquireObjectLock(ObjectHeader);
/* Charge quota and remove the creator info flag */ Status = ObpChargeQuotaForObject(ObjectHeader, ObjectType, &NewObject); @@ -1149,7 +1149,7 @@ }
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader);
/* Check if we have an open procedure */ Status = STATUS_SUCCESS; @@ -1207,7 +1207,7 @@
Quickie: /* Release lock and return */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); return Status; }
@@ -3093,8 +3093,8 @@ } else { - /* Otherwise, lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Otherwise, lock the object */ + ObpAcquireObjectLock(ObjectHeader);
/* And charge quota for the process to make it appear as used */ RealStatus = ObpChargeQuotaForObject(ObjectHeader, @@ -3102,7 +3102,7 @@ &IsNewObject);
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader);
/* Check if we failed and dereference the object if so */ if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);
Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=32... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c [iso-8859-1] Tue Apr 1 15:07:36 2008 @@ -262,8 +262,8 @@ /* Get the header */ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
- /* Acquire object type lock */ - ObpEnterObjectTypeMutex(ObjectHeader->Type); + /* Acquire object lock */ + ObpAcquireObjectLock(ObjectHeader);
/* Check what we're doing to it */ if (Permanent) @@ -272,7 +272,7 @@ ObjectHeader->Flags |= OB_FLAG_PERMANENT;
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectHeader->Type); + ObpReleaseObjectLock(ObjectHeader); } else { @@ -280,7 +280,7 @@ ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectHeader->Type); + ObpReleaseObjectLock(ObjectHeader);
/* Check if we should delete the object now */ ObpDeleteNameCheck(ObjectBody);
Modified: trunk/reactos/ntoskrnl/ob/oblink.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblink.c?rev=32... ============================================================================== --- trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/oblink.c [iso-8859-1] Tue Apr 1 15:07:36 2008 @@ -503,9 +503,8 @@ NULL); if (NT_SUCCESS(Status)) { - /* Lock the object type */ - KeEnterCriticalRegion(); - ExAcquireResourceExclusiveLite(&ObSymbolicLinkType->Mutex, TRUE); + /* Lock the object */ + ObpAcquireObjectLock(OBJECT_TO_OBJECT_HEADER(SymlinkObject));
/* * So here's the thing: If you specify a return length, then the @@ -549,9 +548,8 @@ } _SEH_END;
- /* Unlock the object type and reference the object */ - ExReleaseResourceLite(&ObSymbolicLinkType->Mutex); - KeLeaveCriticalRegion(); + /* Unlock the object and reference the object */ + ObpReleaseObjectLock(OBJECT_TO_OBJECT_HEADER(SymlinkObject)); ObDereferenceObject(SymlinkObject); }
Modified: trunk/reactos/ntoskrnl/ob/obname.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=32... ============================================================================== --- trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/ob/obname.c [iso-8859-1] Tue Apr 1 15:07:36 2008 @@ -206,8 +206,8 @@ &Context); if (Object) { - /* Lock the object type */ - ObpEnterObjectTypeMutex(ObjectType); + /* Lock the object */ + ObpAcquireObjectLock(ObjectHeader);
/* Make sure we can still delete the object */ if (!(ObjectHeader->HandleCount) && @@ -238,7 +238,7 @@ }
/* Release the lock */ - ObpLeaveObjectTypeMutex(ObjectType); + ObpReleaseObjectLock(ObjectHeader); }
/* Cleanup after lookup */