waiting with pthread_mutex_timedlock, pthread_cond_timedwait now uses nanosec too. Thread can be created as a soft-realtime thread. TimerThread should have nanosec precision alarm functionality.

master
Denes Matetelki 14 years ago
parent fe5c8ea507
commit 83f61e602c

2
.gitignore vendored

@ -17,4 +17,4 @@ test/test
leak.log leak.log
leak.log.core.* leak.log.core.*
gdb.out gdb.out
html/*

@ -13,11 +13,20 @@
#include <stdexcept> // runtime_error #include <stdexcept> // runtime_error
#include <sstream> // ostringstream #include <sstream> // 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; timespec abs_time;
clock_gettime ( CLOCK_REALTIME, &abs_time ); clock_gettime ( CLOCK_REALTIME, &abs_time );
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_sec += sec;
abs_time.tv_nsec += nsec;
}
return abs_time; return abs_time;
} }

@ -12,7 +12,7 @@ public:
ConditionVariable(Mutex& mutex); ConditionVariable(Mutex& mutex);
~ConditionVariable(); ~ConditionVariable();
int wait(const long int intervalSec = 0); int wait(const long int intervalSec = 0, const long int intervaNSec = 0);
int signal(); int signal();
int broadcast(); int broadcast();

@ -27,7 +27,7 @@ public:
* If currently locked, the call shall return immediately. * If currently locked, the call shall return immediately.
* @returns Zero if a lock acquired. Otherwise, an error number. * @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(); pthread_mutex_t* getPThreadMutex();

@ -13,7 +13,7 @@ public:
Semaphore( int maxCount = 1 ); Semaphore( int maxCount = 1 );
~Semaphore( void ); ~Semaphore( void );
bool lock( const long int intervalSec = 0 ); bool lock( const long int intervalSec = 0, const long int intervalNSec = 0 );
bool unLock( void ); bool unLock( void );
int getCount( void ) const; int getCount( void ) const;

@ -8,7 +8,7 @@ class Thread
{ {
public: public:
Thread(); Thread( const bool softRealTime = false );
virtual ~Thread(); virtual ~Thread();
void start(); void start();
@ -28,6 +28,7 @@ protected:
private: private:
pthread_t m_threadHandler; pthread_t m_threadHandler;
bool m_softRealTime;
}; };

@ -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; TRACE;
if ( intervalSec == 0 ) { if ( intervalSec == 0 and intervalNSec == 0 ) {
return pthread_cond_wait( &m_condVar, return pthread_cond_wait( &m_condVar,
m_mutex.getPThreadMutex() ); m_mutex.getPThreadMutex() );
} else { } else {
timespec tspec = addSecTotimespec(intervalSec); timespec tspec = addTotimespec( intervalSec, intervalNSec );
return pthread_cond_timedwait( &m_condVar, return pthread_cond_timedwait( &m_condVar,
m_mutex.getPThreadMutex(), m_mutex.getPThreadMutex(),
&tspec); &tspec);

@ -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; TRACE;
if ( intervalSec == 0 ) { if ( intervalSec == 0 and intervalNSec == 0 ) {
return pthread_mutex_trylock ( &m_mutex ); return pthread_mutex_trylock ( &m_mutex );
} else { } else {
timespec tspec = addSecTotimespec( intervalSec ); timespec tspec = addTotimespec( intervalSec, intervalSec );
return pthread_mutex_timedlock ( &m_mutex, &tspec ); return pthread_mutex_timedlock ( &m_mutex, &tspec );
} }
} }

@ -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; TRACE;
ScopedLock sl(m_mutex); ScopedLock sl(m_mutex);
if ( m_count == 0 ) { if ( m_count == 0 ) {
if ( m_condVar.wait(intervalSec) != 0 ) { if ( m_condVar.wait( intervalSec, intervalNSec ) != 0 ) {
return false; return false;
} }
} }

@ -3,12 +3,15 @@
#include <signal.h> #include <signal.h>
#include <iostream> #include <iostream>
#include <exception> // std::runtime_error
#include <sched.h> // sched_param
Thread::Thread()
Thread::Thread(const bool softRealTime)
: m_isRunning(false) : m_isRunning(false)
, m_threadHandler( 0 ) , m_threadHandler( 0 )
, m_softRealTime(softRealTime)
{ {
TRACE; TRACE;
} }
@ -24,7 +27,24 @@ void Thread::start()
{ {
TRACE; TRACE;
m_isRunning = true; 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, &param ) != 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 );
}
} }

@ -4,11 +4,13 @@
#include "ScopedLock.hpp" #include "ScopedLock.hpp"
#include <errno.h> // ETIMEDOUT #include <errno.h> // ETIMEDOUT
#include <pthread.h> // pthread_attr_t, sched_param
TimerThread::TimerThread() TimerThread::TimerThread()
: m_mutex() : Thread(true)
, m_mutex()
, m_condVar(m_mutex) , m_condVar(m_mutex)
, m_users() , m_users()
{ {

Loading…
Cancel
Save