Simplify GC idle notification
authorRyan Dahl <ry@tinyclouds.org>
Thu, 15 Apr 2010 08:29:39 +0000 (01:29 -0700)
committerRyan Dahl <ry@tinyclouds.org>
Thu, 15 Apr 2010 08:30:58 +0000 (01:30 -0700)
In particular, don't leave the timeout running when the heap is fully
compacted.

benchmark/http_simple.js
src/node.cc

index e1eb6b5..e709f2d 100644 (file)
@@ -4,6 +4,8 @@ var puts = require("sys").puts;
 
 var old = (process.argv[2] == 'old');
 
+puts('pid ' + process.pid);
+
 http = require(old ? "http_old" : 'http');
 if (old) puts('old version');
 
index 76027da..cabd92a 100644 (file)
@@ -102,8 +102,21 @@ static ev_tstamp last_active;
 static ev_timer  gc_timer;
 static ev_check gc_check;
 static ev_idle  gc_idle;
-static bool needs_gc;
-#define GC_INTERVAL 2.0
+#define GC_INTERVAL 1.0
+
+static void gc_timer_start () {
+  if (!ev_is_active(&gc_timer)) {
+    ev_timer_start(EV_DEFAULT_UC_ &gc_timer);
+    ev_unref(EV_DEFAULT_UC);
+  }
+}
+
+static void gc_timer_stop () {
+  if (ev_is_active(&gc_timer)) {
+    ev_ref(EV_DEFAULT_UC);
+    ev_timer_stop(EV_DEFAULT_UC_ &gc_timer);
+  }
+}
 
 
 static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
@@ -115,15 +128,10 @@ static void CheckIdleness(EV_P_ ev_timer *watcher, int revents) {
   ev_tstamp idle_time = ev_now(EV_DEFAULT_UC) - last_active;
 
   if (idle_time > GC_INTERVAL) {
-    if (needs_gc) {
-      needs_gc = false;
-      if (!V8::IdleNotification()) {
-        ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
-      }
+    if (!V8::IdleNotification()) {
+      ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
     }
-    // reset the timer
-    gc_timer.repeat = GC_INTERVAL;
-    ev_timer_again(EV_DEFAULT_UC_ watcher);
+    gc_timer_stop();
   }
 }
 
@@ -136,8 +144,8 @@ static void NotifyIdleness(EV_P_ ev_idle *watcher, int revents) {
 
   if (V8::IdleNotification()) {
     ev_idle_stop(EV_A_ watcher);
+    gc_timer_stop();
   }
-  needs_gc = false;
 }
 
 
@@ -149,23 +157,18 @@ static void Activity(EV_P_ ev_check *watcher, int revents) {
 
   // Don't count GC watchers as activity.
 
-  pending -= ev_is_pending(&gc_timer);
-  pending -= ev_is_pending(&gc_idle);
-  pending -= ev_is_pending(&next_tick_watcher);
-  //if (ev_is_pending(&gc_check)) pending--; // This probably never happens?
+  if (ev_is_pending(&gc_timer)) pending--;
+  if (ev_is_pending(&gc_idle)) pending--;
+  if (ev_is_pending(&gc_check)) pending--;
+
+  assert(pending >= 0);
 
   //fprintf(stderr, "activity, pending: %d\n", pending);
 
   if (pending) {
     last_active = ev_now(EV_DEFAULT_UC);
     ev_idle_stop(EV_DEFAULT_UC_ &gc_idle);
-
-    if (!needs_gc) {
-      gc_timer.repeat = GC_INTERVAL;
-      ev_timer_again(EV_DEFAULT_UC_ &gc_timer);
-    }
-
-    needs_gc = true;
+    gc_timer_start();
   }
 }
 
@@ -1594,10 +1597,7 @@ int main(int argc, char *argv[]) {
 
   ev_idle_init(&node::tick_spinner, node::Spin);
 
-  ev_init(&node::gc_timer, node::CheckIdleness);
-  node::gc_timer.repeat = GC_INTERVAL;
-  ev_timer_again(EV_DEFAULT_UC_ &node::gc_timer);
-  ev_unref(EV_DEFAULT_UC);
+  ev_timer_init(&node::gc_timer, node::CheckIdleness, 2*GC_INTERVAL, 2*GC_INTERVAL);
 
   ev_check_init(&node::gc_check, node::Activity);
   ev_check_start(EV_DEFAULT_UC_ &node::gc_check);