Reimplimented IO Timers correctly.

svn path=/trunk/; revision=11550
This commit is contained in:
Alex Ionescu 2004-11-06 04:12:59 +00:00
parent caa0346413
commit 8cb1d77efd
6 changed files with 170 additions and 44 deletions

View file

@ -1,4 +1,4 @@
/* $Id: iotypes.h,v 1.68 2004/10/31 23:40:10 ion Exp $
/* $Id: iotypes.h,v 1.69 2004/11/06 04:12:59 ion Exp $
*
*/
@ -1065,15 +1065,15 @@ typedef VOID STDCALL_FUNC
/*
* PURPOSE: Special timer associated with each device
* NOTES: This is a guess
*/
typedef struct _IO_TIMER
{
KTIMER timer;
KDPC dpc;
PDEVICE_OBJECT DeviceObject;
PIO_TIMER_ROUTINE TimerRoutine;
PVOID Context;
#define IO_TYPE_TIMER 9
typedef struct _IO_TIMER {
USHORT Type; /* Every IO Object has a Type */
USHORT TimerEnabled; /* Tells us if the Timer is enabled or not */
LIST_ENTRY IoTimerList; /* List of other Timers on the system */
PIO_TIMER_ROUTINE TimerRoutine; /* The associated timer routine */
PVOID Context; /* Context */
PDEVICE_OBJECT DeviceObject; /* Driver that owns this IO Timer */
} IO_TIMER, *PIO_TIMER;
typedef struct _IO_WORKITEM *PIO_WORKITEM;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: io.h,v 1.47 2004/10/23 17:32:50 navaraf Exp $
/* $Id: io.h,v 1.48 2004/11/06 04:12:59 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -512,4 +512,14 @@ IopInvalidateDeviceRelations(
IN PDEVICE_NODE DeviceNode,
IN DEVICE_RELATION_TYPE Type);
/* timer.c */
VOID
FASTCALL
IopInitTimerImplementation(VOID);
VOID
STDCALL
IopRemoveTimerFromTimerList(
IN PIO_TIMER Timer
);
#endif

View file

@ -1,4 +1,4 @@
/* $Id: device.c,v 1.82 2004/10/23 17:32:50 navaraf Exp $
/* $Id: device.c,v 1.83 2004/11/06 04:12:59 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -188,7 +188,7 @@ IoDeleteDevice(PDEVICE_OBJECT DeviceObject)
/* Remove the timer if it exists */
if (DeviceObject->Timer)
{
IoStopTimer(DeviceObject);
IopRemoveTimerFromTimerList(DeviceObject->Timer);
ExFreePool(DeviceObject->Timer);
}

View file

@ -1,4 +1,4 @@
/* $Id: iomgr.c,v 1.52 2004/09/08 11:42:56 ekohl Exp $
/* $Id: iomgr.c,v 1.53 2004/11/06 04:12:59 ion Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
@ -520,6 +520,7 @@ IoInit (VOID)
IoInitVpbImplementation();
IoInitShutdownNotification();
IopInitErrorLog();
IopInitTimerImplementation();
/*
* Create link from '\DosDevices' to '\??' directory

View file

@ -1,5 +1,4 @@
/* $Id: timer.c,v 1.12 2004/08/15 16:39:03 chorns Exp $
*
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/io/timer.c
@ -7,29 +6,110 @@
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
* Created 22/05/98
* Reimplemented 05/11/04 - Alex Ionescu (alex@relsoft.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
//#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
/* GLOBALS *******************************************************************/
#define TAG_IO_TIMER TAG('I', 'O', 'T', 'M')
/* Timer Database */
KSPIN_LOCK IopTimerLock;
LIST_ENTRY IopTimerQueueHead;
/* Timer Firing */
KDPC IopTimerDpc;
KTIMER IopTimer;
/* Keep count of how many timers we have */
ULONG IopTimerCount = 0;
/* FUNCTIONS *****************************************************************/
static VOID STDCALL
IoTimerCallback(IN PKDPC Dpc,
IopTimerDispatch(IN PKDPC Dpc,
IN PVOID DeferredContext,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2)
{
PIO_TIMER Timer = (PIO_TIMER) DeferredContext;
KIRQL OldIrql;
PLIST_ENTRY TimerEntry;
PIO_TIMER Timer;
ULONG i;
DPRINT("Dispatching IO Timers. There are: %x \n", IopTimerCount);
/* Check if any Timers are actualyl enabled as of now */
if (IopTimerCount) {
/* Lock the Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Call the Timer Routine of each enabled Timer */
for(TimerEntry = IopTimerQueueHead.Flink, i = IopTimerCount;
(TimerEntry != &IopTimerQueueHead) && i;
TimerEntry = TimerEntry->Flink) {
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
Timer = CONTAINING_RECORD(TimerEntry, IO_TIMER, IoTimerList);
if (Timer->TimerEnabled) {
DPRINT("Dispatching a Timer Routine: %x for Device Object: %x \n",
Timer->TimerRoutine,
Timer->DeviceObject);
Timer->TimerRoutine(Timer->DeviceObject, Timer->Context);
i--;
}
}
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
}
VOID
STDCALL
IopRemoveTimerFromTimerList(
IN PIO_TIMER Timer
)
{
KIRQL OldIrql;
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* Remove Timer from the List and Drop the Timer Count if Enabled */
RemoveEntryList(&Timer->IoTimerList);
if (Timer->TimerEnabled) IopTimerCount--;
/* Unlock the Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
}
VOID
FASTCALL
IopInitTimerImplementation(VOID)
/* FUNCTION: Initializes the IO Timer Object Implementation
* RETURNS: NOTHING
*/
{
LARGE_INTEGER ExpireTime;
/* Initialize Timer List Lock */
KeInitializeSpinLock(&IopTimerLock);
/* Initialize Timer List */
InitializeListHead(&IopTimerQueueHead);
/* Initialize the DPC/Timer which will call the other Timer Routines */
ExpireTime.QuadPart = -10000000;
KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL);
KeInitializeTimerEx(&IopTimer, SynchronizationTimer);
KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc);
}
/*
@ -51,16 +131,32 @@ IoInitializeTimer(PDEVICE_OBJECT DeviceObject,
* RETURNS: Status
*/
{
DeviceObject->Timer = ExAllocatePoolWithTag(NonPagedPool, sizeof(IO_TIMER),
TAG_IO_TIMER);
DeviceObject->Timer->DeviceObject = DeviceObject;
DeviceObject->Timer->TimerRoutine = TimerRoutine;
DeviceObject->Timer->Context = Context;
KeInitializeTimer(&(DeviceObject->Timer->timer));
KeInitializeDpc(&(DeviceObject->Timer->dpc),
IoTimerCallback, DeviceObject->Timer);
DPRINT("IoInitializeTimer() called for Device Object: %x with Routine: %x \n", DeviceObject, TimerRoutine);
/* Allocate Timer */
if (!DeviceObject->Timer) {
DeviceObject->Timer = ExAllocatePoolWithTag(NonPagedPool,
sizeof(IO_TIMER),
TAG_IO_TIMER);
if (!DeviceObject->Timer) return STATUS_INSUFFICIENT_RESOURCES;
/* Set up the Timer Structure */
DeviceObject->Timer->Type = IO_TYPE_TIMER;
DeviceObject->Timer->DeviceObject = DeviceObject;
}
DeviceObject->Timer->TimerRoutine = TimerRoutine;
DeviceObject->Timer->Context = Context;
DeviceObject->Timer->TimerEnabled = FALSE;
/* Add it to the Timer List */
ExInterlockedInsertTailList(&IopTimerQueueHead,
&DeviceObject->Timer->IoTimerList,
&IopTimerLock);
return(STATUS_SUCCESS);
/* Return Success */
DPRINT("IoInitializeTimer() Completed\n");
return(STATUS_SUCCESS);
}
/*
@ -76,16 +172,22 @@ IoStartTimer(PDEVICE_OBJECT DeviceObject)
* DeviceObject = Device whose timer is to be started
*/
{
LONGLONG lli;
LARGE_INTEGER li;
lli = -1000000;
li = *(LARGE_INTEGER *)&lli;
KeSetTimerEx(&DeviceObject->Timer->timer,
li,
1000,
&(DeviceObject->Timer->dpc));
KIRQL OldIrql;
DPRINT("IoStartTimer for Device Object: %x\n", DeviceObject);
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* If the timer isn't already enabled, enable it and increase IO Timer Count*/
if (!DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = TRUE;
IopTimerCount++;
}
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStartTimer Completed for Device Object: %x New Count: %x \n", DeviceObject, IopTimerCount);
}
/*
@ -101,7 +203,22 @@ IoStopTimer(PDEVICE_OBJECT DeviceObject)
* DeviceObject = Device whose timer is to be stopped
*/
{
KeCancelTimer(&(DeviceObject->Timer->timer));
KIRQL OldIrql;
DPRINT("IoStopTimer for Device Object: %x\n", DeviceObject);
/* Lock Timers */
KeAcquireSpinLock(&IopTimerLock, &OldIrql);
/* If the timer is enabled, disable it and decrease IO Timer Count*/
if (DeviceObject->Timer->TimerEnabled) {
DeviceObject->Timer->TimerEnabled = FALSE;
IopTimerCount--;
}
/* Unlock Timers */
KeReleaseSpinLock(&IopTimerLock, OldIrql);
DPRINT("IoStopTimer Completed for Device Object: %x New Count: %x \n", DeviceObject, IopTimerCount);
}

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* $Id: gmutex.c,v 1.1 2004/10/31 21:21:14 ea Exp $
/* $Id: gmutex.c,v 1.2 2004/11/06 04:12:59 ion Exp $
*
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/gmutex.c
@ -34,13 +34,11 @@
/* FUNCTIONS *****************************************************************/
/*
KiWaitForGuardedMutexGate
KeAcquireGuardedMutex
KeAcquireGuardedMutexUnsafe
KeEnterGuardedRegion
KeInitializeGuardedMutex
KeReleaseGuardedMutexUnsafe
WmipTraceGuardedMutex
KeAcquireGuardedMutex
KeTryToAcquireGuardedMutex
KeReleaseGuardedMutex
KeLeaveGuardedRegion