Implemented Nt/KeWaitForMultipleObjects (still buggy).

svn path=/trunk/; revision=651
This commit is contained in:
Eric Kohl 1999-09-08 23:51:36 +00:00
parent 09d88da5e9
commit 1fc6701c79

View file

@ -73,7 +73,9 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
{ {
PKWAIT_BLOCK current; PKWAIT_BLOCK current;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
DPRINT("KeDispatcherObjectWakeAll(hdr %x)\n",hdr);
if (IsListEmpty(&hdr->WaitListHead)) if (IsListEmpty(&hdr->WaitListHead))
{ {
return(FALSE); return(FALSE);
@ -84,7 +86,13 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
current_entry = RemoveHeadList(&hdr->WaitListHead); current_entry = RemoveHeadList(&hdr->WaitListHead);
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK, current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
WaitListEntry); WaitListEntry);
DPRINT("Waking %x\n",current->Thread); DPRINT("Waking %x\n",current->Thread);
if (current->NextWaitBlock != NULL)
{
DbgPrint("DANGLING POINTERS!!! We're in trouble!\n");
}
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb)); PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb));
}; };
return(TRUE); return(TRUE);
@ -94,7 +102,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
{ {
PKWAIT_BLOCK current; PKWAIT_BLOCK current;
PLIST_ENTRY current_entry; PLIST_ENTRY current_entry;
DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr); DPRINT("KeDispatcherObjectWakeOn(hdr %x)\n",hdr);
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
@ -120,7 +128,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
*/ */
{ {
BOOL Ret; BOOL Ret;
DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr); DPRINT("Entering KeDispatcherObjectWake(hdr %x)\n",hdr);
// DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n", // DPRINT("hdr->WaitListHead %x hdr->WaitListHead.Flink %x\n",
// &hdr->WaitListHead,hdr->WaitListHead.Flink); // &hdr->WaitListHead,hdr->WaitListHead.Flink);
@ -129,7 +137,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
{ {
case NotificationEvent: case NotificationEvent:
return(KeDispatcherObjectWakeAll(hdr)); return(KeDispatcherObjectWakeAll(hdr));
case SynchronizationEvent: case SynchronizationEvent:
Ret = KeDispatcherObjectWakeOne(hdr); Ret = KeDispatcherObjectWakeOne(hdr);
if (Ret) if (Ret)
@ -137,7 +145,7 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
hdr->SignalState = FALSE; hdr->SignalState = FALSE;
} }
return(Ret); return(Ret);
case SemaphoreType: case SemaphoreType:
if(hdr->SignalState>0) if(hdr->SignalState>0)
{ {
@ -159,8 +167,8 @@ BOOLEAN KeDispatcherObjectWake(DISPATCHER_HEADER* hdr)
KeBugCheck(0); KeBugCheck(0);
return(FALSE); return(FALSE);
} }
NTSTATUS KeWaitForSingleObject(PVOID Object, NTSTATUS KeWaitForSingleObject(PVOID Object,
KWAIT_REASON WaitReason, KWAIT_REASON WaitReason,
KPROCESSOR_MODE WaitMode, KPROCESSOR_MODE WaitMode,
@ -182,14 +190,14 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
{ {
DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object; DISPATCHER_HEADER* hdr = (DISPATCHER_HEADER *)Object;
KWAIT_BLOCK blk; KWAIT_BLOCK blk;
DPRINT("Entering KeWaitForSingleObject(Object %x) " DPRINT("Entering KeWaitForSingleObject(Object %x) "
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); "PsGetCurrentThread() %x\n",Object,PsGetCurrentThread());
KeAcquireDispatcherDatabaseLock(FALSE); KeAcquireDispatcherDatabaseLock(FALSE);
DPRINT("hdr->SignalState %d\n", hdr->SignalState); DPRINT("hdr->SignalState %d\n", hdr->SignalState);
if (hdr->SignalState > 0) if (hdr->SignalState > 0)
{ {
switch (hdr->Type) switch (hdr->Type)
@ -204,7 +212,7 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
case ID_PROCESS_OBJECT: case ID_PROCESS_OBJECT:
break; break;
case ID_THREAD_OBJECT: case ID_THREAD_OBJECT:
break; break;
case NotificationEvent: case NotificationEvent:
@ -224,10 +232,10 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
{ {
KeAddThreadTimeout(KeGetCurrentThread(),Timeout); KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
} }
blk.Object=Object; blk.Object=Object;
blk.Thread=KeGetCurrentThread(); blk.Thread=KeGetCurrentThread();
blk.WaitKey = WaitReason; // Assumed blk.WaitKey = 0;
blk.WaitType = WaitAll; blk.WaitType = WaitAll;
blk.NextWaitBlock = NULL; blk.NextWaitBlock = NULL;
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
@ -255,91 +263,126 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
PLARGE_INTEGER Timeout, PLARGE_INTEGER Timeout,
PKWAIT_BLOCK WaitBlockArray) PKWAIT_BLOCK WaitBlockArray)
{ {
#if 0 DISPATCHER_HEADER* hdr;
DISPATCHER_HEADER* hdr; PKWAIT_BLOCK blk;
PKWAIT_BLOCK blk; ULONG CountSignaled;
ULONG Counter; ULONG i;
DPRINT("Entering KeWaitForSingleObject(Object %x) " DbgPrint("Entering KeWaitForMultipleObjects(Count %lu Object[] %p) "
"PsGetCurrentThread() %x\n",Object,PsGetCurrentThread()); "PsGetCurrentThread() %x\n",Count,Object,PsGetCurrentThread());
KeAcquireDispatcherDatabaseLock(FALSE); CountSignaled = 0;
for (Counter = 0; Counter < Count; Counter++) if (WaitBlockArray == NULL)
{ {
hdr = (DISPATCHER_HEADER *)Object[Counter]; DbgPrint("FIXME: Use internal wait blocks!\n");
return STATUS_UNSUCCESSFUL;
}
else
{
if (Count > 64)
{
DbgPrint("Too many objects!\n");
return STATUS_UNSUCCESSFUL;
}
blk = WaitBlockArray;
}
DPRINT("hdr->SignalState %d\n", hdr->SignalState); KeAcquireDispatcherDatabaseLock(FALSE);
for (i = 0; i < Count; i++)
{
hdr = (DISPATCHER_HEADER *)Object[i];
// DbgPrint("hdr->SignalState %d\n", hdr->SignalState);
if (hdr->SignalState > 0) if (hdr->SignalState > 0)
{ {
switch (hdr->Type) CountSignaled++;
{
case SynchronizationEvent: switch (hdr->Type)
{
case SynchronizationEvent:
hdr->SignalState = FALSE; hdr->SignalState = FALSE;
break; break;
case SemaphoreType: case SemaphoreType:
break; break;
case ID_PROCESS_OBJECT: case ID_PROCESS_OBJECT:
break; break;
case ID_THREAD_OBJECT: case ID_THREAD_OBJECT:
break; break;
case NotificationEvent: case NotificationEvent:
break; break;
default: default:
DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n", DbgPrint("(%s:%d) Dispatcher object %x has unknown type\n",
__FILE__,__LINE__,hdr); __FILE__,__LINE__,hdr);
KeBugCheck(0); KeBugCheck(0);
}
} if (WaitType == WaitAny)
KeReleaseDispatcherDatabaseLock(FALSE); {
return(STATUS_SUCCESS); KeReleaseDispatcherDatabaseLock(FALSE);
} DbgPrint("One object is already signaled!\n");
} return(STATUS_SUCCESS);
}
}
}
if (Timeout != NULL) if ((WaitType == WaitAll) && (CountSignaled == Count))
{ {
KeReleaseDispatcherDatabaseLock(FALSE);
DbgPrint("All objects are already signaled!\n");
return(STATUS_SUCCESS);
}
if (Timeout != NULL)
{
KeAddThreadTimeout(KeGetCurrentThread(),Timeout); KeAddThreadTimeout(KeGetCurrentThread(),Timeout);
} }
for (Counter = 0; Counter < Count; Counter++) for (i = 0; i < Count; i++)
{ {
hdr = (DISPATCHER_HEADER *)Object[Counter]; hdr = (DISPATCHER_HEADER *)Object[i];
blk = &WaitBlockArray[Counter]; DbgPrint("hdr->SignalState %d\n", hdr->SignalState);
blk->Object=Object[Counter]; blk->Object=Object[i];
blk->Thread=KeGetCurrentThread(); blk->Thread=KeGetCurrentThread();
blk->WaitKey = WaitReason; // Assumed blk->WaitKey = i;
blk->WaitType = WaitType; blk->WaitType = WaitType;
blk->NextWaitBlock = NULL; if (i == Count - 1)
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry)); blk->NextWaitBlock = NULL;
else
blk->NextWaitBlock = (PVOID)((ULONG)blk+sizeof(KWAIT_BLOCK));
DbgPrint("blk %p blk->NextWaitBlock %p\n",
blk, blk->NextWaitBlock);
InsertTailList(&(hdr->WaitListHead),&(blk->WaitListEntry));
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n", // DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink); // hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
}
KeReleaseDispatcherDatabaseLock(FALSE); blk = blk->NextWaitBlock;
}
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__, KeReleaseDispatcherDatabaseLock(FALSE);
KeGetCurrentIrql());
PsSuspendThread(PsGetCurrentThread()); DbgPrint("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
KeGetCurrentIrql());
if (Timeout != NULL) PsSuspendThread(PsGetCurrentThread());
{
if (Timeout != NULL)
{
KeCancelTimer(&KeGetCurrentThread()->Timer); KeCancelTimer(&KeGetCurrentThread()->Timer);
} }
DPRINT("Returning from KeWaitForMultipleObject()\n");
return(STATUS_SUCCESS); DbgPrint("Returning from KeWaitForMultipleObjects()\n");
#else
UNIMPLEMENTED; return STATUS_SUCCESS;
#endif
} }
VOID KeInitializeDispatcher(VOID) VOID KeInitializeDispatcher(VOID)
@ -347,6 +390,7 @@ VOID KeInitializeDispatcher(VOID)
KeInitializeSpinLock(&DispatcherDatabaseLock); KeInitializeSpinLock(&DispatcherDatabaseLock);
} }
NTSTATUS NTSTATUS
STDCALL STDCALL
NtWaitForMultipleObjects ( NtWaitForMultipleObjects (
@ -357,9 +401,10 @@ NtWaitForMultipleObjects (
IN PLARGE_INTEGER Time IN PLARGE_INTEGER Time
) )
{ {
#if 0 KWAIT_BLOCK WaitBlockArray[64];
KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS]; PVOID ObjectPtrArray[64];
PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS]; // KWAIT_BLOCK WaitBlockArray[MAXIMUM_WAIT_OBJECTS];
// PVOID ObjectPtrArray[MAXIMUM_WAIT_OBJECTS];
NTSTATUS Status; NTSTATUS Status;
ULONG i, j; ULONG i, j;
@ -367,8 +412,10 @@ NtWaitForMultipleObjects (
DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n", DPRINT("NtWaitForMultipleObjects(Count %lu Object[] %x, Alertable %d, Time %x)\n",
Count,Object,Alertable,Time); Count,Object,Alertable,Time);
if (Count > MAXIMUM_WAIT_OBJECTS) if (Count > 64)
return ...; /* WAIT_FAIL */ // if (Count > MAXIMUM_WAIT_OBJECTS)
return STATUS_UNSUCCESSFUL;
// return WAIT_FAIL; /* this must be returned by WaitForMultipleObjects */
/* reference all objects */ /* reference all objects */
for (i = 0; i < Count; i++) for (i = 0; i < Count; i++)
@ -394,7 +441,7 @@ NtWaitForMultipleObjects (
Status = KeWaitForMultipleObjects(Count, Status = KeWaitForMultipleObjects(Count,
ObjectPtrArray, ObjectPtrArray,
WaitType, WaitType,
UserMode, UserRequest,
UserMode, UserMode,
Alertable, Alertable,
Time, Time,
@ -407,9 +454,6 @@ NtWaitForMultipleObjects (
} }
return(Status); return(Status);
#else
UNIMPLEMENTED;
#endif
} }