38 #include "../ThreadInterface.hpp"    40 #include "../fosi_internal_interface.hpp"    41 #include "../../Logger.hpp"    44 #include <sys/resource.h>    45 #ifdef ORO_OS_LINUX_CAP_NG    50 #include <sys/types.h>    52 #include <sys/syscall.h>    63         const char* name = 
"main";
    65         main_task->
name = strcpy( (
char*)malloc( (strlen(name) + 1) * 
sizeof(
char)), name);
    66         main_task->
thread = pthread_self();
    67         pthread_attr_init( &(main_task->
attr) );
    68         struct sched_param sp;
    72         pthread_attr_setschedparam(&(main_task->
attr), &sp);
    73         main_task->
priority = sp.sched_priority;
    74         main_task->
pid = getpid();
    80         pthread_attr_destroy( &(main_task->
attr) );
    81         free(main_task->
name);
    82         main_task->
name = NULL;
    88         void* (*wrapper)(
void*);
    95         task->
pid = syscall(SYS_gettid);
   108                        unsigned cpu_affinity,
   112                        void * (*start_routine)(
void *),
   124         xcookie->
wrapper = start_routine;
   127         if ( strlen(name) == 0 )
   129         task->
name = strcpy( (
char*)malloc( (strlen(name) + 1) * 
sizeof(
char)), name);
   131         if ( (rv = pthread_attr_init(&(task->
attr))) != 0 ){
   135         if ( (rv = pthread_attr_setschedpolicy(&(task->
attr), sched_type)) != 0){
   140             if ( (rv = pthread_attr_setstacksize(&(task->
attr), stack_size)) != 0){
   143         pthread_attr_getschedpolicy(&(task->
attr), &rv );
   144         assert( rv == sched_type );
   148         struct sched_param sp;
   149         if (sched_type != SCHED_OTHER){
   150             sp.sched_priority=priority;
   152             if ( (rv = pthread_attr_setschedparam(&(task->
attr), &sp)) != 0 ){
   156         rv = pthread_create(&(task->
thread), &(task->
attr),
   159             log(
Error) << 
"Failed to create thread " << task->
name << 
": "   160                        << strerror(rv) << endlog();
   164 #ifdef ORO_HAVE_PTHREAD_SETNAME_NP   169             static const int MAX_THREAD_NAME_SIZE = 15;
   170             char n[MAX_THREAD_NAME_SIZE + 1];
   171             const char *thread_name = task->
name;
   172             const std::size_t thread_name_len = strlen(thread_name);
   173             if (thread_name_len > MAX_THREAD_NAME_SIZE) {
   175                 strncpy(&n[0], thread_name, 7);
   177                 strncpy(&n[8], &thread_name[thread_name_len - 7], 7);
   183                 strncpy(&n[0], thread_name, MAX_THREAD_NAME_SIZE);
   185             n[MAX_THREAD_NAME_SIZE] = 
'\0'; 
   186             int result = pthread_setname_np(task->
thread, &n[0]);
   188                 log(
Warning) << 
"Failed to set thread name for " << task->
name << 
": "   189                              << strerror(result) << endlog();
   192 #endif // ORO_HAVE_PTHREAD_SETNAME_NP   194         if ( cpu_affinity != 0 ) {
   195             log(
Debug) << 
"Setting CPU affinity to " << cpu_affinity << endlog();
   198                 log(
Error) << 
"Failed to set CPU affinity to " << cpu_affinity << 
" for " << task->
name << 
": "   199                            << strerror(result) << endlog();
   214         int ret = sched_yield();
   216             perror(
"rtos_task_yield");
   228         pthread_t 
self = pthread_self();
   229         if ( pthread_equal(
self, task->
thread) == 0 ) 
   236         struct sched_param param;
   241         if (pthread_getschedparam(task->
thread, &policy, ¶m) == 0) {
   243             param.sched_priority = task->
priority;
   246             return pthread_setschedparam( task->
thread, sched_type, ¶m);
   253         struct sched_param param;
   255         if ( task && task->
thread != 0 && pthread_getschedparam(task->
thread, &policy, ¶m) == 0)
   263         mytask->
period = nanosecs;
   288         while ( clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &(task->
periodMark), NULL) != 0 && errno == EINTR ) {
   300           task->
periodMark.tv_sec += ts.tv_sec + tn / 1000000000LL;
   306           NANO_TIME tn = (now.tv_nsec + ts.tv_nsec);
   308           task->
periodMark.tv_sec = ts.tv_sec + now.tv_sec + tn / 1000000000LL;
   311         return now > wake ? -1 : 0;
   315         pthread_join( mytask->
thread, 0);
   316         pthread_attr_destroy( &(mytask->
attr) );
   323 #ifdef ORO_OS_LINUX_CAP_NG   324         if(capng_get_caps_process()) {
   325             log(
Error) << 
"Failed to retrieve capabilities (lowering to SCHED_OTHER)." <<endlog();
   326             *scheduler = SCHED_OTHER;
   331         if (*scheduler != SCHED_OTHER && geteuid() != 0
   332 #ifdef ORO_OS_LINUX_CAP_NG
   333             && capng_have_capability(CAPNG_EFFECTIVE, CAP_SYS_NICE)==0
   340             if ((0 != getrlimit(RLIMIT_RTPRIO, &r)) || (0 == r.rlim_cur))
   342                 log(
Warning) << 
"Lowering scheduler type to SCHED_OTHER for non-privileged users.." <<endlog();
   343                 *scheduler = SCHED_OTHER;
   348         if (*scheduler != SCHED_OTHER && *scheduler != SCHED_FIFO && *scheduler != SCHED_RR ) {
   349             log(
Error) << 
"Unknown scheduler type." <<endlog();
   350             *scheduler = SCHED_OTHER;
   363         if (*scheduler == SCHED_OTHER) {
   364             if ( *priority != 0 ) {
   366                     log(
Warning) << 
"Forcing priority ("<<*priority<<
") of thread with SCHED_OTHER policy to 0." <<endlog();
   373                 log(
Warning) << 
"Forcing priority ("<<*priority<<
") of thread with !SCHED_OTHER policy to 1." <<endlog();
   378                 log(
Warning) << 
"Forcing priority ("<<*priority<<
") of thread with !SCHED_OTHER policy to 99." <<endlog();
   384 #ifdef ORO_OS_LINUX_CAP_NG
   385                  && !capng_have_capability(CAPNG_EFFECTIVE, CAP_SYS_NICE)
   390                 if (0 == getrlimit(RLIMIT_RTPRIO, &r))
   392                     if (*priority > (
int)r.rlim_cur)
   394                         log(
Warning) << 
"Forcing priority ("<<*priority<<
") of thread with !SCHED_OTHER policy to the pam_limit of " << r.rlim_cur <<endlog();
   395                         *priority = r.rlim_cur;
   413         struct sched_param param;
   415         if( task && task->
thread != 0 && pthread_getschedparam(task->
thread, &policy, ¶m) == 0) {
   418             param.sched_priority = priority;
   421             return pthread_setschedparam( task->
thread, policy, ¶m);
   430         struct sched_param param;
   434         if ( task->
thread == 0 || pthread_getschedparam(task->
thread, &policy, ¶m) != 0)
   436         return param.sched_priority;
   441         if ( cpu_affinity == 0 ) 
   443         if( task && task->
thread != 0 ) {
   446             for(
unsigned i = 0; i < 8*
sizeof(cpu_affinity); i++)
   448                     if(cpu_affinity & (1 << i)) { CPU_SET(i, &cs); }
   450             return pthread_setaffinity_np(task->
thread, 
sizeof(cs), &cs);
   457         if( task && task->
thread != 0) {
   458         unsigned cpu_affinity = 0;
   460         pthread_getaffinity_np(task->
thread, 
sizeof(cs), &cs);
   461         for(
unsigned i = 0; i < 8*
sizeof(cpu_affinity); i++)
   463           if(CPU_ISSET(i, &cs)) { cpu_affinity |= (1 << i); }
   472         return task->
name ? task->
name : 
"(destroyed)";
 
int rtos_task_is_self(const RTOS_TASK *task)
Returns 1 when task is the task struct of the thread calling this function, 0 otherwise. 
int rtos_task_get_priority(const RTOS_TASK *task)
Return the priority of a thread. 
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...
INTERNAL_QUAL int rtos_task_check_priority(int *scheduler, int *priority)
This function checks (and corrects) a given priority within a given scheduler type. 
unsigned int rtos_task_get_pid(const RTOS_TASK *task)
Returns the process ID the OS gave to the task task. 
NANO_TIME rtos_get_time_ns(void)
Get "system" time in nanoseconds. 
int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
INTERNAL_QUAL int rtos_task_delete_main(RTOS_TASK *main_task)
Cleanup the main thread. 
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. 
int rtos_task_set_cpu_affinity(RTOS_TASK *task, unsigned cpu_affinity)
Set the cpu affinity of a thread. 
unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
Return the cpu affinity of a thread. 
INTERNAL_QUAL void * rtos_posix_thread_wrapper(void *cookie)
TIME_SPEC ticks2timespec(TICK_TIME hrt)
void *(* wrapper)(void *)
A thread which is being run. 
void rtos_task_set_wait_period_policy(RTOS_TASK *task, int policy)
Set the wait policy of a thread. 
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...
int rtos_task_set_priority(RTOS_TASK *task, int priority)
Set the priority of a thread. 
const char * rtos_task_get_name(const RTOS_TASK *task)
Returns the name by which a task is known in the RTOS. 
int rtos_task_check_scheduler(int *sched_type)
This function checks (and corrects) if the given sched_type is valid for this RTOS. 
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...
INTERNAL_QUAL void rtos_task_yield(RTOS_TASK *)
Yields the current thread. 
TICK_TIME nano2ticks(NANO_TIME nano)
Time conversions from nano seconds to system ticks. 
const int LowestPriority
An integer denoting the lowest priority of the selected OS. 
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute. 
INTERNAL_QUAL int rtos_task_create_main(RTOS_TASK *main_task)
Initialise the main thread. 
void rtos_task_set_period(RTOS_TASK *mytask, NANO_TIME nanosecs)
Change the period of a periodic RTOS task. 
struct timespec TIME_SPEC
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. 
int rtos_task_get_scheduler(const RTOS_TASK *t)
Returns the current scheduler set for task t.