[ros-diffs] [fireball] 32812: - 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.

fireball at svn.reactos.org fireball at svn.reactos.org
Tue Apr 1 22:07:37 CEST 2008


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/ob_x.h?rev=32812&r1=32811&r2=32812&view=diff
==============================================================================
--- 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=32812&r1=32811&r2=32812&view=diff
==============================================================================
--- 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=32812&r1=32811&r2=32812&view=diff
==============================================================================
--- 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=32812&r1=32811&r2=32812&view=diff
==============================================================================
--- 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=32812&r1=32811&r2=32812&view=diff
==============================================================================
--- 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 */



More information about the Ros-diffs mailing list