mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 02:10:07 +00:00
- 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:
parent
24e07f0eac
commit
1417fd5fa6
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue