diff --git a/.gitignore b/.gitignore index 5f94d10..479fb67 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,4 @@ test/test leak.log leak.log.core.* gdb.out - +html/* diff --git a/include/Common.hpp b/include/Common.hpp index 2dd85c2..4d10e45 100644 --- a/include/Common.hpp +++ b/include/Common.hpp @@ -13,11 +13,20 @@ #include // runtime_error #include // ostringstream -inline timespec addSecTotimespec(const long int & sec) +inline timespec addTotimespec(const long int & sec, const long int & nsec) { + const int nano = 1000000000; // 10^9 timespec abs_time; clock_gettime ( CLOCK_REALTIME, &abs_time ); - abs_time.tv_sec += sec; + long int nsecSum( abs_time.tv_nsec + nsec ); + + if ( nsecSum >= nano ) { + abs_time.tv_sec += sec + nsecSum / nano; + abs_time.tv_nsec = nsecSum % nano; + } else { + abs_time.tv_sec += sec; + abs_time.tv_nsec += nsec; + } return abs_time; } diff --git a/include/ConditionVariable.hpp b/include/ConditionVariable.hpp index 1f9ae7b..b8f05c7 100644 --- a/include/ConditionVariable.hpp +++ b/include/ConditionVariable.hpp @@ -12,7 +12,7 @@ public: ConditionVariable(Mutex& mutex); ~ConditionVariable(); - int wait(const long int intervalSec = 0); + int wait(const long int intervalSec = 0, const long int intervaNSec = 0); int signal(); int broadcast(); diff --git a/include/Mutex.hpp b/include/Mutex.hpp index fa294d5..7b3a2de 100644 --- a/include/Mutex.hpp +++ b/include/Mutex.hpp @@ -27,7 +27,7 @@ public: * If currently locked, the call shall return immediately. * @returns Zero if a lock acquired. Otherwise, an error number. */ - int tryLock(const long int intervalSec = 0); + int tryLock(const long int intervalSec = 0, const long int intervalNSec = 0); pthread_mutex_t* getPThreadMutex(); diff --git a/include/Semaphore.hpp b/include/Semaphore.hpp index cf390d0..fe36a88 100644 --- a/include/Semaphore.hpp +++ b/include/Semaphore.hpp @@ -13,7 +13,7 @@ public: Semaphore( int maxCount = 1 ); ~Semaphore( void ); - bool lock( const long int intervalSec = 0 ); + bool lock( const long int intervalSec = 0, const long int intervalNSec = 0 ); bool unLock( void ); int getCount( void ) const; diff --git a/include/Thread.hpp b/include/Thread.hpp index 2c88df1..f322f59 100644 --- a/include/Thread.hpp +++ b/include/Thread.hpp @@ -8,7 +8,7 @@ class Thread { public: - Thread(); + Thread( const bool softRealTime = false ); virtual ~Thread(); void start(); @@ -28,6 +28,7 @@ protected: private: pthread_t m_threadHandler; + bool m_softRealTime; }; diff --git a/src/ConditionVariable.cpp b/src/ConditionVariable.cpp index 63abbad..71f56a9 100644 --- a/src/ConditionVariable.cpp +++ b/src/ConditionVariable.cpp @@ -19,14 +19,14 @@ ConditionVariable::~ConditionVariable() } -int ConditionVariable::wait(const long int intervalSec) +int ConditionVariable::wait(const long int intervalSec, const long int intervalNSec) { TRACE; - if ( intervalSec == 0 ) { + if ( intervalSec == 0 and intervalNSec == 0 ) { return pthread_cond_wait( &m_condVar, m_mutex.getPThreadMutex() ); } else { - timespec tspec = addSecTotimespec(intervalSec); + timespec tspec = addTotimespec( intervalSec, intervalNSec ); return pthread_cond_timedwait( &m_condVar, m_mutex.getPThreadMutex(), &tspec); diff --git a/src/Mutex.cpp b/src/Mutex.cpp index e5a6147..039d811 100644 --- a/src/Mutex.cpp +++ b/src/Mutex.cpp @@ -40,13 +40,13 @@ int Mutex::unlock() } -int Mutex::tryLock(const long int intervalSec) +int Mutex::tryLock(const long int intervalSec, const long int intervalNSec) { TRACE; - if ( intervalSec == 0 ) { + if ( intervalSec == 0 and intervalNSec == 0 ) { return pthread_mutex_trylock ( &m_mutex ); } else { - timespec tspec = addSecTotimespec( intervalSec ); + timespec tspec = addTotimespec( intervalSec, intervalSec ); return pthread_mutex_timedlock ( &m_mutex, &tspec ); } } diff --git a/src/Semaphore.cpp b/src/Semaphore.cpp index 586438c..d085dfa 100644 --- a/src/Semaphore.cpp +++ b/src/Semaphore.cpp @@ -20,12 +20,12 @@ Semaphore::~Semaphore( void ) } -bool Semaphore::lock( const long int intervalSec ) +bool Semaphore::lock( const long int intervalSec, const long int intervalNSec ) { TRACE; ScopedLock sl(m_mutex); if ( m_count == 0 ) { - if ( m_condVar.wait(intervalSec) != 0 ) { + if ( m_condVar.wait( intervalSec, intervalNSec ) != 0 ) { return false; } } diff --git a/src/Thread.cpp b/src/Thread.cpp index e7ccf1f..78c916f 100644 --- a/src/Thread.cpp +++ b/src/Thread.cpp @@ -3,12 +3,15 @@ #include #include +#include // std::runtime_error +#include // sched_param -Thread::Thread() + +Thread::Thread(const bool softRealTime) : m_isRunning(false) , m_threadHandler( 0 ) - + , m_softRealTime(softRealTime) { TRACE; } @@ -24,7 +27,24 @@ void Thread::start() { TRACE; m_isRunning = true; - pthread_create( &m_threadHandler, NULL, threadStarter, ( void* )this ); + + if ( m_softRealTime ) { + pthread_attr_t attr; + sched_param param; + + pthread_attr_init(&attr); + if ( pthread_attr_setschedpolicy( &attr, SCHED_RR ) != 0 ) { + throw std::runtime_error( "Coudn't set thread scheduler." ); + } + param.sched_priority = 50; + if ( pthread_attr_setschedparam( &attr, ¶m ) != 0 ) { + throw std::runtime_error( "Coudn't set thread priority."); + } + + pthread_create( &m_threadHandler, &attr, threadStarter, ( void* )this ); + } else { + pthread_create( &m_threadHandler, 0, threadStarter, ( void* )this ); + } } diff --git a/src/TimerThread.cpp b/src/TimerThread.cpp index 8e155e4..c1edc1c 100644 --- a/src/TimerThread.cpp +++ b/src/TimerThread.cpp @@ -4,11 +4,13 @@ #include "ScopedLock.hpp" #include // ETIMEDOUT +#include // pthread_attr_t, sched_param TimerThread::TimerThread() - : m_mutex() + : Thread(true) + , m_mutex() , m_condVar(m_mutex) , m_users() {