mirror of
https://github.com/reactos/reactos.git
synced 2025-02-25 01:39:30 +00:00
Use lookaside lists for better performance
svn path=/trunk/; revision=8959
This commit is contained in:
parent
5f3ddeb0c9
commit
87ea1d498e
1 changed files with 57 additions and 103 deletions
|
@ -19,7 +19,7 @@
|
||||||
/*
|
/*
|
||||||
* GDIOBJ.C - GDI object manipulation routines
|
* 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
|
#define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
|
|
||||||
/* enable/disable GDI object caching */
|
|
||||||
#define GDI_CACHE_OBJECTS 0
|
|
||||||
/* count all gdi objects */
|
/* count all gdi objects */
|
||||||
#define GDI_COUNT_OBJECTS 1
|
#define GDI_COUNT_OBJECTS 1
|
||||||
|
|
||||||
|
@ -94,44 +91,33 @@ typedef struct _GDI_HANDLE_TABLE
|
||||||
#if GDI_COUNT_OBJECTS
|
#if GDI_COUNT_OBJECTS
|
||||||
ULONG HandlesCount;
|
ULONG HandlesCount;
|
||||||
#endif
|
#endif
|
||||||
#if GDI_CACHE_OBJECTS
|
PPAGED_LOOKASIDE_LIST LookasideLists;
|
||||||
ULONG ObjHdrSize;
|
|
||||||
PGDIOBJHDR *CachedObjects;
|
|
||||||
#endif
|
|
||||||
PGDIOBJHDR Handles[1];
|
PGDIOBJHDR Handles[1];
|
||||||
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
|
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
|
||||||
|
|
||||||
#if GDI_CACHE_OBJECTS
|
|
||||||
|
|
||||||
#define N_OBJ_TYPES 16
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ULONG Type;
|
ULONG Type;
|
||||||
ULONG Size;
|
ULONG Size;
|
||||||
} GDI_OBJ_SIZE;
|
} GDI_OBJ_SIZE;
|
||||||
|
|
||||||
typedef struct _GDI_DONTCARE
|
|
||||||
{
|
|
||||||
PVOID Data;
|
|
||||||
} GDI_DONTCARE, *PGDI_DONTCARE;
|
|
||||||
|
|
||||||
const
|
const
|
||||||
GDI_OBJ_SIZE ObjSizes[N_OBJ_TYPES] =
|
GDI_OBJ_SIZE ObjSizes[] =
|
||||||
{
|
{
|
||||||
{GDI_OBJECT_TYPE_DC, sizeof(DC)},
|
/* Testing shows that regions are the most used GDIObj type,
|
||||||
{GDI_OBJECT_TYPE_DCE, sizeof(DCE)},
|
so put that one first for performance */
|
||||||
{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_REGION, sizeof(ROSRGNDATA)},
|
||||||
{GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ)},
|
{GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_DC, sizeof(DC)},
|
||||||
|
{GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI)},
|
||||||
|
{GDI_OBJECT_TYPE_BRUSH, sizeof(BRUSHOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_PEN, sizeof(PENOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ)},
|
||||||
|
{GDI_OBJECT_TYPE_DCE, sizeof(DCE)},
|
||||||
/*
|
/*
|
||||||
{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW)},
|
{GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW)},
|
||||||
{GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE)},
|
{GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE)},
|
||||||
*/
|
*/
|
||||||
{GDI_OBJECT_TYPE_DONTCARE, sizeof(GDI_DONTCARE)},
|
|
||||||
{GDI_OBJECT_TYPE_EXTPEN, 0},
|
{GDI_OBJECT_TYPE_EXTPEN, 0},
|
||||||
{GDI_OBJECT_TYPE_METADC, 0},
|
{GDI_OBJECT_TYPE_METADC, 0},
|
||||||
{GDI_OBJECT_TYPE_METAFILE, 0},
|
{GDI_OBJECT_TYPE_METAFILE, 0},
|
||||||
|
@ -141,18 +127,7 @@ GDI_OBJ_SIZE ObjSizes[N_OBJ_TYPES] =
|
||||||
{GDI_OBJECT_TYPE_EMF, 0}
|
{GDI_OBJECT_TYPE_EMF, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
ULONG FASTCALL
|
#define OBJTYPE_COUNT (sizeof(ObjSizes) / sizeof(ObjSizes[0]))
|
||||||
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
|
|
||||||
|
|
||||||
/* GDI stock objects */
|
/* GDI stock objects */
|
||||||
|
|
||||||
|
@ -233,12 +208,9 @@ GDIOBJ_iAllocHandleTable (WORD Size)
|
||||||
{
|
{
|
||||||
PGDI_HANDLE_TABLE handleTable;
|
PGDI_HANDLE_TABLE handleTable;
|
||||||
ULONG MemSize;
|
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;
|
MemSize = sizeof(GDI_HANDLE_TABLE) + sizeof(PGDIOBJ) * Size;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* prevent APC delivery for the *FastMutexUnsafe calls */
|
/* prevent APC delivery for the *FastMutexUnsafe calls */
|
||||||
const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
|
const KIRQL PrevIrql = KfRaiseIrql(APC_LEVEL);
|
||||||
|
@ -248,13 +220,24 @@ GDIOBJ_iAllocHandleTable (WORD Size)
|
||||||
memset (handleTable, 0, MemSize);
|
memset (handleTable, 0, MemSize);
|
||||||
#if GDI_COUNT_OBJECTS
|
#if GDI_COUNT_OBJECTS
|
||||||
handleTable->HandlesCount = 0;
|
handleTable->HandlesCount = 0;
|
||||||
#endif
|
|
||||||
#if GDI_CACHE_OBJECTS
|
|
||||||
handleTable->CachedObjects = &handleTable->Handles[Size];
|
|
||||||
handleTable->ObjHdrSize = sizeof(GDIOBJHDR) + GDI_MaxGdiObjHeaderSize();
|
|
||||||
#endif
|
#endif
|
||||||
handleTable->wTableSize = Size;
|
handleTable->wTableSize = Size;
|
||||||
handleTable->AllocationHint = 1;
|
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);
|
ExReleaseFastMutexUnsafe (&HandleTableMutex);
|
||||||
KfLowerIrql(PrevIrql);
|
KfLowerIrql(PrevIrql);
|
||||||
|
|
||||||
|
@ -310,6 +293,24 @@ GDIOBJ_iGetNextOpenHandleIndex (void)
|
||||||
return 0;
|
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.
|
* Allocate memory for GDI object and return handle to it.
|
||||||
*
|
*
|
||||||
|
@ -328,10 +329,8 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc)
|
||||||
PW32PROCESS W32Process;
|
PW32PROCESS W32Process;
|
||||||
PGDIOBJHDR newObject;
|
PGDIOBJHDR newObject;
|
||||||
WORD Index;
|
WORD Index;
|
||||||
#if GDI_CACHE_OBJECTS
|
PPAGED_LOOKASIDE_LIST LookasideList;
|
||||||
PGDIOBJHDR *CachedObject;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ExAcquireFastMutex(&HandleTableMutex);
|
ExAcquireFastMutex(&HandleTableMutex);
|
||||||
Index = GDIOBJ_iGetNextOpenHandleIndex ();
|
Index = GDIOBJ_iGetNextOpenHandleIndex ();
|
||||||
if (0 == Index)
|
if (0 == Index)
|
||||||
|
@ -341,50 +340,20 @@ GDIOBJ_AllocObj(WORD Size, DWORD ObjectType, GDICLEANUPPROC CleanupProc)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GDI_CACHE_OBJECTS
|
LookasideList = FindLookasideList(ObjectType);
|
||||||
CachedObject = (PGDIOBJHDR*)(HandleTable->CachedObjects + Index);
|
if (NULL == LookasideList)
|
||||||
if(!(newObject = *CachedObject))
|
|
||||||
{
|
|
||||||
/* allocate new gdi object */
|
|
||||||
newObject = ExAllocatePoolWithTag(PagedPool, HandleTable->ObjHdrSize, TAG_GDIOBJ);
|
|
||||||
if(!newObject)
|
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&HandleTableMutex);
|
ExReleaseFastMutex(&HandleTableMutex);
|
||||||
DPRINT1("GDIOBJ_AllocObj: failed\n");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
RtlZeroMemory(newObject, HandleTable->ObjHdrSize);
|
newObject = ExAllocateFromPagedLookasideList(LookasideList);
|
||||||
*CachedObject = newObject;
|
if (NULL == 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)
|
|
||||||
{
|
{
|
||||||
ExReleaseFastMutex(&HandleTableMutex);
|
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;
|
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));
|
RtlZeroMemory (newObject, Size + sizeof(GDIOBJHDR));
|
||||||
#endif
|
|
||||||
|
|
||||||
newObject->wTableIndex = Index;
|
newObject->wTableIndex = Index;
|
||||||
|
|
||||||
|
@ -431,6 +400,7 @@ GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType, DWORD Flag)
|
||||||
PW32PROCESS W32Process;
|
PW32PROCESS W32Process;
|
||||||
PGDIOBJHDR objectHeader;
|
PGDIOBJHDR objectHeader;
|
||||||
PGDIOBJ Obj;
|
PGDIOBJ Obj;
|
||||||
|
PPAGED_LOOKASIDE_LIST LookasideList;
|
||||||
BOOL bRet = TRUE;
|
BOOL bRet = TRUE;
|
||||||
|
|
||||||
objectHeader = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj));
|
objectHeader = GDIOBJ_iGetObjectForIndex(GDI_HANDLE_GET_INDEX(hObj));
|
||||||
|
@ -466,19 +436,11 @@ GDIOBJ_FreeObj(HGDIOBJ hObj, DWORD ObjectType, DWORD Flag)
|
||||||
Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
Obj = (PGDIOBJ)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
||||||
bRet = (*(objectHeader->CleanupProc))(Obj);
|
bRet = (*(objectHeader->CleanupProc))(Obj);
|
||||||
}
|
}
|
||||||
#if GDI_CACHE_OBJECTS
|
LookasideList = FindLookasideList(GDI_MAGIC_TO_TYPE(objectHeader->Magic));
|
||||||
if(GDI_MAGIC_TO_TYPE(objectHeader->Magic) == GDI_OBJECT_TYPE_DONTCARE)
|
if (NULL != LookasideList)
|
||||||
{
|
|
||||||
PGDI_DONTCARE dc = (PGDI_DONTCARE)((PCHAR)objectHeader + sizeof(GDIOBJHDR));
|
|
||||||
if(dc->Data)
|
|
||||||
{
|
{
|
||||||
ExFreePool(dc->Data);
|
ExFreeToPagedLookasideList(LookasideList, objectHeader);
|
||||||
}
|
}
|
||||||
RtlZeroMemory(objectHeader, HandleTable->ObjHdrSize);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ExFreePool(objectHeader);
|
|
||||||
#endif
|
|
||||||
ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
ExAcquireFastMutexUnsafe (&HandleTableMutex);
|
||||||
HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL;
|
HandleTable->Handles[GDI_HANDLE_GET_INDEX(hObj)] = NULL;
|
||||||
#if GDI_COUNT_OBJECTS
|
#if GDI_COUNT_OBJECTS
|
||||||
|
@ -787,15 +749,7 @@ GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType)
|
||||||
ObjHdr->lockline = line;
|
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));
|
return (PGDIOBJ)((PCHAR)ObjHdr + sizeof(GDIOBJHDR));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif//GDIOBJ_LockObj
|
#endif//GDIOBJ_LockObj
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue