From f89bea4411c7949c19492c07f44980299cd02472 Mon Sep 17 00:00:00 2001 From: Guenter Obiltschnig Date: Thu, 11 Aug 2016 12:45:29 +0200 Subject: [PATCH] - prefer clock_getttime() over gettimeofday() if available - use CLOCK_MONOTONIC for POSIX condition in Poco::Event and Poco::Semaphore if supported --- Foundation/src/Event_POSIX.cpp | 41 ++++++++++++++++++++++++++++-- Foundation/src/Mutex_POSIX.cpp | 11 ++++++++ Foundation/src/Semaphore_POSIX.cpp | 40 +++++++++++++++++++++++++++-- Foundation/src/Timestamp.cpp | 2 +- 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/Foundation/src/Event_POSIX.cpp b/Foundation/src/Event_POSIX.cpp index 8dd8ce907..9c5f79f6f 100644 --- a/Foundation/src/Event_POSIX.cpp +++ b/Foundation/src/Event_POSIX.cpp @@ -19,6 +19,7 @@ #include #include #else +#include #include #endif @@ -35,10 +36,37 @@ EventImpl::EventImpl(bool autoReset): _auto(autoReset), _state(false) // if the mutex has never been used. std::memset(&_mutex, 0, sizeof(_mutex)); #endif + if (pthread_mutex_init(&_mutex, NULL)) throw SystemException("cannot create event (mutex)"); - if (pthread_cond_init(&_cond, NULL)) + +#if defined(__linux__) || defined(__QNX__) + pthread_condattr_t attr; + if (pthread_condattr_init(&attr)) + { + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create event (condition attribute)"); + } + if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) + { + pthread_condattr_destroy(&attr); + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create event (condition attribute clock)"); + } + if (pthread_cond_init(&_cond, &attr)) + { + pthread_condattr_destroy(&attr); + pthread_mutex_destroy(&_mutex); throw SystemException("cannot create event (condition)"); + } + pthread_condattr_destroy(&attr); +#else + if (pthread_cond_init(&_cond, NULL)) + { + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create event (condition)"); + } +#endif } @@ -77,7 +105,16 @@ bool EventImpl::waitImpl(long milliseconds) delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); -#elif defined(POCO_VXWORKS) +#elif defined(__linux__) || defined(__QNX__) + clock_gettime(CLOCK_MONOTONIC, &abstime); + abstime.tv_sec += milliseconds / 1000; + abstime.tv_nsec += (milliseconds % 1000)*1000000; + if (abstime.tv_nsec >= 1000000000) + { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } +#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; diff --git a/Foundation/src/Mutex_POSIX.cpp b/Foundation/src/Mutex_POSIX.cpp index ceb704ee5..09b10bec5 100644 --- a/Foundation/src/Mutex_POSIX.cpp +++ b/Foundation/src/Mutex_POSIX.cpp @@ -98,6 +98,16 @@ bool MutexImpl::tryLockImpl(long milliseconds) { #if defined(POCO_HAVE_MUTEX_TIMEOUT) struct timespec abstime; +#if defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME) + clock_gettime(CLOCK_REALTIME, &abstime); + abstime.tv_sec += milliseconds / 1000; + abstime.tv_nsec += (milliseconds % 1000)*1000000; + if (abstime.tv_nsec >= 1000000000) + { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } +#else struct timeval tv; gettimeofday(&tv, NULL); abstime.tv_sec = tv.tv_sec + milliseconds / 1000; @@ -107,6 +117,7 @@ bool MutexImpl::tryLockImpl(long milliseconds) abstime.tv_nsec -= 1000000000; abstime.tv_sec++; } +#endif int rc = pthread_mutex_timedlock(&_mutex, &abstime); if (rc == 0) return true; diff --git a/Foundation/src/Semaphore_POSIX.cpp b/Foundation/src/Semaphore_POSIX.cpp index 1aa13035b..88e768ed1 100644 --- a/Foundation/src/Semaphore_POSIX.cpp +++ b/Foundation/src/Semaphore_POSIX.cpp @@ -19,6 +19,7 @@ #include #include #else +#include #include #endif @@ -39,8 +40,34 @@ SemaphoreImpl::SemaphoreImpl(int n, int max): _n(n), _max(max) #endif if (pthread_mutex_init(&_mutex, NULL)) throw SystemException("cannot create semaphore (mutex)"); - if (pthread_cond_init(&_cond, NULL)) + +#if defined(__linux__) || defined(__QNX__) + pthread_condattr_t attr; + if (pthread_condattr_init(&attr)) + { + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create semaphore (condition attribute)"); + } + if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC)) + { + pthread_condattr_destroy(&attr); + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create semaphore (condition attribute clock)"); + } + if (pthread_cond_init(&_cond, &attr)) + { + pthread_condattr_destroy(&attr); + pthread_mutex_destroy(&_mutex); throw SystemException("cannot create semaphore (condition)"); + } + pthread_condattr_destroy(&attr); +#else + if (pthread_cond_init(&_cond, NULL)) + { + pthread_mutex_destroy(&_mutex); + throw SystemException("cannot create semaphore (condition)"); + } +#endif } @@ -78,7 +105,16 @@ bool SemaphoreImpl::waitImpl(long milliseconds) delta.tv_sec = milliseconds / 1000; delta.tv_nsec = (milliseconds % 1000)*1000000; pthread_get_expiration_np(&delta, &abstime); -#elif defined(POCO_VXWORKS) +#elif defined(__linux__) || defined(__QNX__) + clock_gettime(CLOCK_MONOTONIC, &abstime); + abstime.tv_sec += milliseconds / 1000; + abstime.tv_nsec += (milliseconds % 1000)*1000000; + if (abstime.tv_nsec >= 1000000000) + { + abstime.tv_nsec -= 1000000000; + abstime.tv_sec++; + } +#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += milliseconds / 1000; abstime.tv_nsec += (milliseconds % 1000)*1000000; diff --git a/Foundation/src/Timestamp.cpp b/Foundation/src/Timestamp.cpp index e386ad309..bba23aa4f 100644 --- a/Foundation/src/Timestamp.cpp +++ b/Foundation/src/Timestamp.cpp @@ -226,7 +226,7 @@ void Timestamp::update() ts.QuadPart -= epoch.QuadPart; _ts = ts.QuadPart/10; -#elif defined(POCO_VXWORKS) +#elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__) struct timespec ts; if (clock_gettime(CLOCK_REALTIME, &ts))