40 #include "../Time.hpp" 42 #include "../Logger.hpp" 46 #include "../rtt-config.h" 47 #include "../internal/CatchConfig.hpp" 49 #ifdef OROPKG_OS_THREAD_SCOPE 50 # include "../extras/dev/DigitalOutInterface.hpp" 51 #define SCOPE_ON if ( task->d ) task->d->switchOn( bit ); 52 #define SCOPE_OFF if ( task->d ) task->d->switchOff( bit ); 63 unsigned int Thread::default_stack_size = 0;
65 double Thread::lock_timeout_no_period_in_s = 1.0;
67 double Thread::lock_timeout_period_factor = 10.0;
90 #ifdef OROPKG_OS_THREAD_SCOPE 96 int overruns = 0, cur_sched = task->msched_type;
99 while (!task->prepareForExit)
107 if (!task->active || (task->active && task->period == 0) || !task->running )
110 if (task->period != 0) {
113 rtos_task_set_period(task->getTask(), 0);
117 if (task->prepareForExit)
126 if (task->period != 0)
129 while(task->running && !task->prepareForExit )
144 if ( cur_period != task->period) {
147 cur_period = task->period;
153 if ( cur_sched != task->msched_type) {
155 cur_sched = task->msched_type;
163 if (overruns == task->maxOverRun)
166 else if (overruns != 0)
169 if (overruns == task->maxOverRun || task->prepareForExit)
183 task->inloop =
false;
187 task->inloop =
false;
192 if (overruns == task->maxOverRun)
197 <<
" got too many periodic overruns in step() (" 198 << overruns <<
" times), stopped Thread !" 200 log() <<
" See Thread::setMaxOverrun() for info." 203 )
CATCH(std::exception
const& e,
208 <<
" caught a C++ exception, stopped thread !" 211 << e.what() << endlog();
218 <<
" caught an unknown C++ exception, stopped thread !" 229 this->running =
false;
230 this->inloop =
false;
231 this->active =
false;
237 Seconds periods,
unsigned cpu_affinity,
const std::string & name) :
238 msched_type(scheduler), active(false), prepareForExit(false),
239 inloop(false),running(false),
242 #ifdef OROPKG_OS_THREAD_SCOPE
247 this->setup(_priority, cpu_affinity, name);
250 void Thread::setup(
int _priority,
unsigned cpu_affinity,
const std::string& name)
258 log(
Info) <<
"Creating Thread for scheduler=" << (msched_type ==
ORO_SCHED_OTHER ?
"ORO_SCHED_OTHER" :
"ORO_SCHED_RT")
259 <<
", priority=" << _priority
260 <<
", CPU affinity=" << cpu_affinity
261 <<
", with name='" << name <<
"'" 267 <<
"Could not allocate configuration semaphore 'sem' for " 269 <<
". Throwing std::bad_alloc." << endlog();
272 throw std::bad_alloc();
278 #ifdef OROPKG_OS_THREAD_SCOPE 288 log(
Warning) <<
"Failed to find 'ThreadScope' object in DigitalOutInterface::nameserver." << endlog();
292 int rv =
rtos_task_create(&rtos_task, _priority, cpu_affinity, name.c_str(),
296 log(
Critical) <<
"Could not create thread " 301 throw std::bad_alloc();
310 const char* modname =
getName();
312 log(
Info) <<
"Thread created with scheduler type '" 315 <<
" and period " <<
getPeriod() <<
" (PID= " <<
getPid() <<
" )." << endlog();
316 #ifdef OROPKG_OS_THREAD_SCOPE 320 log(
Info) <<
"ThreadScope :"<< modname <<
" toggles bit "<< bit << endlog();
331 log(
Debug) <<
"Terminating " << this->
getName() << endlog();
333 log(
Debug) <<
" done" << endlog();
344 #ifndef OROPKG_OS_MACOSX 363 if ( this->
initialize() ==
false || active ==
false ) {
382 if (result ==
false || active ==
false)
395 <<
"Thread::start(): sem_signal returns " << ret
410 if (stopTimeout != 0)
412 else if (period == 0)
413 return Thread::lock_timeout_no_period_in_s;
414 else return Thread::lock_timeout_period_factor *
getPeriod();
428 log(
Warning) <<
"Failed to stop thread " << this->
getName() <<
": breakLoop() returned false."<<endlog();
437 log(
Error) <<
"Failed to stop thread " << this->
getName() <<
": breakLoop() returned true, but loop() function did not return after " <<
getStopTimeout() <<
" seconds."<<endlog();
448 log(
Error) <<
"Failed to stop thread " << this->
getName() <<
": step() function did not return after "<<
getStopTimeout() <<
" seconds."<<endlog();
461 return period == 0 ? inloop : running;
479 log(
Info) <<
"Setting scheduler type for Thread '" 481 << sched_type << endlog();
483 msched_type = sched_type;
493 void Thread::configure()
544 nsecs nsperiod = ns + 1000* 1000* 1000* s ;
548 if ( (nsperiod == 0 && period != 0) || (nsperiod != 0 && period == 0)) {
567 return this->
setPeriod( p.tv_sec, p.tv_nsec );
572 s =
secs(period/(1000*1000*1000));
573 ns = period - s*1000*1000*1000;
624 if (prepareForExit)
return;
626 prepareForExit =
true;
int rtos_task_get_priority(const RTOS_TASK *task)
Return the priority of a thread.
virtual void setMaxOverrun(int m)
INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK *mytask, NANO_TIME nanosecs)
This function is to inform the RTOS that a thread is switching between periodic or non-periodic execu...
double Seconds
Seconds are stored as a double precision float.
#define TRY(C)
Contains static global configuration variables and cached entries.
static void setLockTimeoutNoPeriod(double timeout_in_s)
Sets the lock timeout for a thread which does not have a period The default is 1 second.
static NameServer< DigitalOutInterface * > nameserver
The NameServer of this interface.
bool CheckScheduler(int &sched_type)
Check if the scheduler is a valid type in the current process and adapt to a valid value...
A Thread object executes user code in its own thread.
unsigned int rtos_task_get_pid(const RTOS_TASK *task)
Returns the process ID the OS gave to the task task.
Seconds nsecs_to_Seconds(const nsecs ns)
void setStopTimeout(Seconds s)
Sets the timeout for stop(), in seconds.
int rtos_sem_signal(rt_sem_t *m)
int rtos_task_set_scheduler(RTOS_TASK *t, int sched_type)
Set the scheduler of a given task t to a the type sched_type.
friend void * thread_function(void *t)
long secs
seconds as a signed long.
A simple logging class to debug/ analyse what is going on in the Orocos system.
virtual bool setCpuAffinity(unsigned cpu_affinity)
Set cpu affinity for this thread.
int rtos_task_set_cpu_affinity(RTOS_TASK *task, unsigned cpu_affinity)
Set the cpu affinity of a thread.
virtual bool setScheduler(int sched_type)
Change the scheduler policy in which this thread runs.
unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
Return the cpu affinity of a thread.
virtual bool setPriority(int priority)
Set the priority of this Thread.
virtual RTOS_TASK * getTask()
Get the RTOS_TASK pointer.
This file has all the (periodic) thread specific interfaces.
virtual int getMaxOverrun() const
void rtos_task_set_wait_period_policy(RTOS_TASK *task, int policy)
Set the wait policy of a thread.
static void setLockTimeoutPeriodFactor(double factor)
Set the lock timeout for a thread which has a period by a factor of the period The default is factor ...
void rtos_task_delete(RTOS_TASK *mytask)
This function must join the thread created with rtos_task_create and then clean up the RTOS_TASK stru...
virtual bool isActive() const
Returns whether the thread is active.
int rtos_task_set_priority(RTOS_TASK *task, int priority)
Set the priority of a thread.
unsigned int threadNumber() const
The unique thread number (within the same process).
int rtos_sem_destroy(rt_sem_t *m)
virtual bool initialize()
const char * rtos_task_get_name(const RTOS_TASK *task)
Returns the name by which a task is known in the RTOS.
A MutexTimedLock locks a Mutex object on construction and if successful, unlocks it on destruction of...
virtual unsigned getCpuAffinity() const
int rtos_task_wait_period(RTOS_TASK *task)
This function is called by a periodic thread which wants to go to sleep and wake up the next period...
bool isSuccessful()
Return if the locking of the Mutex was succesfull.
ValueType getObject(const NameType &s) const
Get the object registered for a name.
INTERNAL_QUAL void rtos_task_yield(RTOS_TASK *)
Yields the current thread.
void terminate()
Exit and destroy the thread.
virtual int getScheduler() const
Get the scheduler policy in which this thread runs.
#define OROSEM_OS_PERIODIC_THREADS_MAX_OVERRUN
Notify the Logger in which 'module' the message occured.
bool setPeriod(Seconds s)
Set the periodicity in Seconds.
int rtos_sem_init(rt_sem_t *m, int value)
All these should return zero in case of succes.
nsecs Seconds_to_nsecs(const Seconds s)
static void setStackSize(unsigned int ssize)
Sets the stack size of the threads to be created.
virtual bool start()
Start the Thread.
Thread(int scheduler, int priority, double period, unsigned cpu_affinity, const std::string &name)
Create a Thread with a given scheduler type, priority and a name.
int rtos_sem_value(rt_sem_t *m)
Seconds getStopTimeout() const
Returns the desired timeout for stop(), in seconds.
virtual void yield()
Yields (put to the back of the scheduler queue) the calling thread.
virtual bool stop()
Stop the Thread.
virtual void setWaitPeriodPolicy(int p)
Set the wait policy of a periodic thread.
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
void rtos_task_set_period(RTOS_TASK *mytask, NANO_TIME nanosecs)
Change the period of a periodic RTOS task.
virtual int getPriority() const
The priority of this Thread.
virtual Seconds getPeriod() const
Get the periodicity in Seconds.
long long nsecs
nanoseconds as a signed long long.
struct timespec TIME_SPEC
virtual unsigned int getPid() const
Returns the Process or Thread ID of this thread, as assigned by the Operating System.
int rtos_sem_wait(rt_sem_t *m)
virtual bool isPeriodic() const
virtual nsecs getPeriodNS() const
Get the periodicity in nanoseconds.
virtual const char * getName() const
Read the name of this task.
INTERNAL_QUAL int rtos_task_create(RTOS_TASK *task, int priority, unsigned cpu_affinity, const char *name, int sched_type, size_t stack_size, void *(*start_routine)(void *), ThreadInterface *obj)
Create a thread.
virtual bool isRunning() const
Returns whether the thread is running.
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
int rtos_task_get_scheduler(const RTOS_TASK *t)
Returns the current scheduler set for task t.