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/obj... ============================================================================== --- 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;