src: use monotonic time for process.uptime()
`process.uptime()` interface will return the amount of time the current process has been running. To achieve this it was caching the `uv_uptime` value at program start, and then on the call to `process.uptime()` returning the delta between the two values. `uv_uptime` is defined as the number of seconds the operating system has been up since last boot. On sunos this interface uses `kstat`s which can be a significantly expensive operation as it requires exclusive access, but because of the design of `process.uptime()` node *had* to always call this on start. As a result if you had many node processes all starting at the same time you would suffer lock contention as they all tried to read kstats. Instead of using `uv_uptime` to achieve this, the libuv loop already has a concept of current loop time in the form of `uv_now()` which is in fact monotonically increasing, and already stored directly on the loop. By using this value at start every platform performs at least one fewer syscall during initialization. Since the interface to `uv_uptime` is defined as seconds, in the call to `process.uptime()` we now `uv_update_time` get our delta, divide by 1000 to get seconds, and then convert to an `Integer`. In 0.12 we can move back to `Number::New` instead and not lose precision. Caveat: For some platforms `uv_uptime` reports time monotonically increasing regardless of system hibernation, `uv_now` interface is also monotonically increasing but may not reflect time spent in hibernation.
This commit is contained in:
parent
af69f88a9d
commit
632c135622
11
src/node.cc
11
src/node.cc
@ -1714,13 +1714,10 @@ static Handle<Value> Uptime(const Arguments& args) {
|
||||
HandleScope scope;
|
||||
double uptime;
|
||||
|
||||
uv_err_t err = uv_uptime(&uptime);
|
||||
uv_update_time(uv_default_loop());
|
||||
uptime = uv_now(uv_default_loop()) - prog_start_time;
|
||||
|
||||
if (err.code != UV_OK) {
|
||||
return Undefined();
|
||||
}
|
||||
|
||||
return scope.Close(Number::New(uptime - prog_start_time));
|
||||
return scope.Close(Integer::New(uptime / 1000));
|
||||
}
|
||||
|
||||
|
||||
@ -2893,7 +2890,7 @@ static Handle<Value> DebugEnd(const Arguments& args) {
|
||||
|
||||
char** Init(int argc, char *argv[]) {
|
||||
// Initialize prog_start_time to get relative uptime.
|
||||
uv_uptime(&prog_start_time);
|
||||
prog_start_time = uv_now(uv_default_loop());
|
||||
|
||||
// Make inherited handles noninheritable.
|
||||
uv_disable_stdio_inheritance();
|
||||
|
Loading…
x
Reference in New Issue
Block a user