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