reactos/include/win32k
diff -u -r1.27 -r1.28
--- gdiobj.h 12 Dec 2004 01:40:36 -0000 1.27
+++ gdiobj.h 13 Dec 2004 21:59:27 -0000 1.28
@@ -65,6 +65,8 @@
PETHREAD LockingThread; /* only assigned if a thread is holding the lock! */
ULONG Locks;
#ifdef GDI_DEBUG
+ const char* createdfile;
+ int createdline;
const char* lockfile;
int lockline;
#endif
@@ -77,7 +79,6 @@
DWORD ObjectType;
} GDIMULTILOCK, *PGDIMULTILOCK;
-HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObj(ULONG ObjectType);
BOOL INTERNAL_CALL GDIOBJ_LockMultipleObj(PGDIMULTILOCK pList, INT nObj);
BOOL INTERNAL_CALL GDIOBJ_UnlockMultipleObj(PGDIMULTILOCK pList, INT nObj);
BOOL INTERNAL_CALL GDIOBJ_OwnedByCurrentProcess(HGDIOBJ ObjectHandle);
@@ -92,16 +93,19 @@
#ifdef GDI_DEBUG
/* a couple macros for debugging GDIOBJ locking */
+#define GDIOBJ_AllocObj(ty) GDIOBJ_AllocObjDbg(__FILE__,__LINE__,ty)
#define GDIOBJ_FreeObj(obj,ty) GDIOBJ_FreeObjDbg(__FILE__,__LINE__,obj,ty)
#define GDIOBJ_LockObj(obj,ty) GDIOBJ_LockObjDbg(__FILE__,__LINE__,obj,ty)
#define GDIOBJ_UnlockObj(obj) GDIOBJ_UnlockObjDbg(__FILE__,__LINE__,obj)
+HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObjDbg(const char* file, int line, ULONG ObjectType);
BOOL INTERNAL_CALL GDIOBJ_FreeObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_LockObjDbg (const char* file, int line, HGDIOBJ hObj, DWORD ObjectType);
BOOL INTERNAL_CALL GDIOBJ_UnlockObjDbg (const char* file, int line, HGDIOBJ hObj);
#else /* !GDI_DEBUG */
+HGDIOBJ INTERNAL_CALL GDIOBJ_AllocObj(ULONG ObjectType);
BOOL INTERNAL_CALL GDIOBJ_FreeObj (HGDIOBJ hObj, DWORD ObjectType);
PGDIOBJ INTERNAL_CALL GDIOBJ_LockObj (HGDIOBJ hObj, DWORD ObjectType);
BOOL INTERNAL_CALL GDIOBJ_UnlockObj (HGDIOBJ hObj);
reactos/subsys/win32k/objects
diff -u -r1.76 -r1.77
--- gdiobj.c 13 Dec 2004 12:51:51 -0000 1.76
+++ gdiobj.c 13 Dec 2004 21:59:28 -0000 1.77
@@ -19,7 +19,7 @@
/*
* GDIOBJ.C - GDI object manipulation routines
*
- * $Id: gdiobj.c,v 1.76 2004/12/13 12:51:51 weiden Exp $
+ * $Id: gdiobj.c,v 1.77 2004/12/13 21:59:28 weiden Exp $
*/
#include <w32k.h>
@@ -52,13 +52,13 @@
typedef struct _GDI_HANDLE_TABLE
{
- LONG HandlesCount;
- LONG nEntries;
PPAGED_LOOKASIDE_LIST LookasideLists;
+
+ SLIST_HEADER FreeEntriesHead;
+ SLIST_ENTRY FreeEntries[((GDI_HANDLE_COUNT * sizeof(GDI_TABLE_ENTRY)) << 3) /
+ (sizeof(SLIST_ENTRY) << 3)];
- PGDI_TABLE_ENTRY EntriesEnd;
-
- GDI_TABLE_ENTRY Entries[1];
+ GDI_TABLE_ENTRY Entries[GDI_HANDLE_COUNT];
} GDI_HANDLE_TABLE, *PGDI_HANDLE_TABLE;
typedef struct
@@ -116,20 +116,26 @@
* \param Size - number of entries in the object table.
*/
static PGDI_HANDLE_TABLE INTERNAL_CALL
-GDIOBJ_iAllocHandleTable(ULONG Entries)
+GDIOBJ_iAllocHandleTable(VOID)
{
PGDI_HANDLE_TABLE handleTable;
UINT ObjType;
- ULONG MemSize = sizeof(GDI_HANDLE_TABLE) + (sizeof(GDI_TABLE_ENTRY) * (Entries - 1));
+ UINT i;
+ PGDI_TABLE_ENTRY Entry;
- handleTable = ExAllocatePoolWithTag(NonPagedPool, MemSize, TAG_GDIHNDTBLE);
+ handleTable = ExAllocatePoolWithTag(NonPagedPool, sizeof(GDI_HANDLE_TABLE), TAG_GDIHNDTBLE);
ASSERT( handleTable );
- RtlZeroMemory(handleTable, MemSize);
-
- handleTable->HandlesCount = 0;
- handleTable->nEntries = Entries;
-
- handleTable->EntriesEnd = &handleTable->Entries[Entries];
+ RtlZeroMemory(handleTable, sizeof(GDI_HANDLE_TABLE));
+
+ /*
+ * initialize the free entry cache
+ */
+ InitializeSListHead(&handleTable->FreeEntriesHead);
+ Entry = &HandleTable->Entries[RESERVE_ENTRIES_COUNT];
+ for(i = GDI_HANDLE_COUNT - 1; i >= RESERVE_ENTRIES_COUNT; i--)
+ {
+ InterlockedPushEntrySList(&handleTable->FreeEntriesHead, &handleTable->FreeEntries[i]);
+ }
handleTable->LookasideLists = ExAllocatePoolWithTag(NonPagedPool,
OBJTYPE_COUNT * sizeof(PAGED_LOOKASIDE_LIST),
@@ -214,12 +220,19 @@
* \todo return the object pointer and lock it by default.
*/
HGDIOBJ INTERNAL_CALL
+#ifdef GDI_DEBUG
+GDIOBJ_AllocObjDbg(const char* file, int line, ULONG ObjectType)
+#else /* !GDI_DEBUG */
GDIOBJ_AllocObj(ULONG ObjectType)
+#endif /* GDI_DEBUG */
{
PW32PROCESS W32Process;
PGDIOBJHDR newObject;
PPAGED_LOOKASIDE_LIST LookasideList;
LONG CurrentProcessId, LockedProcessId;
+#ifdef GDI_DEBUG
+ ULONG Attempts = 0;
+#endif
ASSERT(ObjectType != GDI_OBJECT_TYPE_DONTCARE);
@@ -229,6 +242,7 @@
newObject = ExAllocateFromPagedLookasideList(LookasideList);
if(newObject != NULL)
{
+ PSLIST_ENTRY FreeEntry;
PGDI_TABLE_ENTRY Entry;
PGDIOBJ ObjectBody;
LONG TypeInfo;
@@ -244,6 +258,8 @@
newObject->Locks = 0;
#ifdef GDI_DEBUG
+ newObject->createdfile = file;
+ newObject->createdline = line;
newObject->lockfile = NULL;
newObject->lockline = 0;
#endif
@@ -253,40 +269,57 @@
RtlZeroMemory(ObjectBody, GetObjectSize(ObjectType));
TypeInfo = (ObjectType & 0xFFFF0000) | (ObjectType >> 16);
-
- /* Search for a free handle entry */
- for(Entry = &HandleTable->Entries[RESERVE_ENTRIES_COUNT];
- Entry < HandleTable->EntriesEnd;
- Entry++)
+
+ FreeEntry = InterlockedPopEntrySList(&HandleTable->FreeEntriesHead);
+ if(FreeEntry != NULL)
{
- LONG PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, 0);
+ LONG PrevProcId;
+ UINT Index;
+ HGDIOBJ Handle;
+
+ /* 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];
+ Handle = (HGDIOBJ)((Index & 0xFFFF) | (ObjectType & 0xFFFF0000));
+
+LockHandle:
+ PrevProcId = InterlockedCompareExchange(&Entry->ProcessId, LockedProcessId, 0);
if(PrevProcId == 0)
{
- if(InterlockedCompareExchangePointer(&Entry->KernelData, ObjectBody, NULL) == NULL)
- {
- HGDIOBJ Handle;
- UINT Index = GDI_ENTRY_TO_INDEX(HandleTable, Entry);
-
- Handle = (HGDIOBJ)((Index & 0xFFFF) | (ObjectType & 0xFFFF0000));
-
- /* we found a free entry, no need to exchange this field atomically
- since we're holding the lock */
- Entry->Type = TypeInfo;
+ ASSERT(Entry->KernelData == NULL);
+
+ Entry->KernelData = ObjectBody;
- InterlockedExchange(&Entry->ProcessId, CurrentProcessId);
+ /* we found a free entry, no need to exchange this field atomically
+ since we're holding the lock */
+ Entry->Type = TypeInfo;
- if(W32Process != NULL)
- {
- InterlockedIncrement(&W32Process->GDIObjects);
- }
+ /* unlock the entry */
+ InterlockedExchange(&Entry->ProcessId, CurrentProcessId);
- DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, ObjectBody);
- return Handle;
+ if(W32Process != NULL)
+ {
+ InterlockedIncrement(&W32Process->GDIObjects);
}
- else
+
+ DPRINT("GDIOBJ_AllocObj: 0x%x ob: 0x%x\n", Handle, ObjectBody);
+ return Handle;
+ }
+ else
+ {
+#ifdef GDI_DEBUG
+ if(++Attempts > 20)
{
- InterlockedExchange(&Entry->ProcessId, PrevProcId);
+ DPRINT1("[%d]Waiting on 0x%x\n", Attempts, Handle);
}
+#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();
+ /* try again */
+ goto LockHandle;
}
}
@@ -374,6 +407,10 @@
/* unlock the handle slot */
InterlockedExchange(&Entry->ProcessId, 0);
+ /* push this entry to the free list */
+ InterlockedPushEntrySList(&HandleTable->FreeEntriesHead,
+ &HandleTable->FreeEntries[GDI_ENTRY_TO_INDEX(HandleTable, Entry)]);
+
if(W32Process != NULL)
{
InterlockedDecrement(&W32Process->GDIObjects);
@@ -536,7 +573,7 @@
{
DPRINT("InitGdiObjectHandleTable\n");
- HandleTable = GDIOBJ_iAllocHandleTable (GDI_HANDLE_COUNT);
+ HandleTable = GDIOBJ_iAllocHandleTable();
DPRINT("HandleTable: %x\n", HandleTable);
}
@@ -561,7 +598,7 @@
BOOL INTERNAL_CALL
GDI_CleanupForProcess (struct _EPROCESS *Process)
{
- PGDI_TABLE_ENTRY Entry;
+ PGDI_TABLE_ENTRY Entry, End;
PEPROCESS CurrentProcess;
PW32PROCESS W32Process;
LONG ProcId;
@@ -582,8 +619,9 @@
we should delete it directly here! */
ProcId = ((LONG)Process->UniqueProcessId << 1);
+ End = &HandleTable->Entries[GDI_HANDLE_COUNT];
for(Entry = &HandleTable->Entries[RESERVE_ENTRIES_COUNT];
- Entry < HandleTable->EntriesEnd;
+ Entry < End;
Entry++, Index++)
{
/* ignore the lock bit */
@@ -832,6 +870,9 @@
Entry->KernelData = NULL;
InterlockedExchange(&Entry->ProcessId, 0);
+ InterlockedPushEntrySList(&HandleTable->FreeEntriesHead,
+ &HandleTable->FreeEntries[GDI_ENTRY_TO_INDEX(HandleTable, Entry)]);
+
if(W32Process != NULL)
{
InterlockedDecrement(&W32Process->GDIObjects);