From 645c412ac466f8b26bd62aab1e26cd5e2fb82ea3 Mon Sep 17 00:00:00 2001 From: alexpeshkoff Date: Tue, 27 Mar 2012 13:16:44 +0000 Subject: [PATCH] Fixed CORE-3770: fbtracemgr loads CPU up to ~55% when no activity is present --- configure.in | 1 + src/common/classes/semaphore.cpp | 55 ++++++++++++++++++++++++++------ 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/configure.in b/configure.in index 1e576de40d..c8e6b14190 100644 --- a/configure.in +++ b/configure.in @@ -642,6 +642,7 @@ AC_CHECK_HEADERS(sys/stat.h) AC_CHECK_HEADERS(sys/uio.h) AC_HEADER_SYS_WAIT AC_HEADER_TIME +AC_CHECK_HEADERS(sys/time.h) AC_CHECK_HEADERS(sys/timeb.h) AC_CHECK_HEADERS(sys/param.h) AC_CHECK_HEADERS(sys/mount.h) diff --git a/src/common/classes/semaphore.cpp b/src/common/classes/semaphore.cpp index 92110f9f7e..0190220bca 100644 --- a/src/common/classes/semaphore.cpp +++ b/src/common/classes/semaphore.cpp @@ -29,6 +29,41 @@ #include "../common/classes/alloc.h" #include "gen/iberror.h" +#ifdef HAVE_SYS_TIMES_H +#include +#endif +#ifdef HAVE_SYS_TIMEB_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#if defined(COMMON_CLASSES_SEMAPHORE_POSIX_RT) || defined(COMMON_CLASSES_SEMAPHORE_COND_VAR) + +static timespec getCurrentTime() +{ + timespec rc; + +#ifdef HAVE_GETTIMEOFDAY + struct timeval tp; + GETTIMEOFDAY(&tp); + rc.tv_sec = tp.tv_sec; + rc.tv_nsec = tp.tv_usec * 1000; +#else + struct timeb time_buffer; + ftime(&time_buffer); + rc.tv_sec = time_buffer.time; + rc.tv_nsec = time_buffer.millitm * 1000000; +#endif + + return rc; +} + +#endif // semaphore kind defined + + + namespace Firebird { #ifdef COMMON_CLASSES_SEMAPHORE_MACH @@ -101,9 +136,9 @@ static const char* semName = "/firebird_temp_sem"; #ifdef HAVE_SEM_TIMEDWAIT bool SignalSafeSemaphore::tryEnter(const int seconds, int milliseconds) { - milliseconds += seconds * 1000; + long nanoseconds = long(milliseconds + seconds * 1000) * 1000000l; // Return true in case of success - if (milliseconds == 0) + if (nanoseconds == 0) { // Instant try do { @@ -114,7 +149,7 @@ static const char* semName = "/firebird_temp_sem"; return false; system_call_failed::raise("sem_trywait"); } - if (milliseconds < 0) + if (nanoseconds < 0) { // Unlimited wait, like enter() do { @@ -124,9 +159,10 @@ static const char* semName = "/firebird_temp_sem"; system_call_failed::raise("sem_wait"); } // Wait with timeout - struct timespec timeout; - timeout.tv_sec = time(NULL) + milliseconds / 1000; - timeout.tv_nsec = (milliseconds % 1000) * 1000000; + timespec timeout = getCurrentTime(); + nanoseconds += timeout.tv_nsec; + timeout.tv_sec += nanoseconds / 1000000000l; + timeout.tv_nsec = nanoseconds % 1000000000l; int errcode = 0; do { int rc = sem_timedwait(sem, &timeout); @@ -243,9 +279,10 @@ static const char* semName = "/firebird_temp_sem"; return true; } - timespec timeout; - timeout.tv_sec = time(NULL) + milliseconds / 1000; - timeout.tv_nsec = (milliseconds % 1000) * 1000000; + timespec timeout = getCurrentTime(); + nanoseconds += timeout.tv_nsec; + timeout.tv_sec += nanoseconds / 1000000000l; + timeout.tv_nsec = nanoseconds % 1000000000l; err = pthread_cond_timedwait(&cv, &mu, &timeout); mtxUnlock();