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.