mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
Reimplimented IO Timers correctly.
svn path=/trunk/; revision=11550
This commit is contained in:
parent
caa0346413
commit
8cb1d77efd
6 changed files with 170 additions and 44 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue