From 2a0497e2c15d2440f7c222bbec2c580a4cd31081 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 18 Nov 2009 13:00:35 +0000 Subject: [PATCH] From Pau Garcia i Quiles, "On Linux/Unix, when you change the system time (for instance, using settimeofday), OSG animations will freeze your application because osg::Timer uses gettimeofday internally on non-Win32 platforms. This is wrong and should be replace with times(2) or clock_gettime(2). The attached patch fixes the issue in a binary-compatible way by using clock_gettime when it's available, and falling back to gettimeofday when it's not." --- CMakeLists.txt | 3 +++ src/osg/CMakeLists.txt | 4 ++-- src/osg/Timer.cpp | 28 ++++++++++++++++++++-------- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 083edc0b6..e502aa0a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,9 @@ IF(UNIX) FIND_PACKAGE(X11) # Some Unicies need explicit linkage to the Math library or the build fails. FIND_LIBRARY(MATH_LIBRARY m) + IF( CMAKE_SYSTEM MATCHES "Linux" ) + FIND_LIBRARY( RT_LIBRARY rt ) + ENDIF( CMAKE_SYSTEM MATCHES "Linux" ) ENDIF() # Make the headers visible to everything diff --git a/src/osg/CMakeLists.txt b/src/osg/CMakeLists.txt index 02dde57f4..a8b4cbe95 100644 --- a/src/osg/CMakeLists.txt +++ b/src/osg/CMakeLists.txt @@ -331,7 +331,7 @@ ADD_LIBRARY(${LIB_NAME} LINK_INTERNAL(${LIB_NAME} OpenThreads ) -LINK_EXTERNAL(${LIB_NAME} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIBRARY} ) -LINK_CORELIB_DEFAULT(${LIB_NAME} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIBRARY} ) +LINK_EXTERNAL(${LIB_NAME} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIBRARY} ${RT_LIBRARY} ) +LINK_CORELIB_DEFAULT(${LIB_NAME} ${CMAKE_THREAD_LIBS_INIT} ${MATH_LIBRARY} ${RT_LIBRARY} ) INCLUDE(ModuleInstall OPTIONAL) diff --git a/src/osg/Timer.cpp b/src/osg/Timer.cpp index 3a5c450c0..835b69561 100644 --- a/src/osg/Timer.cpp +++ b/src/osg/Timer.cpp @@ -71,8 +71,7 @@ Timer* Timer::instance() } #else - - #include + #include Timer::Timer( void ) { @@ -81,11 +80,24 @@ Timer* Timer::instance() setStartTick(); } - Timer_t Timer::tick() const - { - struct timeval tv; - gettimeofday(&tv, NULL); - return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec; - } + #if defined(_POSIX_TIMERS) && ( _POSIX_TIMERS > 0 ) && defined(_POSIX_MONOTONIC_CLOCK) + #include + + Timer_t Timer::tick() const + { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ((osg::Timer_t)ts.tv_sec)*1000000+(osg::Timer_t)ts.tv_nsec/1000; + } + #else + #include + + Timer_t Timer::tick() const + { + struct timeval tv; + gettimeofday(&tv, NULL); + return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec; + } + #endif #endif