From ac3bc2ed41c18cfd45772ec895afe98a929ab78c Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Thu, 15 Apr 2010 01:29:39 -0700 Subject: [PATCH] Simplify GC idle notification In particular, don't leave the timeout running when the heap is fully compacted. --- benchmark/http_simple.js | 2 ++ src/node.cc | 52 ++++++++++++++++++++-------------------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/benchmark/http_simple.js b/benchmark/http_simple.js index e1eb6b5779..e709f2d724 100644 --- a/benchmark/http_simple.js +++ b/benchmark/http_simple.js @@ -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'); diff --git a/src/node.cc b/src/node.cc index 76027da4ab..cabd92a06a 100644 --- a/src/node.cc +++ b/src/node.cc @@ -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);