none
タイマーによるモダンスタンバイからの復帰方法 RRS feed

  • 質問

  • お世話になります。桑原と申します。

    デスクトップアプリケーションで、モダンスタンバイからタイマーで復帰する方法を探しております。従来のスリープ(S3/S4)であれば SetWaitableTimer で復帰できていたのですが、モダンスタンバイ対応のシステムでは無効なようです。

    Hardware Dev Center の "Wake sources" という資料によれば、Real-time clock(RTC) or always-on timer にて実現できるようなことが書かれているように思えるのですが、その具体的な方法については記載されていませんでした。

    どなたか方法や資料をご存知であれば、ご教授いただければと思います。


    2020年1月8日 4:54

すべての返信

  • > Hardware Dev Center の "Wake sources" という資料によれば、
    > Real-time clock(RTC) or always-on timer にて実現できる
    > ようなことが書かれているように思えるのですが、
    > その具体的な方法については記載されていませんでした。

    そこでの説明は、モダン スタンバイをサポートする "core silicon" もしくは "SoC chip" に対してであって、デスクトップ アプリに対するモノではないと思います。

    モダン スタンバイは、System Power State の S0 と S1 の間に新たに定義された "S0 low-power idle" に該当するみたいですが、Desktop App が電源管理でハンドリングする WM_POWERBROADCAST とかの Window Message は S1~S3 をスリープとみなしているはずなので、昔の実装だとそこら辺の整合性がかみ合わないのかも。
    -------------------------------------------
    System Power States
    https://docs.microsoft.com/en-us/windows/win32/power/system-power-states
    -------------------------------------------

    SetWaitableTimer API をどのタイミングで呼び出しているのかが書かれていたいのでなんとも言えませんが、Window Message をトリガに SetWaitableTimer コールを行っているのであれば、PowerRegisterSuspendResumeNotification API を利用したコールバックに書き換えることで、もしかしたらうまくいくかも。(あくまでも私の脳内妄想ですけど。)
    -------------------------------------------
    PowerRegisterSuspendResumeNotification function
    https://docs.microsoft.com/ja-jp/windows/win32/api/powerbase/nf-powerbase-powerregistersuspendresumenotification?redirectedfrom=MSDN
    -------------------------------------------
    2020年1月8日 8:45
  • > SetWaitableTimer API をどのタイミングで呼び出しているのかが書かれていたいのでなんとも言えませんが、Window Message をトリガに SetWaitableTimer コールを行っているのであれば、PowerRegisterSuspendResumeNotification API を利用したコールバックに書き換えることで、もしかしたらうまくいくかも。(あくまでも私の脳内妄想ですけど。)

    返答ありがとうございます。SetWaitableTimer の代替を探すのではなく、その呼出しのタイミング(というかトリガ)を変更してみてはということでしょうか。そちらの方向でいろいろと試してみます。結果が出ましたら、またご相談させていただくかもしれません。

    2020年1月8日 9:06
  • コードを見直してみたところ、SetWaitableTimer の呼び出しはスリープに入るタイミング等ではなく、必要なタスク実行時間が決まったら定期的に繰り返し呼び出すという実装になっていました。ですので、メッセージが飛んでこないので駄目とかではなく、やはり SetWaitableTimer では効果がないのではないかと予想されます。

    せっかくお教え頂いたのですが、どうやら違う解が必要なようです。

    2020年1月8日 10:00
  • > SetWaitableTimer の代替を探すのではなく、
    > その呼出しのタイミング(というかトリガ)を変更してみてはということでしょうか。

    そうです。
    先の返信で提示した "System Power States" のサイトでも説明されていますが、モダン スタンバイの System Power State は、S0 と S1 の間に位置します。
    即ち、モダン スタンバイの System Power State は、通常のスリープ (S1,S2,S3) よりも Power Supply が高い状態です。
    モダン スタンバイ時は通常のスリープと同様に、起動中のアプリケーションは一時停止されますが、Power State としてはモダン スタンバイの方が上位なので、Power Supply の高いモダン スタンバイでのみタイマーが正常に動かないというのは、論理的に考えておかしいと思うのです。
    (仮にそのような不具合があったなら、「"Modern Standby" Windows SetWaitableTimer」でググればヒットしそうに思いますが、私の検索能力では見つけることができませんでした。)
    上記理由より本質問の根本的な問題はモダン スタンバイではなく、SetWaitableTimer API をコールするまでのロジックにあると思い、先の返信をしたわけです。

    > コードを見直してみたところ、
    > SetWaitableTimer の呼び出しはスリープに入るタイミング等ではなく、
    > 必要なタスク実行時間が決まったら定期的に繰り返し呼び出すという実装になっていました。
    > ですので、メッセージが飛んでこないので駄目とかではなく、
    > やはり SetWaitableTimer では効果がないのではないかと予想されます。

    つまり、SetWaitableTimer API コールが行われたかどうかを、デバッガ等で実際に確認されたわけではないということですよね?
    そもそも「モダンスタンバイ対応のシステムでは無効なよう」とは、どのような検証を行いこの結論に至ったのでしょうか?
    まずはこの現象が本当に「モダンスタンバイに起因する問題」なのか、きちんと切り分ける必要があると思います。
    2020年1月9日 2:17
  • ご指導ありがとうございます。

    SetWaitableTimer API がコールされたかどうかは、ログで確認しております。

    呼び出しの結果は成功を返しているが、実際にレジュームはされなかったので「モダンスタンバイ対応のシステムでは無効」であると判断しました。

    2020年1月9日 9:59
  • > 呼び出しの結果は成功を返しているが、
    > 実際にレジュームはされなかったので
    > 「モダンスタンバイ対応のシステムでは無効」であると判断しました。

    モダン スタンバイはハードウェア依存で、すべての Windows 10 PC でこの機能が有効とは限りませんが、この現象はモダン スタンバイをサポートする PC でのみ発生しているということでしょうか?
    ("powercfg /a" コマンド等で確認済みなのでしょうか?)
    2020年1月10日 2:00
  • > この現象はモダン スタンバイをサポートする PC でのみ発生しているということでしょうか?

    はい、モダンスタンバイ対応のPCでのみ発生します。確実に対応していることも確認済みです。

    2020年1月10日 2:19
  • > はい、モダンスタンバイ対応のPCでのみ発生します。
    > 確実に対応していることも確認済みです。

    でしたら、その PC に対して WinDBG をカーネル デバッグ接続させ、かつ問題アプリの SetWaitableTimer コール周りに DebugBreak や OutputDebugString API コールを仕込んで、スリープ時における該当処理の挙動を確認されることをお勧めします。
    ------------------------------------------------
    KDNET ネットワーク カーネル デバッグの手動設定
    https://docs.microsoft.com/ja-jp/windows-hardware/drivers/debugger/setting-up-a-network-debugging-connection
    ------------------------------------------------
    2020年1月10日 2:29
  • こんにちは。フォーラムオペレーターのクモです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    SetWaitableTimer APIを言及したようですが、APIについて何かが間違っているのか分かりません。
    API を正しく使用する方法については、次のリンクを参照してください。
    Create pagesetwaitabletimer (kernel32)

    また、ハードウェアに関連している場合は、関連フォーラムで助けを求めることをお勧めします。

    どうぞよろしくお願いいたします。

    MSDN/ TechNet Community Support Kumo ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、 ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    2020年1月10日 7:01
    モデレータ