Author: tkreuzer
Date: Thu Sep 6 06:54:17 2007
New Revision: 28892
URL:
http://svn.reactos.org/svn/reactos?rev=28892&view=rev
Log:
- use the new ObjectType list with fixed indices
Modified:
trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/gdiobj.c Thu Sep 6 06:54:17 2007
@@ -48,13 +48,6 @@
/* apparently the first 10 entries are never used in windows as they are empty */
#define RESERVE_ENTRIES_COUNT 10
-typedef struct
-{
- ULONG Type;
- ULONG Size;
- GDICLEANUPPROC CleanupProc;
-} GDI_OBJ_INFO, *PGDI_OBJ_INFO;
-
/*
* Dummy GDI Cleanup Callback
*/
@@ -63,31 +56,6 @@
{
return TRUE;
}
-
-/* Testing shows that regions are the most used GDIObj type,
- so put that one first for performance */
-static const
-GDI_OBJ_INFO ObjInfo[] =
-{
- /* Type */ /* Size */ /* CleanupProc */
- {GDI_OBJECT_TYPE_REGION, sizeof(ROSRGNDATA), RGNDATA_Cleanup},
- {GDI_OBJECT_TYPE_BITMAP, sizeof(BITMAPOBJ), BITMAP_Cleanup},
- {GDI_OBJECT_TYPE_DC, sizeof(DC), DC_Cleanup},
- {GDI_OBJECT_TYPE_PALETTE, sizeof(PALGDI), PALETTE_Cleanup},
- {GDI_OBJECT_TYPE_BRUSH, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
- {GDI_OBJECT_TYPE_PEN, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
- {GDI_OBJECT_TYPE_FONT, sizeof(TEXTOBJ), GDI_CleanupDummy},
- {GDI_OBJECT_TYPE_DIRECTDRAW, sizeof(DD_DIRECTDRAW), DD_Cleanup},
- {GDI_OBJECT_TYPE_DD_SURFACE, sizeof(DD_SURFACE), DDSURF_Cleanup},
- {GDI_OBJECT_TYPE_EXTPEN, sizeof(GDIBRUSHOBJ), BRUSH_Cleanup},
- /* FIXME do not use normal DC struct for this */
- {GDI_OBJECT_TYPE_METADC, sizeof(DC), GDI_CleanupDummy},
- {GDI_OBJECT_TYPE_METAFILE, sizeof(DC), GDI_CleanupDummy},
- {GDI_OBJECT_TYPE_ENHMETAFILE, 0, GDI_CleanupDummy},
- {GDI_OBJECT_TYPE_EMF, 0, GDI_CleanupDummy}
-};
-
-#define OBJTYPE_COUNT (sizeof(ObjInfo) / sizeof(ObjInfo[0]))
typedef struct
{
@@ -200,7 +168,7 @@
}
HandleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool,
- OBJTYPE_COUNT *
sizeof(PAGED_LOOKASIDE_LIST),
+ BASE_OBJTYPE_COUNT *
sizeof(PAGED_LOOKASIDE_LIST),
TAG_GDIHNDTBLE);
if(HandleTable->LookasideLists == NULL)
{
@@ -210,10 +178,13 @@
return NULL;
}
- for(ObjType = 0; ObjType < OBJTYPE_COUNT; ObjType++)
- {
- ExInitializePagedLookasideList(HandleTable->LookasideLists + ObjType, NULL, NULL,
0,
- ObjInfo[ObjType].Size + sizeof(GDIOBJHDR), TAG_GDIOBJ,
0);
+ for(ObjType = 0; ObjType < BASE_OBJTYPE_COUNT; ObjType++)
+ {
+ if (ObjTypeInfo[ObjType].bUseLookaside)
+ {
+ ExInitializePagedLookasideList(HandleTable->LookasideLists + ObjType, NULL,
NULL, 0,
+ ObjTypeInfo[ObjType].ulBodySize + sizeof(GDIOBJHDR),
ObjTypeInfo[ObjType].Tag, 0);
+ }
}
ShortDelay.QuadPart = -5000LL; /* FIXME - 0.5 ms? */
@@ -223,55 +194,21 @@
static __inline PPAGED_LOOKASIDE_LIST
FindLookasideList(PGDI_HANDLE_TABLE HandleTable,
- DWORD ObjectType)
-{
- int Index;
-
- for (Index = 0; Index < OBJTYPE_COUNT; Index++)
- {
- if (ObjInfo[Index].Type == ObjectType)
- {
- return HandleTable->LookasideLists + Index;
- }
- }
-
- DPRINT1("Can't find lookaside list for object type 0x%08x\n",
ObjectType);
-
- return NULL;
+ ULONG TypeIndex)
+{
+ return HandleTable->LookasideLists + TypeIndex;
}
static __inline BOOL
-RunCleanupCallback(PGDIOBJ pObj, DWORD ObjectType)
-{
- int Index;
-
- for (Index = 0; Index < OBJTYPE_COUNT; Index++)
- {
- if (ObjInfo[Index].Type == ObjectType)
- {
- return ((GDICLEANUPPROC)ObjInfo[Index].CleanupProc)(pObj);
- }
- }
-
- DPRINT1("Can't find cleanup callback for object type 0x%08x\n",
ObjectType);
- return TRUE;
+RunCleanupCallback(PGDIOBJ pObj, ULONG TypeIndex)
+{
+ return ((GDICLEANUPPROC)ObjTypeInfo[TypeIndex].CleanupProc)(pObj);
}
static __inline ULONG
-GetObjectSize(DWORD ObjectType)
-{
- int Index;
-
- for (Index = 0; Index < OBJTYPE_COUNT; Index++)
- {
- if (ObjInfo[Index].Type == ObjectType)
- {
- return ObjInfo[Index].Size;
- }
- }
-
- DPRINT1("Can't find size for object type 0x%08x\n", ObjectType);
- return 0;
+GetObjectSize(ULONG TypeIndex)
+{
+ return ObjTypeInfo[TypeIndex].ulBodySize;
}
#ifdef GDI_DEBUG
@@ -411,9 +348,10 @@
#endif /* GDI_DEBUG */
{
PW32PROCESS W32Process;
- PGDIOBJHDR newObject;
- PPAGED_LOOKASIDE_LIST LookasideList;
+ PGDIOBJHDR newObject = NULL;
+ PPAGED_LOOKASIDE_LIST LookasideList = NULL;
HANDLE CurrentProcessId, LockedProcessId;
+ ULONG TypeIndex;
#ifdef GDI_DEBUG
ULONG Attempts = 0;
#endif
@@ -426,115 +364,128 @@
ASSERT(ObjectType != GDI_OBJECT_TYPE_DONTCARE);
- LookasideList = FindLookasideList(HandleTable, ObjectType);
- if(LookasideList != NULL)
- {
- newObject = ExAllocateFromPagedLookasideList(LookasideList);
- if(newObject != NULL)
- {
- PSLIST_ENTRY FreeEntry;
- PGDI_TABLE_ENTRY Entry;
- PGDIOBJ ObjectBody;
- LONG TypeInfo;
-
- CurrentProcessId = PsGetCurrentProcessId();
- LockedProcessId = (HANDLE)((ULONG_PTR)CurrentProcessId | 0x1);
-
- newObject->LockingThread = NULL;
- newObject->Locks = 0;
-
-#ifdef GDI_DEBUG
- newObject->createdfile = file;
- newObject->createdline = line;
- newObject->lockfile = NULL;
- newObject->lockline = 0;
-#endif
-
- ObjectBody = GDIHdrToBdy(newObject);
-
- RtlZeroMemory(ObjectBody, GetObjectSize(ObjectType));
+ TypeIndex = GDI_OBJECT_GET_TYPE_INDEX(ObjectType);
+ if (ObjTypeInfo[TypeIndex].bUseLookaside)
+ {
+ LookasideList = FindLookasideList(HandleTable, TypeIndex);
+ if(LookasideList != NULL)
+ {
+ newObject = ExAllocateFromPagedLookasideList(LookasideList);
+ }
+ }
+ else
+ {
+ newObject = ExAllocatePoolWithTag(PagedPool,
+ ObjTypeInfo[TypeIndex].ulBodySize +
sizeof(GDIOBJHDR),
+ ObjTypeInfo[TypeIndex].Tag);
+ }
+ if(newObject != NULL)
+ {
+ PSLIST_ENTRY FreeEntry;
+ PGDI_TABLE_ENTRY Entry;
+ PGDIOBJ ObjectBody;
+ LONG TypeInfo;
+
+ CurrentProcessId = PsGetCurrentProcessId();
+ LockedProcessId = (HANDLE)((ULONG_PTR)CurrentProcessId | 0x1);
+
+ newObject->LockingThread = NULL;
+ newObject->Locks = 0;
+
+#ifdef GDI_DEBUG
+ newObject->createdfile = file;
+ newObject->createdline = line;
+ newObject->lockfile = NULL;
+ newObject->lockline = 0;
+#endif
+
+ ObjectBody = GDIHdrToBdy(newObject);
+
+ RtlZeroMemory(ObjectBody, GetObjectSize(TypeIndex));
/* FIXME: On Windows the higher 16 bit of the type field don't always match
the type from the handle, it is probably a storage type
(type = pen, storage = brush) */
- TypeInfo = (ObjectType & GDI_HANDLE_TYPE_MASK) | (ObjectType >>
GDI_ENTRY_UPPER_SHIFT);
-
- FreeEntry = InterlockedPopEntrySList(&HandleTable->FreeEntriesHead);
- if(FreeEntry != NULL)
- {
- HANDLE PrevProcId;
- UINT Index;
-
- /* calculate the entry from the address of the entry in the free slot array */
- Index = ((ULONG_PTR)FreeEntry - (ULONG_PTR)&HandleTable->FreeEntries[0])
/
- sizeof(HandleTable->FreeEntries[0]);
- Entry = &HandleTable->Entries[Index];
+ TypeInfo = (ObjectType & GDI_HANDLE_TYPE_MASK) | (ObjectType >>
GDI_ENTRY_UPPER_SHIFT);
+
+ FreeEntry = InterlockedPopEntrySList(&HandleTable->FreeEntriesHead);
+ if(FreeEntry != NULL)
+ {
+ HANDLE PrevProcId;
+ UINT Index;
+
+ /* calculate the entry from the address of the entry in the free slot array */
+ Index = ((ULONG_PTR)FreeEntry - (ULONG_PTR)&HandleTable->FreeEntries[0]) /
+ sizeof(HandleTable->FreeEntries[0]);
+ Entry = &HandleTable->Entries[Index];
LockHandle:
- PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId,
LockedProcessId, 0);
- if(PrevProcId == NULL)
+ PrevProcId = InterlockedCompareExchangePointer(&Entry->ProcessId,
LockedProcessId, 0);
+ if(PrevProcId == NULL)
+ {
+ HGDIOBJ Handle;
+
+ ASSERT(Entry->KernelData == NULL);
+
+ Entry->KernelData = ObjectBody;
+
+ /* copy the reuse-counter */
+ TypeInfo |= Entry->Type & GDI_ENTRY_REUSE_MASK;
+
+ /* we found a free entry, no need to exchange this field atomically
+ since we're holding the lock */
+ Entry->Type = TypeInfo;
+
+ /* unlock the entry */
+ (void)InterlockedExchangePointer(&Entry->ProcessId, CurrentProcessId);
+
+#ifdef GDI_DEBUG
+ memset ( GDIHandleAllocator[Index], 0xcd, GDI_STACK_LEVELS * sizeof(ULONG) );
+ KeRosGetStackFrames ( GDIHandleAllocator[Index], GDI_STACK_LEVELS );
+#endif /* GDI_DEBUG */
+
+ if(W32Process != NULL)
{
- HGDIOBJ Handle;
-
- ASSERT(Entry->KernelData == NULL);
-
- Entry->KernelData = ObjectBody;
-
- /* copy the reuse-counter */
- TypeInfo |= Entry->Type & GDI_ENTRY_REUSE_MASK;
-
- /* we found a free entry, no need to exchange this field atomically
- since we're holding the lock */
- Entry->Type = TypeInfo;
-
- /* unlock the entry */
- (void)InterlockedExchangePointer(&Entry->ProcessId, CurrentProcessId);
-
-#ifdef GDI_DEBUG
- memset ( GDIHandleAllocator[Index], 0xcd, GDI_STACK_LEVELS * sizeof(ULONG) );
- KeRosGetStackFrames ( GDIHandleAllocator[Index], GDI_STACK_LEVELS );
-#endif /* GDI_DEBUG */
-
- if(W32Process != NULL)
- {
- InterlockedIncrement(&W32Process->GDIObjects);
- }
- Handle = (HGDIOBJ)((Index & 0xFFFF) | (TypeInfo <<
GDI_ENTRY_UPPER_SHIFT));
-
- DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, ObjectBody);
- return Handle;
+ InterlockedIncrement(&W32Process->GDIObjects);
}
- else
+ Handle = (HGDIOBJ)((Index & 0xFFFF) | (TypeInfo <<
GDI_ENTRY_UPPER_SHIFT));
+
+ DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, ObjectBody);
+ return Handle;
+ }
+ else
+ {
+#ifdef GDI_DEBUG
+ if(++Attempts > 20)
{
-#ifdef GDI_DEBUG
- if(++Attempts > 20)
- {
- DPRINT1("[%d]Waiting on handle in index 0x%x\n", Attempts, Index);
- }
+ DPRINT1("[%d]Waiting on handle in index 0x%x\n", Attempts, Index);
+ }
#endif
/* damn, someone is trying to lock the object even though it doesn't
eve nexist anymore, wait a little and try again!
FIXME - we shouldn't loop forever! Give up after some time! */
- DelayExecution();
+ DelayExecution();
/* try again */
- goto LockHandle;
- }
- }
-
+ goto LockHandle;
+ }
+ }
+
+ if (ObjTypeInfo[TypeIndex].bUseLookaside)
+ {
ExFreeToPagedLookasideList(LookasideList, newObject);
- DPRINT1("Failed to insert gdi object into the handle table, no handles
left!\n");
-#ifdef GDI_DEBUG
- IntDumpHandleTable(HandleTable);
+ }
+ else
+ {
+ ExFreePool(newObject);
+ }
+ DPRINT1("Failed to insert gdi object into the handle table, no handles
left!\n");
+#ifdef GDI_DEBUG
+ IntDumpHandleTable(HandleTable);
#endif /* GDI_DEBUG */
- }
- else
- {
- DPRINT1("Not enough memory to allocate gdi object!\n");
- }
}
else
{
- DPRINT1("Failed to find lookaside list for object type 0x%x\n",
ObjectType);
+ DPRINT1("Not enough memory to allocate gdi object!\n");
}
return NULL;
}
@@ -559,7 +510,7 @@
PGDI_TABLE_ENTRY Entry;
PPAGED_LOOKASIDE_LIST LookasideList;
HANDLE ProcessId, LockedProcessId, PrevProcId;
- ULONG HandleType, HandleUpper;
+ ULONG HandleType, HandleUpper, TypeIndex;
BOOL Silent;
#ifdef GDI_DEBUG
ULONG Attempts = 0;
@@ -632,13 +583,21 @@
}
/* call the cleanup routine. */
- Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), HandleType);
+ TypeIndex = GDI_OBJECT_GET_TYPE_INDEX(HandleType);
+ Ret = RunCleanupCallback(GDIHdrToBdy(GdiHdr), TypeIndex);
/* Now it's time to free the memory */
- LookasideList = FindLookasideList(HandleTable, HandleType);
- if(LookasideList != NULL)
+ if (ObjTypeInfo[TypeIndex].bUseLookaside)
{
- ExFreeToPagedLookasideList(LookasideList, GdiHdr);
+ LookasideList = FindLookasideList(HandleTable, TypeIndex);
+ if(LookasideList != NULL)
+ {
+ ExFreeToPagedLookasideList(LookasideList, GdiHdr);
+ }
+ }
+ else
+ {
+ ExFreePool(GdiHdr);
}
return Ret;