Browse Source

Simplify GC idle notification

In particular, don't leave the timeout running when the heap is fully
compacted.
v0.7.4-release
Ryan Dahl 15 years ago
parent
commit
ac3bc2ed41
  1. 2
      benchmark/http_simple.js
  2. 48
      src/node.cc

2
benchmark/http_simple.js

@ -4,6 +4,8 @@ var puts = require("sys").puts;
var old = (process.argv[2] == 'old'); var old = (process.argv[2] == 'old');
puts('pid ' + process.pid);
http = require(old ? "http_old" : 'http'); http = require(old ? "http_old" : 'http');
if (old) puts('old version'); if (old) puts('old version');

48
src/node.cc

@ -102,8 +102,21 @@ static ev_tstamp last_active;
static ev_timer gc_timer; static ev_timer gc_timer;
static ev_check gc_check; static ev_check gc_check;
static ev_idle gc_idle; static ev_idle gc_idle;
static bool needs_gc; #define GC_INTERVAL 1.0
#define GC_INTERVAL 2.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) { 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; ev_tstamp idle_time = ev_now(EV_DEFAULT_UC) - last_active;
if (idle_time > GC_INTERVAL) { if (idle_time > GC_INTERVAL) {
if (needs_gc) {
needs_gc = false;
if (!V8::IdleNotification()) { if (!V8::IdleNotification()) {
ev_idle_start(EV_DEFAULT_UC_ &gc_idle); ev_idle_start(EV_DEFAULT_UC_ &gc_idle);
} }
} gc_timer_stop();
// reset the timer
gc_timer.repeat = GC_INTERVAL;
ev_timer_again(EV_DEFAULT_UC_ watcher);
} }
} }
@ -136,8 +144,8 @@ static void NotifyIdleness(EV_P_ ev_idle *watcher, int revents) {
if (V8::IdleNotification()) { if (V8::IdleNotification()) {
ev_idle_stop(EV_A_ watcher); 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. // Don't count GC watchers as activity.
pending -= ev_is_pending(&gc_timer); if (ev_is_pending(&gc_timer)) pending--;
pending -= ev_is_pending(&gc_idle); if (ev_is_pending(&gc_idle)) pending--;
pending -= ev_is_pending(&next_tick_watcher); if (ev_is_pending(&gc_check)) pending--;
//if (ev_is_pending(&gc_check)) pending--; // This probably never happens?
assert(pending >= 0);
//fprintf(stderr, "activity, pending: %d\n", pending); //fprintf(stderr, "activity, pending: %d\n", pending);
if (pending) { if (pending) {
last_active = ev_now(EV_DEFAULT_UC); last_active = ev_now(EV_DEFAULT_UC);
ev_idle_stop(EV_DEFAULT_UC_ &gc_idle); ev_idle_stop(EV_DEFAULT_UC_ &gc_idle);
gc_timer_start();
if (!needs_gc) {
gc_timer.repeat = GC_INTERVAL;
ev_timer_again(EV_DEFAULT_UC_ &gc_timer);
}
needs_gc = true;
} }
} }
@ -1594,10 +1597,7 @@ int main(int argc, char *argv[]) {
ev_idle_init(&node::tick_spinner, node::Spin); ev_idle_init(&node::tick_spinner, node::Spin);
ev_init(&node::gc_timer, node::CheckIdleness); ev_timer_init(&node::gc_timer, node::CheckIdleness, 2*GC_INTERVAL, 2*GC_INTERVAL);
node::gc_timer.repeat = GC_INTERVAL;
ev_timer_again(EV_DEFAULT_UC_ &node::gc_timer);
ev_unref(EV_DEFAULT_UC);
ev_check_init(&node::gc_check, node::Activity); ev_check_init(&node::gc_check, node::Activity);
ev_check_start(EV_DEFAULT_UC_ &node::gc_check); ev_check_start(EV_DEFAULT_UC_ &node::gc_check);

Loading…
Cancel
Save