- 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.

svn path=/trunk/; revision=32812
This commit is contained in:
Aleksey Bragin 2008-04-01 20:07:36 +00:00
parent 24e07f0eac
commit 1417fd5fa6
5 changed files with 86 additions and 26 deletions

View file

@ -15,6 +15,68 @@
#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
ObpAcquireNameInformation(IN POBJECT_HEADER ObjectHeader)

View file

@ -495,8 +495,8 @@ ObpDecrementHandleCount(IN PVOID ObjectBody,
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 @@ ObpDecrementHandleCount(IN PVOID ObjectBody,
}
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
/* Check if we have a close procedure */
if (ObjectType->TypeInfo.CloseProcedure)
@ -796,8 +796,8 @@ ObpIncrementHandleCount(IN PVOID Object,
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 @@ ObpIncrementHandleCount(IN PVOID Object,
}
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
/* Check if we have an open procedure */
Status = STATUS_SUCCESS;
@ -988,7 +988,7 @@ ObpIncrementHandleCount(IN PVOID Object,
Quickie:
/* Release lock and return */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
return Status;
}
@ -1049,7 +1049,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object,
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 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object,
}
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
/* Check if we have an open procedure */
Status = STATUS_SUCCESS;
@ -1207,7 +1207,7 @@ ObpIncrementUnnamedHandleCount(IN PVOID Object,
Quickie:
/* Release lock and return */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
return Status;
}
@ -3093,8 +3093,8 @@ ObInsertObject(IN PVOID Object,
}
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 @@ ObInsertObject(IN PVOID Object,
&IsNewObject);
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
/* Check if we failed and dereference the object if so */
if (!NT_SUCCESS(RealStatus)) ObDereferenceObject(Object);

View file

@ -262,8 +262,8 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
/* 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 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
ObjectHeader->Flags |= OB_FLAG_PERMANENT;
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectHeader->Type);
ObpReleaseObjectLock(ObjectHeader);
}
else
{
@ -280,7 +280,7 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectHeader->Type);
ObpReleaseObjectLock(ObjectHeader);
/* Check if we should delete the object now */
ObpDeleteNameCheck(ObjectBody);

View file

@ -503,9 +503,8 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle,
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 @@ NtQuerySymbolicLinkObject(IN HANDLE LinkHandle,
}
_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);
}

View file

@ -206,8 +206,8 @@ ObpDeleteNameCheck(IN PVOID Object)
&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 @@ ObpDeleteNameCheck(IN PVOID Object)
}
/* Release the lock */
ObpLeaveObjectTypeMutex(ObjectType);
ObpReleaseObjectLock(ObjectHeader);
}
/* Cleanup after lookup */