From 2c185a9dfd3be8e718858b946333c433c375c295 Mon Sep 17 00:00:00 2001 From: Tom Hughes Date: Sat, 5 Mar 2011 18:11:09 -0600 Subject: [PATCH] Use higher resolution clock for uptime on Linux (if available). --- cmake/configure.cmake | 17 ++++++++++++++++- src/platform_linux.cc | 16 ++++++++++++++-- wscript | 19 ++++++++++++++++++- 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/cmake/configure.cmake b/cmake/configure.cmake index 81f721e2cf..66907b83eb 100644 --- a/cmake/configure.cmake +++ b/cmake/configure.cmake @@ -2,7 +2,8 @@ # configure node for building # include(CheckFunctionExists) - +include(CheckLibraryExists) +include(CheckSymbolExists) if(NOT "v${CMAKE_BUILD_TYPE}" MATCHES vDebug) set(CMAKE_BUILD_TYPE "Release") @@ -72,6 +73,20 @@ else() add_definitions(-DHAVE_FDATASYNC=0) endif() +# check first without rt and then with rt +check_function_exists(clock_gettime HAVE_CLOCK_GETTIME) +check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME_RT) + +if(HAVE_CLOCK_GETTIME OR HAVE_CLOCK_GETTIME_RT) + check_symbol_exists(CLOCK_MONOTONIC "time.h" HAVE_MONOTONIC_CLOCK) +endif() + +if(HAVE_MONOTONIC_CLOCK) + add_definitions(-DHAVE_MONOTONIC_CLOCK=1) +else() + add_definitions(-DHAVE_MONOTONIC_CLOCK=0) +endif() + if(DTRACE) if(NOT ${node_platform} MATCHES sunos) message(FATAL_ERROR "DTrace support only currently available on Solaris") diff --git a/src/platform_linux.cc b/src/platform_linux.cc index 2b90833918..cf9742b716 100644 --- a/src/platform_linux.cc +++ b/src/platform_linux.cc @@ -15,6 +15,10 @@ #include // free #include // strdup +#if HAVE_MONOTONIC_CLOCK +#include +#endif + namespace node { using namespace v8; @@ -240,13 +244,21 @@ double Platform::GetTotalMemory() { } double Platform::GetUptimeImpl() { +#if HAVE_MONOTONIC_CLOCK + struct timespec now; + if (0 == clock_gettime(CLOCK_MONOTONIC, &now)) { + double uptime = now.tv_sec; + uptime += (double)now.tv_nsec / 1000000000.0; + return uptime; + } + return -1; +#else struct sysinfo info; - if (sysinfo(&info) < 0) { return -1; } - return static_cast(info.uptime); +#endif } int Platform::GetLoadAvg(Local *loads) { diff --git a/wscript b/wscript index aea3fb7b9b..526195456d 100644 --- a/wscript +++ b/wscript @@ -328,7 +328,24 @@ def configure(conf): elif 'DEST_CPU' in conf.env and conf.env['DEST_CPU']: conf.env['DEST_CPU'] = canonical_cpu_type(conf.env['DEST_CPU']) - conf.check(lib='rt', uselib_store='RT') + have_librt = conf.check(lib='rt', uselib_store='RT') + + have_monotonic = False + if have_librt: + code = """ + #include + int main(void) { + struct timespec now; + clock_gettime(CLOCK_MONOTONIC, &now); + return 0; + } + """ + have_monotonic = conf.check_cc(lib="rt", msg="Checking for CLOCK_MONOTONIC", fragment=code) + + if have_monotonic: + conf.env.append_value('CPPFLAGS', '-DHAVE_MONOTONIC_CLOCK=1') + else: + conf.env.append_value('CPPFLAGS', '-DHAVE_MONOTONIC_CLOCK=0') if sys.platform.startswith("sunos"): if not conf.check(lib='socket', uselib_store="SOCKET"):