- prefer clock_getttime() over gettimeofday() if available

- use CLOCK_MONOTONIC for POSIX condition in Poco::Event and Poco::Semaphore if supported
This commit is contained in:
Guenter Obiltschnig 2016-08-11 12:45:29 +02:00 committed by Guenter Obiltschnig
parent a1b8f96111
commit 64635f7c8b
4 changed files with 89 additions and 5 deletions

View File

@ -19,6 +19,7 @@
#include <timers.h> #include <timers.h>
#include <cstring> #include <cstring>
#else #else
#include <time.h>
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -35,10 +36,37 @@ EventImpl::EventImpl(EventTypeImpl type): _auto(type == EVENT_AUTORESET_IMPL), _
// if the mutex has never been used. // if the mutex has never been used.
std::memset(&_mutex, 0, sizeof(_mutex)); std::memset(&_mutex, 0, sizeof(_mutex));
#endif #endif
if (pthread_mutex_init(&_mutex, NULL)) if (pthread_mutex_init(&_mutex, NULL))
throw SystemException("cannot create event (mutex)"); 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)"); 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_sec = milliseconds / 1000;
delta.tv_nsec = (milliseconds % 1000)*1000000; delta.tv_nsec = (milliseconds % 1000)*1000000;
pthread_get_expiration_np(&delta, &abstime); 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); clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += milliseconds / 1000; abstime.tv_sec += milliseconds / 1000;
abstime.tv_nsec += (milliseconds % 1000)*1000000; abstime.tv_nsec += (milliseconds % 1000)*1000000;

View File

@ -73,6 +73,16 @@ bool MutexImpl::tryLockImpl(long milliseconds)
{ {
#if defined(POCO_HAVE_MUTEX_TIMEOUT) #if defined(POCO_HAVE_MUTEX_TIMEOUT)
struct timespec abstime; 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; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
abstime.tv_sec = tv.tv_sec + milliseconds / 1000; abstime.tv_sec = tv.tv_sec + milliseconds / 1000;
@ -82,6 +92,7 @@ bool MutexImpl::tryLockImpl(long milliseconds)
abstime.tv_nsec -= 1000000000; abstime.tv_nsec -= 1000000000;
abstime.tv_sec++; abstime.tv_sec++;
} }
#endif
int rc = pthread_mutex_timedlock(&_mutex, &abstime); int rc = pthread_mutex_timedlock(&_mutex, &abstime);
if (rc == 0) if (rc == 0)
return true; return true;

View File

@ -19,6 +19,7 @@
#include <timers.h> #include <timers.h>
#include <cstring> #include <cstring>
#else #else
#include <time.h>
#include <sys/time.h> #include <sys/time.h>
#endif #endif
@ -39,8 +40,34 @@ SemaphoreImpl::SemaphoreImpl(int n, int max): _n(n), _max(max)
#endif #endif
if (pthread_mutex_init(&_mutex, NULL)) if (pthread_mutex_init(&_mutex, NULL))
throw SystemException("cannot create semaphore (mutex)"); 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)"); 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_sec = milliseconds / 1000;
delta.tv_nsec = (milliseconds % 1000)*1000000; delta.tv_nsec = (milliseconds % 1000)*1000000;
pthread_get_expiration_np(&delta, &abstime); 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); clock_gettime(CLOCK_REALTIME, &abstime);
abstime.tv_sec += milliseconds / 1000; abstime.tv_sec += milliseconds / 1000;
abstime.tv_nsec += (milliseconds % 1000)*1000000; abstime.tv_nsec += (milliseconds % 1000)*1000000;

View File

@ -227,7 +227,7 @@ void Timestamp::update()
ts.QuadPart -= epoch.QuadPart; ts.QuadPart -= epoch.QuadPart;
_ts = ts.QuadPart/10; _ts = ts.QuadPart/10;
#elif defined(POCO_VXWORKS) #elif (defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME)) || defined(POCO_VXWORKS) || defined(__QNX__)
struct timespec ts; struct timespec ts;
if (clock_gettime(CLOCK_REALTIME, &ts)) if (clock_gettime(CLOCK_REALTIME, &ts))