#include // include this first #include #include #include #include #include #include #include #include #include "gosy_thread.hpp" #include "gosy_threadimpl.hpp" #include "glog_logging.hpp" #include "gosy_common.hpp" /***************** cGosyThreadImpl *****************/ cGosyThreadImpl::cGosyThreadImpl(void) { mRunning = false; if ( geteuid() != 0) // root { assert(false); // Must run as root, else we cannot change priority of task } } cGosyThreadImpl::~cGosyThreadImpl() { } void *cGosyThreadImpl::StartThread(cGosyThread *pThread) { pThread->StartThread(); return NULL; } void cGosyThreadImpl::Start(int Priority, cGosyThread* pThread) { int RetVal = 0; // SCHED_OTHER (0 @ sched.h) -> Regular, non-realtime // SCHED_RR (1 @ sched.h) -> Round Robin, Realtime // SCHED_FIFO (2 @ sched.h) -> First-in First-out, Realtime # define POLICY (SCHED_FIFO) int Policy; pthread_attr_t Attr; struct sched_param SchedParam; assert( cGosyThread::GetMinPrio() <= Priority && cGosyThread::GetMaxPrio() >= Priority ); #if (POLICY != SCHED_OTHER) // SCHED_RR & SCHED_FIFO have prio between 1..99, so add 1 to priority of GOSY // as GOSY has prio between 0..15 Priority = 1; assert( sched_get_priority_min(POLICY) <= Priority && sched_get_priority_max(POLICY) >= Priority ); #endif if (!mRunning) { mRunning = true; RetVal = pthread_attr_init(&Attr); assert( RetVal == 0 ); // Detach state of thread will prevent "zombie processes" as no need // to join threads after cancellation. RetVal = pthread_attr_setdetachstate(&Attr, PTHREAD_CREATE_DETACHED); assert( RetVal == 0 ); #if (POLICY != SCHED_OTHER) RetVal = pthread_attr_setschedpolicy( &Attr, POLICY); assert( RetVal == 0 ); SchedParam.sched_priority = Priority; RetVal = pthread_attr_setschedparam( &Attr, &SchedParam); assert( RetVal == 0 ); #endif RetVal = pthread_create(&mThread, &Attr, (void *(*) (void *))&StartThread, (void *)pThread); assert( RetVal == 0 ); RetVal = pthread_getschedparam(mThread, &Policy, &SchedParam); assert( RetVal == 0 ); assert( Policy == POLICY ); #if (POLICY != SCHED_OTHER) assert( SchedParam.sched_priority == Priority ); #endif RetVal = pthread_attr_destroy(&Attr); assert( RetVal == 0 ); } } int cGosyThreadImpl::SetPriority(int Priority) { struct sched_param SchedParam; int RetVal = 0; pthread_attr_t Attr; if (Priority < cGosyThread::GetMinPrio() || Priority > cGosyThread::GetMaxPrio()) { return GOSY_WRONG_PRIO; } #if (POLICY != SCHED_OTHER) assert(mRunning); RetVal = pthread_attr_init(&Attr); assert( RetVal == 0 ); SchedParam.sched_priority = Priority; RetVal = pthread_setschedparam(mThread, POLICY, &SchedParam); assert( RetVal == 0 ); #endif }