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/…
==============================================================================
--- 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=3…
==============================================================================
--- 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=3…
==============================================================================
--- 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=3…
==============================================================================
--- 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 */