Skip to content

Instantly share code, notes, and snippets.

@zoka
Created March 28, 2010 09:16
Show Gist options
  • Save zoka/346669 to your computer and use it in GitHub Desktop.
Save zoka/346669 to your computer and use it in GitHub Desktop.
diff --git a/src/node.cc b/src/node.cc
index 452c111..32911e2 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1062,6 +1062,53 @@ static Handle<Value> CheckBreak(const Arguments& args) {
return Undefined();
}
+ // monotonic time stamp recorded when Node app was started
+static double startup_time;
+
+#ifdef __APPLE__
+
+#include <mach/mach_time.h>
+
+static double monotonic_msec() {
+ static mach_timebase_info_data_t clock_gettime_inf;
+ uint64_t now, nano;
+
+ now = mach_absolute_time();
+
+ if (0 == clock_gettime_inf.denom)
+ mach_timebase_info(&clock_gettime_inf);
+
+ nano = now * clock_gettime_inf.numer / clock_gettime_inf.denom;
+ return (double) nano * 1e-6;
+}
+
+#else
+
+static double monotonic_msec() {
+ timespec ts;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+ return (double) ts.tv_sec * 1e3 + (double) ts.tv_nsec * 1e-6;
+}
+
+#endif
+
+// Return time since node app startup in milliseconds using
+// double precision floating point format.
+// Note that accuracy of this function gradually falls by
+// n bits od mantissa for every (2**(n-1))*104 days since operating
+// system was restarted (104 days ~ 2**53 nanoseconds)
+static Handle<Value> Uptime(const Arguments& args) {
+ HandleScope scope;
+
+ Local <Number> ret = Number::New(monotonic_msec() - startup_time);
+ return scope.Close(ret);
+}
+
+void startup_time_init() {
+ startup_time=monotonic_msec();
+}
+
Persistent<Object> binding_cache;
static Handle<Value> Binding(const Arguments& args) {
@@ -1295,6 +1342,7 @@ static void Load(int argc, char *argv[]) {
NODE_SET_METHOD(process, "kill", Kill);
NODE_SET_METHOD(process, "memoryUsage", MemoryUsage);
NODE_SET_METHOD(process, "checkBreak", CheckBreak);
+ NODE_SET_METHOD(process, "uptime", Uptime);
NODE_SET_METHOD(process, "binding", Binding);
@@ -1447,6 +1495,8 @@ int main(int argc, char *argv[]) {
return 1;
}
+ node::startup_time_init();
+
// Ignore the SIGPIPE
evcom_ignore_sigpipe();
// uptime_test.js
var sys=require('sys');
sys.puts("Node init time: "+ process.uptime()+ " msec");
var i;
var n = 10000; // samples to take
var m = 1000; // default cut off value 1000 nsec
var maxRejected=0;
var minRejected=Number.MAX_VALUE;
if (process.argv.length > 2) {
if (process.argv[2] === "-h") {
sys.puts(
"Usage: node uptime_test [[<samples>] <cutoff>]\n"+
" <samples>..Number of samples to take - default 10000\n"+
" <cutoff> ..Use only samples below <cuttoff> nsec, default is 1000");
}
n = process.argv[2];
}
if (process.argv.length > 3)
m = process.argv[3];
var unique_deltas = 0;
var deltas = new Array(m);
deltas.length = m;
for (i = 0; i < m; i++)
deltas[i] = 0;
var samples=n;
sys.puts(
"Testing consecutive process.uptime() invocations delta times\n"+
"Number of samples: "+n +"\n" +
"Cut off value: "+m + " nanoseconds")
for (i = 0; i < n; i++) {
var f,d;
f = process.uptime();
// nothing external is supposed to get in between 2 uptime calls
s = process.uptime();
d = Math.round((s-f)*1e6); // delta in integer nanoseconds
if (d >= m) {
samples--;
if (d > maxRejected)
maxRejected=d;
if (d < minRejected)
minRejected = d;
//sys.puts ( "sample is too large: "+ d + " nsec sample no "+ i);
}
else {
deltas[d]++;
}
}
var mean= 0;
var variance = 0;
for (i = 0; i < m; i++) {
if (deltas[i] > 0) {
mean += deltas[i]*i;
unique_deltas++;
//sys.puts(i+" nsec "+deltas[i] + " times");
}
}
mean = mean/samples;
for (i = 0; i < m; i++) {
if (deltas[i] > 0) {
variance += (mean - i)*(mean - i) * deltas[i];
}
}
variance = variance/samples;
sys.puts("Valid samples: "+ samples+ " Rejected: "+ (n -samples));
if (maxRejected > 0) {
sys.puts("Largest rejected sample: "+ maxRejected+ " nsec");
sys.puts("Smallest rejected sample: "+ minRejected+ " nsec");
}
sys.puts("Unique samples: "+ unique_deltas);
sys.puts("Mean delta: "+ mean);
sys.puts("Variance: "+ variance + " Std deviation: "+ Math.sqrt(variance));
function test_timer_accuracy(expected) {
var v8_ms = Date.now();
var uptime_ms = process.uptime();
function interval_cb() {
var v8_ms_now = Date.now();
var uptime_ms_now = process.uptime();
var uptime_delta = Math.round (uptime_ms_now - uptime_ms);
var v8_delta = v8_ms_now-v8_ms;
var error = expected-v8_delta;
sys.puts("v8 delta: "+v8_delta + "msec update delta: "
+uptime_delta+" msec expected: "+ expected + " ms, v8_error: "
+error+" ms");
}
setTimeout(interval_cb, expected);
}
test_timer_accuracy(100);
test_timer_accuracy(1000);
ZokaMac:node Zoka$ ./node ../sample/uptime_test.js 1000 1000
Node init time: 21.40157002210617 msec
Testing consecutive process.uptime() invocations delta times
Number of samples: 1000
Cut off value: 1000 nanoseconds
Valid samples: 997 Rejected: 3
Largest rejected sample: 4270 nsec
Smallest rejected sample: 1170 nsec
Unique samples: 45
Mean delta: 172.84353059177533
Variance: 782.0958784075395 Std deviation: 27.965977158103016
v8 delta: 92msec update delta: 92 msec expected: 100 ms, v8_error: 8 ms
v8 delta: 992msec update delta: 992 msec expected: 1000 ms, v8_error: 8 ms
ZokaMac:node Zoka$ ./node ../sample/uptime_test.js 10000 1000
Node init time: 21.464042961597443 msec
Testing consecutive process.uptime() invocations delta times
Number of samples: 10000
Cut off value: 1000 nanoseconds
Valid samples: 9967 Rejected: 33
Largest rejected sample: 15164 nsec
Smallest rejected sample: 1191 nsec
Unique samples: 73
Mean delta: 172.67271997592053
Variance: 274.9816808027946 Std deviation: 16.582571597999948
v8 delta: 84msec update delta: 84 msec expected: 100 ms, v8_error: 16 ms
v8 delta: 984msec update delta: 984 msec expected: 1000 ms, v8_error: 16 ms
ZokaMac:node Zoka$ ./node ../sample/uptime_test.js 100000 1000
Node init time: 21.46239000558853 msec
Testing consecutive process.uptime() invocations delta times
Number of samples: 100000
Cut off value: 1000 nanoseconds
Valid samples: 99846 Rejected: 154
Largest rejected sample: 32088 nsec
Smallest rejected sample: 1191 nsec
Unique samples: 135
Mean delta: 173.45490054684214
Variance: 331.32177971238127 Std deviation: 18.20224655674077
v8 delta: 21msec update delta: 21 msec expected: 100 ms, v8_error: 79 ms
v8 delta: 921msec update delta: 921 msec expected: 1000 ms, v8_error: 79 ms
ZokaMac:node Zoka$ ./node ../sample/uptime_test.js 1000000 1000
Node init time: 21.6750990152359 msec
Testing consecutive process.uptime() invocations delta times
Number of samples: 1000000
Cut off value: 1000 nanoseconds
Valid samples: 999707 Rejected: 293
Largest rejected sample: 34690 nsec
Smallest rejected sample: 1140 nsec
Unique samples: 182
Mean delta: 172.04407191307052
Variance: 310.0622314694028 Std deviation: 17.608584027950766
v8 delta: 0msec update delta: 0 msec expected: 100 ms, v8_error: 100 ms
v8 delta: 301msec update delta: 301 msec expected: 1000 ms, v8_error: 699 ms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment