Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging

The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.

Check out The OSR Learning Library at:

Why is KTIMER useful?

0xrepnz0xrepnz Member Posts: 16
edited January 18 in NTDEV

I have this exercise where I have PASSIVE_LEVEL job I need to perform every 10 seconds.
I can use KTIMER, But then (as far as I know) the routine will run at DISPATCH_LEVEL so I'll have to use a work item to queue the job..
I found it was easier to just create a system thread then use KeWaitForSingleObject like this:


typedef struct _PERIODIC_JOB {
    PVOID Context;
    KEVENT ExitEvent;
    LARGE_INTEGER Interval;
    HANDLE SystemThreadHandle;

    __in PVOID Context
    NTSTATUS Status;

    while (TRUE) {

        Status = KeWaitForSingleObject(

        if (Status == STATUS_SUCCESS) {
            // The thread was signaled to exit.

        if (Status == STATUS_TIMEOUT) {


    __out PERIODIC_JOB* Job,
    __in PERIODIC_ROUTINE Routine,
    __in PLARGE_INTEGER Interval,
    __in_opt PVOID Context
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ThreadAttributes;

    RtlZeroMemory(Job, sizeof(PERIODIC_JOB));

    Job->Context = Context;
    Job->Routine = Routine;
    Job->Interval.QuadPart = Interval->QuadPart;

    KeInitializeEvent(&Job->ExitEvent, NotificationEvent, FALSE);

    InitializeObjectAttributes(&ThreadAttributes, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

    return PsCreateSystemThread(

    __in PERIODIC_JOB* Job,
    __in PLARGE_INTEGER Timeout
    KeSetEvent(&Job->ExitEvent, IO_NO_INCREMENT, FALSE);
    return ZwWaitForSingleObject(Job->SystemThreadHandle, FALSE, Timeout);

My question is:
1) What is the general use case of KTIMER? In which case it's useful?
2) Is it bad to use a system thread like I did?

I guess that in my case it does not really matter but in case the timer is not a periodic timer it's better to use KeSetTimer to save the overhead
of creating threads..

Sorry in advance if I'm missing something.

Thank you :smiley:


  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,911

    You use timers whenever you want a callback at IRQL DISPATCH_LEVEL that occurs after some amount of time has elapsed. Any time you’re waiting for something to happen that has a max time that it should take.

    If you want to do something (a) periodically, (b) you need to do that at IRQL PASSIVE_LEVEL, and you’re willing to accept the overhead of the scheduling operations (inherent in doing the work at IRQ PASSIVE_LEVEL in any case), it’s probably worth spinning up a system thread as you have done.

    Otherwise, KTIMER is your friend.


    Peter Viscarola

  • 0xrepnz0xrepnz Member Posts: 16
    edited January 18
    Thank you for your answer!

    >Any time you’re waiting for something to happen that has a max time that it should take.

    If I understand correctly, In this case I can still use KEVENT and call KeWaitForSingleObject to wait for this max time, then signal the event when the job is done. The only advantage I can think of is the fact that I don't need to block any thread while waiting for the callback

    Can you give me one real scenario where KTIMER would be useful?
  • Peter_Viscarola_(OSR)Peter_Viscarola_(OSR) Administrator Posts: 7,911

    In this case I can still use KEVENT and call KeWaitForSingleObject to wait for this max time

    Hmmm... in what context? Still in your system thread, perhaps. Otherwise, you don’t want to block an arbitrary thread, right?

    Can you give me one real scenario where KTIMER would be useful?

    It’s very device dependent, of course. How about for a deadman timer on a decide? You start a request on the device, and it’s supposed to finish in less than 250ms and if it doesn’t, you need to reset the the device and retry the request... so, you set the timer to manage the timeout.

    Or during device initialization: You start the device initializing and then you need to wait for some time before the device is ready to process requests. Again, you set use a timer here.

    Really, the KTIMER is your go to facility for managing timeouts. It’s less common to want to spin a thread for this and run the timeout at PASSIVE_LEVEL.


    Peter Viscarola

  • 0xrepnz0xrepnz Member Posts: 16

    Ok, thanks!

Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA