Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(714)

Unified Diff: sdk/lib/io/timer_impl.dart

Issue 858973002: - Reduce the amount of messages being sent for Timer.run(). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/timer_impl.dart
===================================================================
--- sdk/lib/io/timer_impl.dart (revision 42999)
+++ sdk/lib/io/timer_impl.dart (working copy)
@@ -132,6 +132,10 @@
static RawReceivePort _receivePort;
static SendPort _sendPort;
static int _scheduledWakeupTime;
+ // Keep track whether at least one message is pending in the event loop. This
+ // way we do not have to notify for every pending _firstZeroTimer.
+ static var _messagePending = false;
+
static bool _handlingCallbacks = false;
Function _callback; // Closure to call when timer fires. null if canceled.
@@ -255,7 +259,7 @@
return;
}
- if (_firstZeroTimer == null && _heap.isEmpty) {
+ if ((_firstZeroTimer == null) && _heap.isEmpty) {
// No pending timers: Close the receive port and let the event handler
// know.
if (_receivePort != null) {
@@ -269,7 +273,10 @@
_createTimerHandler();
}
if (_firstZeroTimer != null) {
- _sendPort.send(null);
+ if (!_messagePending) {
+ _sendPort.send(null);
+ _messagePending = true; // Reset when the port receives a message.
+ }
} else {
var wakeupTime = _heap.first._wakeupTime;
if ((_scheduledWakeupTime == null) ||
@@ -282,56 +289,71 @@
}
static void _handleTimeout(pendingImmediateCallback) {
- int currentTime = new DateTime.now().millisecondsSinceEpoch;
+ // Fast exit if no timers have been scheduled.
+ if (_heap.isEmpty && (_firstZeroTimer == null)) {
Søren Gjesse 2015/01/20 15:36:27 maybe assert(_receivePort == null)
Ivan Posva 2015/01/20 16:01:17 Done.
+ return;
+ }
+
// Collect all pending timers.
var head = null;
var tail = null;
- // Keep track of the lowest wakeup times for both the list and heap. If
- // the respective queue is empty move its time beyond the current time.
- var heapTime = _heap.isEmpty ?
- (currentTime + 1) : _heap.first._wakeupTime;
- var listTime = (_firstZeroTimer == null) ?
- (currentTime + 1) : _firstZeroTimer._wakeupTime;
+ if (_heap.isEmpty) {
+ // Only immediate timers are scheduled. Take over the whole list as is.
+ assert(_firstZeroTimer != null);
+ assert(_lastZeroTimer != null);
+ head = _firstZeroTimer;
+ tail = _lastZeroTimer;
+ _firstZeroTimer = null;
+ _lastZeroTimer = null;
+ } else {
+ assert(!_heap.isEmpty);
zra 2015/01/20 15:23:34 Why is this assert needed?
Ivan Posva 2015/01/20 16:01:17 It is more of a documentation and making sure the
+ // Keep track of the lowest wakeup times for both the list and heap. If
+ // the respective queue is empty move its time beyond the current time.
+ var currentTime = new DateTime.now().millisecondsSinceEpoch;
+ var heapTime = _heap.first._wakeupTime;
+ var listTime = (_firstZeroTimer == null) ?
+ (currentTime + 1) : _firstZeroTimer._wakeupTime;
zra 2015/01/20 15:23:34 Indentation
Ivan Posva 2015/01/20 16:01:17 Done.
- while ((heapTime <= currentTime) || (listTime <= currentTime)) {
- var timer;
- // Consume the timers in order by removing from heap or list based on
- // their wakeup time and update the queue's time.
- assert((heapTime != listTime) ||
- ((_heap.first != null) && (_firstZeroTimer != null)));
- if ((heapTime < listTime) ||
- ((heapTime == listTime) &&
- (_heap.first._id < _firstZeroTimer._id))) {
- timer = _heap.removeFirst();
- heapTime = _heap.isEmpty ? (currentTime + 1) : _heap.first._wakeupTime;
- } else {
- timer = _firstZeroTimer;
- assert(timer._milliSeconds == 0);
- _firstZeroTimer = timer._indexOrNext;
- if (_firstZeroTimer == null) {
- _lastZeroTimer = null;
- listTime = currentTime + 1;
+ while ((heapTime <= currentTime) || (listTime <= currentTime)) {
+ var timer;
+ // Consume the timers in order by removing from heap or list based on
+ // their wakeup time and update the queue's time.
+ assert((heapTime != listTime) ||
+ ((_heap.first != null) && (_firstZeroTimer != null)));
+ if ((heapTime < listTime) ||
+ ((heapTime == listTime) &&
+ (_heap.first._id < _firstZeroTimer._id))) {
+ timer = _heap.removeFirst();
+ heapTime = _heap.isEmpty ? (currentTime + 1) : _heap.first._wakeupTime;
zra 2015/01/20 15:23:34 Long line
Ivan Posva 2015/01/20 16:01:17 Done.
} else {
- // We want to drain all entries from the list as they should have
- // been pending for 0 ms. To prevent issues with current time moving
- // we ensure that the listTime does not go beyond current, unless the
- // list is empty.
- listTime = _firstZeroTimer._wakeupTime;
- if (listTime > currentTime) {
- listTime = currentTime;
+ timer = _firstZeroTimer;
+ assert(timer._milliSeconds == 0);
+ _firstZeroTimer = timer._indexOrNext;
+ if (_firstZeroTimer == null) {
+ _lastZeroTimer = null;
+ listTime = currentTime + 1;
+ } else {
+ // We want to drain all entries from the list as they should have
+ // been pending for 0 ms. To prevent issues with current time moving
+ // we ensure that the listTime does not go beyond current, unless
+ // the list is empty.
+ listTime = _firstZeroTimer._wakeupTime;
+ if (listTime > currentTime) {
+ listTime = currentTime;
+ }
}
}
- }
- // Append this timer to the pending timer list.
- timer._indexOrNext = null;
- if (head == null) {
- assert(tail == null);
- head = timer;
- tail = timer;
- } else {
- tail._indexOrNext = timer;
- tail = timer;
+ // Append this timer to the pending timer list.
+ timer._indexOrNext = null;
+ if (head == null) {
+ assert(tail == null);
+ head = timer;
+ tail = timer;
+ } else {
+ tail._indexOrNext = timer;
+ tail = timer;
+ }
}
}
@@ -385,13 +407,16 @@
// Creates a receive port and registers an empty handler on that port. Just
// the triggering of the event loop will ensure that timers are executed.
- static _ignoreMessage(_) => null;
+ static _ignoreMessage(_) {
+ _messagePending = false;
+ }
static void _createTimerHandler() {
assert(_receivePort == null);
_receivePort = new RawReceivePort(_ignoreMessage);
_sendPort = _receivePort.sendPort;
_scheduledWakeupTime = null;
+ _messagePending = false;
}
static void _shutdownTimerHandler() {
@@ -399,6 +424,7 @@
_receivePort = null;
_sendPort = null;
_scheduledWakeupTime = null;
+ _messagePending = false;
}
// The Timer factory registered with the dart:async library by the embedder.
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698