Commit in reactos/subsys/win32k/objects on MAIN
gdiobj.c+55-1011.63 -> 1.64
Use lookaside lists for better performance

reactos/subsys/win32k/objects
gdiobj.c 1.63 -> 1.64
diff -u -r1.63 -r1.64
--- gdiobj.c	14 Mar 2004 12:16:50 -0000	1.63
+++ gdiobj.c	3 Apr 2004 20:33:39 -0000	1.64
@@ -19,7 +19,7 @@
 /*
  * GDIOBJ.C - GDI object manipulation routines
  *
- * $Id: gdiobj.c,v 1.63 2004/03/14 12:16:50 weiden Exp $
+ * $Id: gdiobj.c,v 1.64 2004/04/03 20:33:39 gvg Exp $
  *
  */
 
@@ -43,9 +43,6 @@
 #define NDEBUG
 #include <win32k/debug1.h>
 
-
-/* enable/disable GDI object caching */
-#define GDI_CACHE_OBJECTS 0
 /* count all gdi objects */
 #define GDI_COUNT_OBJECTS 1
 
@@ -94,44 +91,33 @@
   #if GDI_COUNT_OBJECTS
   ULONG HandlesCount;
   #endif
-  #if GDI_CACHE_OBJECTS
-  ULONG ObjHdrSize;
-  PGDIOBJHDR *CachedObjects;
-  #endif
+  PPAGED_LOOKASIDE_LIST LookasideLists;
   PGDIOBJHDR Handles[1];
 } GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
 
-#if GDI_CACHE_OBJECTS
-
-#define N_OBJ_TYPES 16
-
 typedef struct
 {
   ULONG Type;
   ULONG Size;
 } GDI_OBJ_SIZE;
 
-typedef struct _GDI_DONTCARE
-{
-  PVOID Data;
-} GDI_DONTCARE, *PGDI_DONTCARE;
-
 const
-GDI_OBJ_SIZE ObjSizes[N_OBJ_TYPES] =
+GDI_OBJ_SIZE ObjSizes[] =
 {
+  /* Testing shows that regions are the most used GDIObj type,
+     so put that one first for performance */
+  {GDI_OBJECT_TYPE_REGION,      sizeof(ROSRGNDATA)},
+  {GDI_OBJECT_TYPE_BITMAP,      sizeof(BITMAPOBJ)},
   {GDI_OBJECT_TYPE_DC,          sizeof(DC)},
-  {GDI_OBJECT_TYPE_DCE,         sizeof(DCE)},
   {GDI_OBJECT_TYPE_PALETTE,     sizeof(PALGDI)},
-  {GDI_OBJECT_TYPE_FONT,        sizeof(TEXTOBJ)},
   {GDI_OBJECT_TYPE_BRUSH,       sizeof(BRUSHOBJ)},
   {GDI_OBJECT_TYPE_PEN,         sizeof(PENOBJ)},
-  {GDI_OBJECT_TYPE_REGION,      sizeof(ROSRGNDATA)},
-  {GDI_OBJECT_TYPE_BITMAP,      sizeof(BITMAPOBJ)},
+  {GDI_OBJECT_TYPE_FONT,        sizeof(TEXTOBJ)},
+  {GDI_OBJECT_TYPE_DCE,         sizeof(DCE)},
 /*
   {GDI_OBJECT_TYPE_DIRECTDRAW,  sizeof(DD_DIRECTDRAW)},
   {GDI_OBJECT_TYPE_DD_SURFACE,  sizeof(DD_SURFACE)},
 */
-  {GDI_OBJECT_TYPE_DONTCARE,    sizeof(GDI_DONTCARE)},
   {GDI_OBJECT_TYPE_EXTPEN,      0},
   {GDI_OBJECT_TYPE_METADC,      0},
   {GDI_OBJECT_TYPE_METAFILE,    0},
@@ -141,18 +127,7 @@
   {GDI_OBJECT_TYPE_EMF,         0}
 };
 
-ULONG FASTCALL
-GDI_MaxGdiObjHeaderSize(VOID)
-{
-  ULONG i, Size;
-  for(i = 0, Size = 0; i < N_OBJ_TYPES; i++)
-  {
-    Size = max(Size, ObjSizes[i].Size);
-  }
-  return Size;
-}
-
-#endif
+#define OBJTYPE_COUNT (sizeof(ObjSizes) / sizeof(ObjSizes[0]))
 
 /*  GDI stock objects */
 
@@ -233,12 +208,9 @@
 {
   PGDI_HANDLE_TABLE  handleTable;
   ULONG MemSize;
+  UINT ObjType;
   
-#if GDI_CACHE_OBJECTS
-  MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * (Size << 1);
-#else
   MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size;
-#endif
 
   /* prevent APC delivery for the *FastMutexUnsafe calls */
   const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
@@ -249,12 +221,23 @@
 #if GDI_COUNT_OBJECTS
   handleTable->HandlesCount = 0;
 #endif
-#if GDI_CACHE_OBJECTS
-  handleTable->CachedObjects = &handleTable->Handles[Size];
-  handleTable->ObjHdrSize = sizeof(GDIOBJHDR) + GDI_MaxGdiObjHeaderSize();
-#endif
   handleTable->wTableSize = Size;
   handleTable->AllocationHint = 1;
+  handleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool,
+                                                      OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST),
+                                                      TAG_GDIHNDTBLE);
+  if (NULL == handleTable->LookasideLists)
+    {
+      ExFreePool(handleTable);
+      ExReleaseFastMutexUnsafe (&HandleTableMutex);
+      KfLowerIrql(PrevIrql);
+      return NULL;
+    }
+  for (ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++)
+    {
+      ExInitializePagedLookasideList(handleTable->LookasideLists + ObjType, NULL, NULL, 0,
+                                     ObjSizes[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ, 0);
+    }
   ExReleaseFastMutexUnsafe (&HandleTableMutex);
   KfLowerIrql(PrevIrql);
 
@@ -310,6 +293,24 @@
    return 0;
 }
 
+static PPAGED_LOOKASIDE_LIST FASTCALL
+FindLookasideList(DWORD ObjectType)
+{
+  int Index;
+
+  for (Index = 0; Index < OBJTYPE_COUNT; Index++)
+    {
+      if (ObjSizes[Index].Type == ObjectType)
+        {
+          return HandleTable->LookasideLists + Index;
+        }
+    }
+
+  DPRINT1("Can't find lookaside list for object type 0x%08x\n", ObjectType);
+
+  return NULL;
+}
+
 /*!
  * Allocate memory for GDI object and return handle to it.
  *
@@ -328,10 +329,8 @@
   PW32PROCESS W32Process;
   PGDIOBJHDR  newObject;
   WORD Index;
-#if GDI_CACHE_OBJECTS
-  PGDIOBJHDR *CachedObject;
-#endif
-  
+  PPAGED_LOOKASIDE_LIST LookasideList;
+
   ExAcquireFastMutex(&HandleTableMutex);
   Index = GDIOBJ_iGetNextOpenHandleIndex ();
   if (0 == Index)
@@ -341,50 +340,20 @@
       return NULL;
     }
 
-#if GDI_CACHE_OBJECTS
-  CachedObject = (PGDIOBJHDR*)(HandleTable->CachedObjects + Index);
-  if(!(newObject = *CachedObject))
-  {
-    /* allocate new gdi object */
-    newObject = ExAllocatePoolWithTag(PagedPool, HandleTable->ObjHdrSize, TAG_GDIOBJ);
-    if(!newObject)
+  LookasideList = FindLookasideList(ObjectType);
+  if (NULL == LookasideList)
     {
       ExReleaseFastMutex(&HandleTableMutex);
-      DPRINT1("GDIOBJ_AllocObj: failed\n");
       return NULL;
     }
-    RtlZeroMemory(newObject, HandleTable->ObjHdrSize);
-    *CachedObject = newObject;
-  }
-  /* Zero the memory when destroying the object */
-  if(ObjectType == GDI_OBJECT_TYPE_DONTCARE)
-  {
-    PVOID *Data;
-    PGDI_DONTCARE dc;
-    
-    Data = ExAllocatePoolWithTag(PagedPool, sizeof(PVOID) + Size, TAG_GDIOBJ);
-    if(!Data)
+  newObject = ExAllocateFromPagedLookasideList(LookasideList);
+  if (NULL == newObject)
     {
       ExReleaseFastMutex(&HandleTableMutex);
-      DPRINT1("GDIOBJ_AllocObj failed: %d bytes for GDI_OBJECT_TYPE_DONTCARE\n", Size + sizeof(PVOID));
+      DPRINT1("Unable to allocate GDI object from lookaside list\n");
       return NULL;
     }
-    dc = (PGDI_DONTCARE)((PCHAR)newObject + sizeof(GDIOBJHDR));
-    RtlZeroMemory((PVOID)(Data + 1), Size);
-    ((PGDI_DONTCARE)((PCHAR)newObject + sizeof(GDIOBJHDR)))->Data = Data;
-    *Data = newObject;
-  }
-#else
-  DPRINT("GDIOBJ_AllocObj: handle: %d, size: %d, type: 0x%08x\n", Index, Size, ObjectType);
-  newObject = ExAllocatePoolWithTag(PagedPool, Size + sizeof (GDIOBJHDR), TAG_GDIOBJ);
-  if (newObject == NULL)
-  {
-    ExReleaseFastMutex(&HandleTableMutex);
-    DPRINT1("GDIOBJ_AllocObj: failed\n");
-    return NULL;
-  }
   RtlZeroMemory (newObject, Size + sizeof(GDIOBJHDR));
-#endif
 
   newObject->wTableIndex = Index;
 
@@ -431,6 +400,7 @@
   PW32PROCESS W32Process;
   PGDIOBJHDR objectHeader;
   PGDIOBJ Obj;
+  PPAGED_LOOKASIDE_LIST LookasideList;
   BOOL 	bRet = TRUE;
 
   objectHeader = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj));
@@ -466,19 +436,11 @@
       Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
       bRet = (*(objectHeader->CleanupProc))(Obj);
     }
-#if GDI_CACHE_OBJECTS
-  if(GDI_MAGIC_TO_TYPE(objectHeader->Magic) == GDI_OBJECT_TYPE_DONTCARE)
-  {
-    PGDI_DONTCARE dc = (PGDI_DONTCARE)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
-    if(dc->Data)
+  LookasideList = FindLookasideList(GDI_MAGIC_TO_TYPE(objectHeader->Magic));
+  if (NULL != LookasideList)
     {
-      ExFreePool(dc->Data);
+      ExFreeToPagedLookasideList(LookasideList, objectHeader);
     }
-    RtlZeroMemory(objectHeader, HandleTable->ObjHdrSize);
-  }
-#else
-  ExFreePool(objectHeader);
-#endif
   ExAcquireFastMutexUnsafe (&HandleTableMutex);
   HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL;
 #if GDI_COUNT_OBJECTS
@@ -787,15 +749,7 @@
       ObjHdr->lockline = line;
     }
 
-#if GDI_CACHE_OBJECTS
-  if(GDI_MAGIC_TO_TYPE(ObjHdr->Magic) != GDI_OBJECT_TYPE_DONTCARE)
-  {
-    return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
-  }
-  return (PGDIOBJ)((PVOID)(((PGDI_DONTCARE)((PCHAR)ObjHdr + sizeof(GDIOBJHDR)))->Data) + 1);
-#else
   return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
-#endif
 }
 #endif//GDIOBJ_LockObj
 
CVSspam 0.2.8