class SuspendWakeupTimer

Defined at line 102 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

# SuspendWakeupTimer

## Summary

A class which helps to abstract the specific timer HW used to wake the system

from a suspended state. Currently meant to be used only by the

IdlePowerThread.

## Creation

Users of the SuspendWakeupTimer start by creating a timer instance using the

static Create factory function. During creation, a Callback instance

must be passed.

The Callback is a fit::inline_function with enough storage for exactly one

pointer, allowing it to easily target either a static or instanced method of

a class. It takes two parameters, now and resume_at, both timestamps on

the boot timeline which inform the callback owner of when the interrupt

fired, as well as what the originally requested resume time was.

The lifecycle of the SuspendWakeupTimer is controlled by a unique_ptr

returned from the Create function. Create must not be called earlier

than LK_INIT_LEVEL_PLATFORM to allow platform specific wakeup timer

hardware to be detected and initialized. Callbacks will always take place on

the BOOT_CPU and with interrupts off.

## Usage

Usage of the SuspendWakeupTimer involves three methods called in accordance

with a protocol which must be followed to ensure correct behavior. The

methods are:

+ SetResumeDeadline

+ CancelTimer

+ EnsureStarted

At the start of a suspend operation, if the operation has a resume deadline,

SetResumeDeadline must be called to configure the desired deadline before

instructing the BOOT_CPU's IdlePowerThread to transition to the suspended

state. Once a resume deadline has been configured, it is illegal to call

SetResumeDeadline again without first explicitly canceling the timer via

CancelTimer.

After the resume deadline has been configured, and as the suspend coordinator

thread unwinds from the suspend operation for any reason (resume timer fired,

some other wake source fired, failure to enter suspend due to an unrelated

error), CancelTimer *must* be called in order to reset the timer, and

guarantee that there are no timer callbacks in flight. CancelTimer is

idempotent. Unlike SetResumeDeadline, it may be called any number of times

in a row. Once CancelTimer has been called, it is guaranteed that there are

no longer any callbacks in flight, however it does *not* guarantee that the

user won the race to cancel a timer which had been set up, but may not have

fired yet.

Finally, in the BOOT_CPU's IdlePowerThread itself, when the system is

supposed to be in the suspend state, it *must* call EnsureStarted to make

certain that the hardware is properly set up to deliver an interrupt which

will wake the system at an appropriate time. This call *must* be made from

the BOOT_CPU and interrupts *must* be disabled when this happens. Similar to

CancelTimer, EnsureStarted is idempotent and may multiple times without a

problem. If there is a configured deadline and the timer is not yet started,

it will be.

So, the summary of the usage protocol is as follows.

1) At the start of a suspend operation call SetResumeDeadline to configure

the time to wake up and resume the system.

2) In the BOOT_CPU's IdlePowerThread itself, just before entering a suspended

state and with interrupts still disabled, call EnsureStarted to make sure

that the timer is running if it needs to be.

3) After control is returned to the coordinator thread, always call

CancelTimer as we unwind.

## Restrictions

SuspendWakeupTimer callbacks will take place at hard IRQ time. Operations

which may need to block (such as holding a Mutex) are not allowed. That

said, no spinlocks are held during the callback itself. It is safe for the

callback to call methods on the SuspendWakeupTimer instance itself, however

it is anticipated that there is little to no reason to do so. Keep in mind,

however, that it is illegal to call SetResumeDeadline a second time without

having canceled the timer first. If a callback _wanted_ to re-program its

deadline during the operation itself, `CancelTimer` must still be called

first to ensure that the timer is ready to be set up again.

Protected Members

LockDep lock_
bool started_
RelaxedAtomic resume_at_
function_impl callback_

Public Methods

ktl::unique_ptr<SuspendWakeupTimer> Create (Callback callback)

Defined at line 90 of file ../../zircon/kernel/lib/suspend_wakeup_timer/suspend_wakeup_timer.cc

void EnsureStarted ()

Called by the BOOT_CPU's IdlePowerThread every time it is just about to

enter a suspended state to ensure that its SuspendWakeupTimer is started

and will wake it up at the appropriate time.

void CancelTimer ()

Called to cancel any pending timer and its callback. Must be called at

least once after every call to SetResumeDeadline before a second call to

SetResumeDeadline may be made. After returning from CancelTimer, the user

is guaranteed that there the registered callback is no longer in flight.

It has either completed, or was successfully canceled.

void ~SuspendWakeupTimer ()

Defined at line 106 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

void SetResumeDeadline (zx_instant_boot_t resume_at)

Sets the time at which the SuspendWakeupTimer should call the user's

callback in order to wake the system from suspend. Note that once this has

been called and the timer has an assigned deadline, it is illegal to call

this method again without first calling CancelTimer.

Defined at line 114 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

Protected Methods

void SuspendWakeupTimer (Callback callback)

Defined at line 134 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

void SuspendWakeupTimer (const SuspendWakeupTimer & )

Defined at line 136 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

SuspendWakeupTimer & operator= (const SuspendWakeupTimer & )

Defined at line 137 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

void SuspendWakeupTimer (SuspendWakeupTimer && )

Defined at line 138 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

SuspendWakeupTimer & operator= (SuspendWakeupTimer && )

Defined at line 139 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

void ResetLocked ()

Defined at line 141 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h

void DoCallback (zx_instant_boot_t now)

Defined at line 146 of file ../../zircon/kernel/lib/suspend_wakeup_timer/include/lib/suspend_wakeup_timer.h