template <typename T>

class TimerSyncVar

Defined at line 159 of file ../../zircon/kernel/include/kernel/timer.h

TimerSyncVar is a small helper class used to help us follow some of the

trickier rules when it comes to synchronization and timer operations. Most

of timer and timer queue state is protected by the global TimerLock, which

guarantees ordering. There are some examples which are a bit more

complicated. Consider the cancel operation.

When a timer needs to fire, the global lock is held and the timer's

deadline is evaluated. If the deadline has arrived, the TimerTick code

will remove the timer from the appropriate pending list, and then indicate

that there is a callback-in-flight by setting the `active_cpu_` atomic to

the current CPU value. Then it drops the lock and performs the callback.

Both dropping the lock and recording which cpu is handling the callback are

important here because the callback can choose to call into the timer's

methods during the callback. Calling "set" is a good example of something

someone might want to do from the timer callback.

Now consider another CPU attempting to cancel a timer T when there is a

callback already in flight. Cancel is supposed to return a boolean:

1) True means that the cancel succeeded. The timer was canceled before any

callback was made, and now there is a guarantee that no callback will be

made and that the timer's owner is free to destroy the Timer.

2) False means that the cancel failed. When control is returned to the

caller, the callback is guaranteed to have finished.

So, when cancel runs, it grabs the lock and checks to see if the callback

has already started. If it has, then it need to drop the lock (so the

TimerTick code can reacquire the lock and mark the callback done via

active_cpu_), _and wait for the callback to finish_. It does this by

spinning on the `active_cpu_` variable, read using atomic loads.

It is important, however, that when the callback has finished, that the

cancel CPU is guaranteed that not only is the callback done, but that all

of the side effects of the callback are visible to the cancel CPU. So, it

needs to load with acquire, and writes of the state (who always hold the

lock) need to store with release. Anyone else reading the variable from

_inside_ of the lock, however, do not need to load with acquire. The lock

is already satisfying any ordering requirements.

So: TimerSyncVar lets us control access to the two variables (cancel_ and

active_cpu_) we have which are sometimes are called upon to provide

synchronization guarantees without relying on the guarantees provided by

the lock. It enforces the following rules using the static analyzer.

1) Whenever a SyncVar is written, it is always stored with release semantics,

and also demands that we hold the lock.

2) Whenever a SyncVar is read from inside of the lock, it is loaded with

relaxed semantics. The fact that #1 happened with the lock held

provides our synchronization guarantees.

3) Whenever a SyncVar is read from outside of the lock, it is read using

acquire semantics, which should syncronize-with the release-store

performed in #1.

Wrapping this all up in a class provides a good place for annotations, in

addition to guaranteeing that no one can make a mistake by directly

accessing the actual atomic with the wrong semantics.

Public Methods

void TimerSyncVar<T> (T val)

No default constructor. Explicitly initialize your PODs folks!

Defined at line 162 of file ../../zircon/kernel/include/kernel/timer.h

void TimerSyncVar<T> (const TimerSyncVar<T> & )

No copy, no move.

Defined at line 165 of file ../../zircon/kernel/include/kernel/timer.h

void TimerSyncVar<T> (TimerSyncVar<T> && )

Defined at line 166 of file ../../zircon/kernel/include/kernel/timer.h

TimerSyncVar<T> & operator= (const TimerSyncVar<T> & )

Defined at line 167 of file ../../zircon/kernel/include/kernel/timer.h

TimerSyncVar<T> & operator= (TimerSyncVar<T> && )

Defined at line 168 of file ../../zircon/kernel/include/kernel/timer.h

T load_locked ()

Defined at line 170 of file ../../zircon/kernel/include/kernel/timer.h

T load_unlocked ()

Defined at line 171 of file ../../zircon/kernel/include/kernel/timer.h

void store_locked (T val)

Defined at line 172 of file ../../zircon/kernel/include/kernel/timer.h