Performance/Power Timer

From MozillaWiki
Jump to: navigation, search

The problem

Consider a module that needs to poll for information. This can be FHR, add-on CPU monitoring, page memory use monitoring, etc, the profiler, the slow script or slow addon monitor, etc.

Currently, the simple solution is to either use a repeating nsITimer on the main thread or spawn a thread and have it sleep, perform its work, then loop. Both solutions wake up Firefox, which is bad for power usage.

We need a solution that works both for JavaScript and C++, and that can be used to trigger treatments both on the main thread and on custom threads.

RFC

API

 PowerTimer {
   /**
    * Initialize the timer to fire after `delay` milliseconds,
    * and send `event` on `target`.
    */
   Init(delay, bool repeating, nsIRunnable event, nsIEventTarget target);
   /**
    * Cancel the timer. It may be reinitialized later by a new call to Init(), if necessary.
    */
   Cancel();
 }

Main thread

The main thread exposes the following atomic variables: State: one of "Handling an Event" / "Not currently handling an Event" LatestActivity: TimeStamp

- Before handling an event

 1. Mark State as "Handling an Event".
 2. If the timer thread is hibernating, wake it up.

- After having handled an event

 1. Mark State as "Not current handling an Event".
 2. Update LatestActivity to now

Timer thread

The timer thread maintains: - A list of timers.

 1. Compute next sleep date
 2. If no timer is currently active
   a. Hibernate until awakened by main thread.
   b. Loop back to 1.
 3. Sleep until next date or awakened (to add/remove a timer).
 4. If awakened (to add/remove a timer)
   a. Loop back to 1.
 6. If main thread's State is "Handling an Event" or if main thread's LatestActivity is recent
   a. Fire event to target thread.
   b. Loop back to 1.
 7. Otherwise
   a. Hibernate until awakened by main thread.
   b. Loop back to 1.