Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

SetWaitableTimer for Use In Waking Machine from Hibernate

529 views
Skip to first unread message

sengsational

unread,
Apr 24, 2008, 3:12:15 PM4/24/08
to
I've got some code working that prints timestamp one
and timestamp two. They are one minute apart.

(pseudo code):
HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL)
LARGE_INTEGER DueTime.QuadPart = -oneMinute // relative
SetWaitableTimer(hTimer, &DueTime, 0, NULL, NULL, TRUE) //last parm
for wakeup
(>>> print timestamp one here)
int waitResult = WaitForSingleObject(hTimer, INFINITE)
(>>> print timestamp two here)

But if I hibernate my machine after I see
timestamp one print out, the machine does not wake-up
to print timestamp two.

If I manually resume my machine, it prints timestamp two
but of the difference between the two timestamps
is greater than one minute (depending on how long I wait
to do the manual resume).

I have read the references, below, but I must be missing
something. Should the above code work to resume a machine,
or do I need to do something else?

--Dale--

References:
SetWaitbleTimer http://msdn2.microsoft.com/en-us/library/ms686289(VS.85).aspx
WaitForSingleObject http://msdn2.microsoft.com/en-us/library/ms687032.aspx
Using Waitable Timer Objects http://msdn2.microsoft.com/en-us/library/ms687008(VS.85).aspx

Kellie Fitton

unread,
Apr 24, 2008, 10:32:59 PM4/24/08
to
On Apr 24, 12:12 pm, sengsational <DRS.Use...@sengsational.com> wrote:
> I've got some code working that prints timestamp one
> and timestamp two.  They are one minute apart.
>
> (pseudo code):
> HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL)
> LARGE_INTEGER DueTime.QuadPart = -oneMinute // relative
> SetWaitableTimer(hTimer, &DueTime, 0, NULL, NULL, TRUE)  //last parm
> for wakeup
> (>>> print timestamp one here)
> int waitResult = WaitForSingleObject(hTimer, INFINITE)
> (>>> print timestamp two here)
>
> But if I hibernate my machine after I see
> timestamp one print out, the machine does not wake-up
> to print timestamp two.
>
> If I manually resume my machine, it prints timestamp two
> but of the difference between the two timestamps
> is greater than one minute (depending on how long I wait
> to do the manual resume).
>
> I have read the references, below, but I must be missing
> something.  Should the above code work to resume a machine,
> or do I need to do something else?
>
> --Dale--
>


Hi,

You need to create a periodic/synchronization timer,
with the following approach you can wake-up Windows
and the machine from hibernation immediately after
the dueTime have elapsed:

CreateWaitableTimer(NULL, FALSE, NULL);

SetWaitableTimer(hTimer, &dueTime, 1000, NULL, NULL, TRUE);

SetSuspendState(TRUE, FALSE, FALSE);

CancelWaitableTimer(hTimer);

http://msdn2.microsoft.com/en-us/library/aa373201(VS.85).aspx

Kellie.

sengsational

unread,
Apr 25, 2008, 8:54:54 AM4/25/08
to
On Apr 24, 10:32 pm, Kellie Fitton <KELLIEFIT...@yahoo.com> wrote:
> On Apr 24, 12:12 pm, sengsational <DRS.Use...@sengsational.com> wrote:
> > (pseudo code):
> > HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL)
> > LARGE_INTEGER DueTime.QuadPart = -oneMinute // relative
> > SetWaitableTimer(hTimer, &DueTime, 0, NULL, NULL, TRUE)
> > (>>> print timestamp one here)
> > int waitResult = WaitForSingleObject(hTimer, INFINITE)
> > (>>> print timestamp two here)
>
> > But if I hibernate my machine after I see
> > timestamp one print out, the machine does not wake-up
> > to print timestamp two.
>
> You need to create a periodic/synchronization timer,
> with the following approach you can wake-up Windows
> and the machine from hibernation immediately after
> the dueTime have elapsed:
>
> CreateWaitableTimer(NULL, FALSE, NULL);
> SetWaitableTimer(hTimer, &dueTime, 1000, NULL, NULL, TRUE);
> SetSuspendState(TRUE, FALSE, FALSE);
> CancelWaitableTimer(hTimer);
>
> http://msdn2.microsoft.com/en-us/library/aa373201(VS.85).aspx

Thanks again Kellie for your kind attention.

I noticed that you suggested the bManualReset (second
parameter of CreateWaitableTimer) be set to FALSE,
indicating a synchronization timer, and the lPeriod
(third parameter of SetWaitableTimer) be 1000. I had
TRUE and 0 earlier for those, respectively.

I changed the above to match your suggestion, and I
substituted SetSuspendState instead of using the
WaitForSingleObject.

When the program hits the SetSuspendState, the
machine begins hibernation, but at the end of the
dueTime, the machine STILL does not resume. When
I manually resume the machine, I see that the code
after the SetSuspendState statement begins executing.

If you, or any lurkers, have any more suggestions,
I'd love to hear them. Thanks.

--Dale--

Kellie Fitton

unread,
Apr 25, 2008, 3:15:21 PM4/25/08
to
On Apr 25, 5:54 am, sengsational <DRS.Use...@sengsational.com> wrote:
> Thanks again Kellie for your kind attention.
>
> I noticed that you suggested the bManualReset (second
> parameter of CreateWaitableTimer) be set to FALSE,
> indicating a synchronization timer, and the lPeriod
> (third parameter of SetWaitableTimer) be 1000.  I had
> TRUE and 0 earlier for those, respectively.
>
> I changed the above to match your suggestion, and I
> substituted SetSuspendState instead of using the
> WaitForSingleObject.
>
> When the program hits the SetSuspendState, the
> machine begins hibernation, but at the end of the
> dueTime, the machine STILL does not resume.  When
> I manually resume the machine, I see that the code
> after the SetSuspendState statement begins executing.
>
> If you, or any lurkers, have any more suggestions,
> I'd love to hear them.  Thanks.
>
> --Dale---


Hi Dale,

Are you running your program under Windows Vista ?

My program runs under Windows XP sp2 and it wakes up
Windows/machine from hibernation without any problems.

Just make sure you don't have any computer bootup issues
with any of the devices installed.

Kellie.


sengsational

unread,
Apr 25, 2008, 3:43:59 PM4/25/08
to
On Apr 25, 3:15 pm, Kellie Fitton <KELLIEFIT...@yahoo.com> wrote:
> On Apr 25, 5:54 am, sengsational <DRS.Use...@sengsational.com> wrote:
> > I noticed that you suggested the bManualReset (second
> > parameter of CreateWaitableTimer) be set to FALSE,
> > indicating a synchronization timer, and the lPeriod
> > (third parameter of SetWaitableTimer) be 1000. I had
> > TRUE and 0 earlier for those, respectively.
>
> > I changed the above to match your suggestion, and I
> > substituted SetSuspendState instead of using the
> > WaitForSingleObject.
>
> > When the program hits the SetSuspendState, the
> > machine begins hibernation, but at the end of the
> > dueTime, the machine STILL does not resume. When
> > I manually resume the machine, I see that the code
> > after the SetSuspendState statement begins executing.
>
> > If you, or any lurkers, have any more suggestions,
> > I'd love to hear them. Thanks.
>
> Are you running your program under Windows Vista ?
>
> My program runs under Windows XP sp2 and it wakes up
> Windows/machine from hibernation without any problems.

Kellie,

Thanks again for your reply and confirmation that the
technique you have identified really works for you.

Scheduled tasks seem to wake the machine (also XP),
so the machine can be restored, but just not using the
technique I'm trying to use (which isn't exactly the
technique you are using).

There's a difference in my implementation that
I have not yet mentioned that I will accept now as the
root cause of the problem: I'm making these kernel32
calls through a tool called JNA (Java Native Access
https://jna.dev.java.net). There must be something
about how JNA works that prevents this from waking
the machine.

Thanks again. If I ever get this figured out, I'll come
back and update the thread.

--Dale--

Christian ASTOR

unread,
May 1, 2008, 2:04:27 AM5/1/08
to
sengsational wrote:

> Scheduled tasks seem to wake the machine (also XP),
> so the machine can be restored, but just not using the
> technique I'm trying to use (which isn't exactly the
> technique you are using).

It just uses CreateWaitableTimer()-SetWaitableTimer()
then WaitForMultipleObjects() on various events.

Bob Masta

unread,
May 1, 2008, 8:48:24 AM5/1/08
to
On Thu, 24 Apr 2008 12:12:15 -0700 (PDT), sengsational
<DRS.U...@sengsational.com> wrote:

>I've got some code working that prints timestamp one
>and timestamp two. They are one minute apart.
>
>(pseudo code):
>HANDLE hTimer = CreateWaitableTimer(NULL, TRUE, NULL)
>LARGE_INTEGER DueTime.QuadPart = -oneMinute // relative
>SetWaitableTimer(hTimer, &DueTime, 0, NULL, NULL, TRUE) //last parm
>for wakeup
>(>>> print timestamp one here)
>int waitResult = WaitForSingleObject(hTimer, INFINITE)
>(>>> print timestamp two here)
>
>But if I hibernate my machine after I see
>timestamp one print out, the machine does not wake-up
>to print timestamp two.
>
>If I manually resume my machine, it prints timestamp two
>but of the difference between the two timestamps
>is greater than one minute (depending on how long I wait
>to do the manual resume).
>
>I have read the references, below, but I must be missing
>something. Should the above code work to resume a machine,
>or do I need to do something else?
>

I've just had occasion to implement a waitable timer, and it does wake
from a manual suspend. It looks almost identical to your pseudo-code.
So I wonder if the problem is in the value you pass for the duration.
This must be the negation of the number of 100 nsec ticks; for one
minute it would be -(1e7 * 60 * 60) = -3.6e10.

Also note that the wake time is the time wake-up *starts*. The actual
wake-up from hibernation can be quite lengthy, so timestamp 2 will
always be later than you set. One way to handle this is to set 2
timers: The first does nothing other than to wake the machine ahead
of the actual target time; the second causes the desired action, with
no wake-up latency.

Best regards,


Bob Masta

DAQARTA v3.50
Data AcQuisition And Real-Time Analysis
www.daqarta.com
Scope, Spectrum, Spectrogram, FREE Signal Generator
Science with your sound card!

sengsational

unread,
May 1, 2008, 1:29:54 PM5/1/08
to
On Apr 25, 3:43 pm, sengsational <DRS.Use...@sengsational.com> wrote:
> On Apr 25, 3:15 pm, Kellie Fitton <KELLIEFIT...@yahoo.com> wrote:
> > On Apr 25, 5:54 am, sengsational <DRS.Use...@sengsational.com> wrote:
> > > When the program hits the SetSuspendState, the
> > > machine begins hibernation, but at the end of the
> > > dueTime, the machine STILL does not resume. When
> > > I manually resume the machine, I see that the code
> > > after the SetSuspendState statement begins executing.
>
> > > If you, or any lurkers, have any more suggestions,
> > > I'd love to hear them. Thanks.
>
> > My program runs under Windows XP sp2 and it wakes up
> > Windows/machine from hibernation without any problems.
>
> Kellie,
>
> Thanks again for your reply and confirmation that the
> technique you have identified really works for you.
>
> There's a difference in my implementation that
> I have not yet mentioned that I will accept now as the
> root cause of the problem: I'm making these kernel32
> calls through a tool called JNA (Java Native Access
> https://jna.dev.java.net). There must be something
> about how JNA works that prevents this from waking
> the machine.
>
> Thanks again. If I ever get this figured out, I'll come
> back and update the thread.

It has been figured-out (notice I didn't say "I" figured
it out!)

When calling the SetWaitableTimer through JNA, I had,
as the third parameter, "0L" which is a Java long (64 bits).
Well, that was _supposed_ to be a Windows
LONG, which is shorter. So apparently the last parameter
(the fResume) that I wanted to have set to "TRUE" got
pushed off to the right too far and I actually was putting
null into fResume, so, no wakeup.

Sorry for this "Java intrusion" in your forum.

--Dale--

0 new messages