mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
fixed timers and a wait functions, and a few bugs
svn path=/trunk/; revision=818
This commit is contained in:
parent
d4c340c696
commit
d0c1e25256
2 changed files with 45 additions and 34 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: timer.c,v 1.21 1999/11/24 11:51:50 dwelch Exp $
|
/* $Id: timer.c,v 1.22 1999/12/04 07:40:53 phreak Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* 28/05/98: Created
|
* 28/05/98: Created
|
||||||
|
* 12/3/99: Phillip Susi: enabled the timers, fixed spin lock
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTES ******************************************************************/
|
/* NOTES ******************************************************************/
|
||||||
|
@ -74,6 +75,8 @@ volatile ULONGLONG KiTimerTicks;
|
||||||
static LIST_ENTRY TimerListHead;
|
static LIST_ENTRY TimerListHead;
|
||||||
static KSPIN_LOCK TimerListLock;
|
static KSPIN_LOCK TimerListLock;
|
||||||
|
|
||||||
|
/* must raise IRQL to HIGH_LEVEL and grab spin lock there, to sync with ISR */
|
||||||
|
|
||||||
extern ULONG PiNrRunnableThreads;
|
extern ULONG PiNrRunnableThreads;
|
||||||
|
|
||||||
#define MICROSECONDS_PER_TICK (54945)
|
#define MICROSECONDS_PER_TICK (54945)
|
||||||
|
@ -239,7 +242,8 @@ BOOLEAN KeSetTimerEx(PKTIMER Timer, LARGE_INTEGER DueTime, LONG Period,
|
||||||
|
|
||||||
DPRINT("KeSetTimerEx(Timer %x)\n",Timer);
|
DPRINT("KeSetTimerEx(Timer %x)\n",Timer);
|
||||||
|
|
||||||
KeAcquireSpinLock(&TimerListLock,&oldlvl);
|
KeRaiseIrql( HIGH_LEVEL, &oldlvl );
|
||||||
|
KeAcquireSpinLockAtDpcLevel(&TimerListLock);
|
||||||
|
|
||||||
Timer->Dpc = Dpc;
|
Timer->Dpc = Dpc;
|
||||||
if (DueTime.QuadPart < 0)
|
if (DueTime.QuadPart < 0)
|
||||||
|
@ -276,7 +280,8 @@ BOOLEAN KeCancelTimer(PKTIMER Timer)
|
||||||
|
|
||||||
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
|
DPRINT("KeCancelTimer(Timer %x)\n",Timer);
|
||||||
|
|
||||||
KeAcquireSpinLock(&TimerListLock, &oldlvl);
|
KeRaiseIrql( HIGH_LEVEL, &oldlvl );
|
||||||
|
KeAcquireSpinLockAtDpcLevel( &TimerListLock );
|
||||||
|
|
||||||
if (Timer->TimerListEntry.Flink == NULL)
|
if (Timer->TimerListEntry.Flink == NULL)
|
||||||
{
|
{
|
||||||
|
@ -381,13 +386,8 @@ VOID KeExpireTimers(VOID)
|
||||||
PLIST_ENTRY current_entry = NULL;
|
PLIST_ENTRY current_entry = NULL;
|
||||||
PKTIMER current = NULL;
|
PKTIMER current = NULL;
|
||||||
KIRQL oldlvl;
|
KIRQL oldlvl;
|
||||||
|
|
||||||
// DPRINT("KeExpireTimers()\n");
|
DPRINT("KeExpireTimers()\n");
|
||||||
|
|
||||||
if (TimerInitDone == FALSE)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
current_entry = TimerListHead.Flink;
|
current_entry = TimerListHead.Flink;
|
||||||
|
|
||||||
|
@ -396,7 +396,8 @@ VOID KeExpireTimers(VOID)
|
||||||
// DPRINT("current_entry->Flink %x\n",current_entry->Flink);
|
// DPRINT("current_entry->Flink %x\n",current_entry->Flink);
|
||||||
// DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink);
|
// DPRINT("current_entry->Flink->Flink %x\n",current_entry->Flink->Flink);
|
||||||
|
|
||||||
KeAcquireSpinLock(&TimerListLock, &oldlvl);
|
KeRaiseIrql( HIGH_LEVEL, &oldlvl );
|
||||||
|
KeAcquireSpinLockAtDpcLevel(&TimerListLock);
|
||||||
|
|
||||||
while (current_entry!=(&TimerListHead))
|
while (current_entry!=(&TimerListHead))
|
||||||
{
|
{
|
||||||
|
@ -410,7 +411,7 @@ VOID KeExpireTimers(VOID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KeReleaseSpinLock(&TimerListLock,oldlvl);
|
KeReleaseSpinLock( &TimerListLock, oldlvl );
|
||||||
// DPRINT("Finished KeExpireTimers()\n");
|
// DPRINT("Finished KeExpireTimers()\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -429,6 +430,10 @@ VOID KiTimerInterrupt(VOID)
|
||||||
extern unsigned int EiUsedNonPagedPool;
|
extern unsigned int EiUsedNonPagedPool;
|
||||||
extern ULONG MiNrFreePages;
|
extern ULONG MiNrFreePages;
|
||||||
|
|
||||||
|
if (TimerInitDone == FALSE)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Increment the number of timers ticks
|
* Increment the number of timers ticks
|
||||||
*/
|
*/
|
||||||
|
@ -456,9 +461,9 @@ VOID KiTimerInterrupt(VOID)
|
||||||
// sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks,
|
// sprintf(str,"%.8u %.8u",(unsigned int)EiNrUsedBlocks,
|
||||||
// (unsigned int)EiFreeNonPagedPool);
|
// (unsigned int)EiFreeNonPagedPool);
|
||||||
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
|
// sprintf(str,"%.8u %.8u",EiFreeNonPagedPool,EiUsedNonPagedPool);
|
||||||
// sprintf(str,"%.8u %.8u",PiNrRunnableThreads,KiTimerTicks);
|
sprintf(str,"%.8u %.8u",(unsigned int)PiNrRunnableThreads,(unsigned int)KiTimerTicks);
|
||||||
sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads,
|
// sprintf(str,"%.8u %.8u", (unsigned int)PiNrRunnableThreads,
|
||||||
(unsigned int)MiNrFreePages);
|
// (unsigned int)MiNrFreePages);
|
||||||
for (i=0;i<17;i++)
|
for (i=0;i<17;i++)
|
||||||
{
|
{
|
||||||
*vidmem=str[i];
|
*vidmem=str[i];
|
||||||
|
@ -466,6 +471,7 @@ VOID KiTimerInterrupt(VOID)
|
||||||
*vidmem=0x7;
|
*vidmem=0x7;
|
||||||
vidmem++;
|
vidmem++;
|
||||||
}
|
}
|
||||||
|
KeExpireTimers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* PROGRAMMER: David Welch (welch@mcmail.com)
|
* PROGRAMMER: David Welch (welch@mcmail.com)
|
||||||
* REVISION HISTORY:
|
* REVISION HISTORY:
|
||||||
* 21/07/98: Created
|
* 21/07/98: Created
|
||||||
|
* 12/1/99: Phillip Susi: Fixed wake code in KeDispatcherObjectWake
|
||||||
|
* so that things like KeWaitForXXX() return the correct value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* NOTES ********************************************************************
|
/* NOTES ********************************************************************
|
||||||
|
@ -134,14 +136,21 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
|
||||||
|
|
||||||
while (!IsListEmpty(&(hdr->WaitListHead)))
|
while (!IsListEmpty(&(hdr->WaitListHead)))
|
||||||
{
|
{
|
||||||
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
NTSTATUS Status = STATUS_WAIT_0;
|
||||||
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
|
current_entry = RemoveHeadList(&hdr->WaitListHead);
|
||||||
|
current = CONTAINING_RECORD(current_entry,KWAIT_BLOCK,
|
||||||
WaitListEntry);
|
WaitListEntry);
|
||||||
DPRINT("Waking %x\n",current->Thread);
|
DPRINT("Waking %x\n",current->Thread);
|
||||||
|
|
||||||
if (current->WaitType == WaitAny)
|
if (current->WaitType == WaitAny)
|
||||||
{
|
{
|
||||||
DPRINT("WaitAny: Remove all wait blocks.\n");
|
DPRINT("WaitAny: Remove all wait blocks.\n");
|
||||||
|
//count the number of the wait block that is waking us, and set that as the wake status
|
||||||
|
for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock )
|
||||||
|
if( PrevBlock == current )
|
||||||
|
break;
|
||||||
|
if( PrevBlock == 0 )
|
||||||
|
DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" );
|
||||||
current->Thread->WaitBlockList = NULL;
|
current->Thread->WaitBlockList = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -180,7 +189,7 @@ static BOOLEAN KeDispatcherObjectWakeAll(DISPATCHER_HEADER* hdr)
|
||||||
KiSideEffectsBeforeWake(hdr);
|
KiSideEffectsBeforeWake(hdr);
|
||||||
|
|
||||||
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
||||||
NULL);
|
&Status);
|
||||||
};
|
};
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
@ -190,6 +199,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
|
||||||
PKWAIT_BLOCK current;
|
PKWAIT_BLOCK current;
|
||||||
PLIST_ENTRY current_entry;
|
PLIST_ENTRY current_entry;
|
||||||
PKWAIT_BLOCK PrevBlock;
|
PKWAIT_BLOCK PrevBlock;
|
||||||
|
NTSTATUS Status = STATUS_WAIT_0;
|
||||||
|
|
||||||
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",
|
||||||
|
@ -207,7 +217,13 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
|
||||||
if (current->WaitType == WaitAny)
|
if (current->WaitType == WaitAny)
|
||||||
{
|
{
|
||||||
DPRINT("WaitAny: Remove all wait blocks.\n");
|
DPRINT("WaitAny: Remove all wait blocks.\n");
|
||||||
current->Thread->WaitBlockList = NULL;
|
//count the number of the wait block that is waking us, and set that as the wake status
|
||||||
|
for( PrevBlock = current->Thread->WaitBlockList; PrevBlock; ++Status, PrevBlock = PrevBlock->NextWaitBlock )
|
||||||
|
if( PrevBlock == current )
|
||||||
|
break;
|
||||||
|
if( PrevBlock == 0 )
|
||||||
|
DbgPrint( "WaitOne: Wait Block not in list! Wait result will be corrupt\n" );
|
||||||
|
current->Thread->WaitBlockList = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -246,7 +262,7 @@ static BOOLEAN KeDispatcherObjectWakeOne(DISPATCHER_HEADER* hdr)
|
||||||
KiSideEffectsBeforeWake(hdr);
|
KiSideEffectsBeforeWake(hdr);
|
||||||
|
|
||||||
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
PsResumeThread(CONTAINING_RECORD(current->Thread,ETHREAD,Tcb),
|
||||||
NULL);
|
&Status);
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,9 +379,9 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
blk.WaitKey = 0;
|
blk.WaitKey = 0;
|
||||||
blk.WaitType = WaitAny;
|
blk.WaitType = WaitAny;
|
||||||
blk.NextWaitBlock = NULL;
|
blk.NextWaitBlock = NULL;
|
||||||
|
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x blk.WaitListEntry = %x\n",
|
||||||
|
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, blk.WaitListEntry );
|
||||||
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
|
InsertTailList(&(hdr->WaitListHead),&(blk.WaitListEntry));
|
||||||
// DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x\n",
|
|
||||||
// hdr->WaitListHead.Flink,hdr->WaitListHead.Blink);
|
|
||||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||||
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
|
DPRINT("Waiting at %s:%d with irql %d\n", __FILE__, __LINE__,
|
||||||
KeGetCurrentIrql());
|
KeGetCurrentIrql());
|
||||||
|
@ -387,9 +403,8 @@ NTSTATUS KeWaitForSingleObject(PVOID Object,
|
||||||
DPRINT("Current thread is alertable and APCs are pending\n");
|
DPRINT("Current thread is alertable and APCs are pending\n");
|
||||||
return(STATUS_USER_APC);
|
return(STATUS_USER_APC);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Returning from KeWaitForSingleObject()\n");
|
DPRINT("Returning from KeWaitForSingleObject()\n");
|
||||||
return(Status);
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -513,16 +528,6 @@ NTSTATUS KeWaitForMultipleObjects(ULONG Count,
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Returning from KeWaitForMultipleObjects()\n");
|
DPRINT("Returning from KeWaitForMultipleObjects()\n");
|
||||||
|
|
||||||
if (WaitType == WaitAny)
|
|
||||||
{
|
|
||||||
for (i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
if (((DISPATCHER_HEADER *)Object[i])->SignalState)
|
|
||||||
return(STATUS_WAIT_0+i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue