32 #include <sys/resource.h> 35 #if CONFIG_XENO_VERSION_MAJOR >= 3 36 # include <alchemy/task.h> 37 # include <alchemy/timer.h> 39 # include <native/task.h> 40 # include <native/timer.h> 51 static bool init_rt =
false;
52 static pthread_key_t is_rt_key;
53 static char* RT_TASK_NAME =
"RTXI RT Thread";
55 static const char* sigdebug_reasons[] = {
56 [SIGDEBUG_UNDEFINED] =
"latency: received SIGXCPU for unknown reason",
57 [SIGDEBUG_MIGRATE_SIGNAL] =
"received signal",
58 [SIGDEBUG_MIGRATE_SYSCALL] =
"invoked syscall",
59 [SIGDEBUG_MIGRATE_FAULT] =
"triggered fault",
60 [SIGDEBUG_MIGRATE_PRIOINV] =
"affected by priority inversion",
62 "Xenomai: process memory not locked " 63 "(missing mlockall?)",
65 "Xenomai: watchdog triggered " 66 "(period too short?)",
71 const char fmt[] =
"Mode switch (reason: %s), aborting. Backtrace:\n";
72 unsigned int reason = si->si_value.sival_int;
73 static char buffer[256];
77 if (reason > SIGDEBUG_WATCHDOG)
78 reason = SIGDEBUG_UNDEFINED;
81 case SIGDEBUG_UNDEFINED:
82 n = snprintf(buffer,
sizeof(buffer),
"%s\n", sigdebug_reasons[reason]);
83 write(STDERR_FILENO, buffer, n);
85 case SIGDEBUG_MIGRATE_SIGNAL:
86 n = snprintf(buffer,
sizeof(buffer),
"%s\n", sigdebug_reasons[reason]);
87 write(STDERR_FILENO, buffer, n);
89 case SIGDEBUG_WATCHDOG:
91 n = snprintf(buffer,
sizeof(buffer),
"%s\n", sigdebug_reasons[reason]);
92 write(STDERR_FILENO, buffer, n);
97 n = snprintf(buffer,
sizeof(buffer), fmt, sigdebug_reasons[reason]);
98 n = write(STDERR_FILENO, buffer, n);
99 n = backtrace(bt,
sizeof(bt) /
sizeof(bt[0]));
100 backtrace_symbols_fd(bt, n, STDERR_FILENO);
102 signal(sig, SIG_DFL);
111 struct rlimit rlim = {RLIM_INFINITY, RLIM_INFINITY};
112 setrlimit(RLIMIT_MEMLOCK, &rlim);
114 if (mlockall(MCL_CURRENT | MCL_FUTURE)) {
115 ERROR_MSG(
"RTOS:Xenomai::initiate : failed to lock memory.\n");
119 pthread_key_create(&is_rt_key, 0);
127 pthread_key_delete(is_rt_key);
131 void* (*entry)(
void*),
141 sigemptyset(&sa.sa_mask);
143 sa.sa_flags = SA_SIGINFO;
144 sigaction(SIGDEBUG, &sa, NULL);
147 rt_task_set_mode(0, T_WARNSW, NULL);
150 if ((prio >= 0) && (prio <= 99))
153 if ((retval = rt_task_create(&t->
task, RT_TASK_NAME, 0, priority, 0))) {
154 ERROR_MSG(
"RT::OS::createTask : failed to create task\n");
161 pthread_setspecific(is_rt_key,
reinterpret_cast<const void*
>(t));
163 if ((retval = rt_task_start(
164 &t->
task,
reinterpret_cast<void (*)(
void*)
>(entry), arg)))
166 ERROR_MSG(
"RT::OS::createTask : failed to start task\n");
176 rt_task_delete(&t->
task);
181 if (init_rt && rt_task_self() != NULL)
188 #if CONFIG_XENO_VERSION_MAJOR >= 3 189 return rt_timer_read();
191 return rt_timer_tsc2ns(rt_timer_tsc());
201 if (period / 10 > 50000ll)
202 t->
wakeup_t = rt_timer_ns2ticks(50000ll);
204 t->
wakeup_t = rt_timer_ns2ticks(period / 10);
207 t->
period = rt_timer_ns2ticks(period);
222 rt_timer_spin(rt_timer_ticks2ns(t->
next_t - rt_timer_read()));
237 "RT::OS::getCpuUsage : This function should only be run in user space. " 244 double cpu_rt_percent;
245 double cpu_user_percent;
246 long rt_time_elapsed;
247 long proc_time_elapsed;
248 long cpu_time_elapsed;
249 RT_TASK_INFO task_info;
253 reinterpret_cast<xenomai_task_t*
>(RT::System::getInstance()->getTask());
254 rt_task_inquire(&(task->
task), &task_info);
257 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &proc_time);
258 clock_gettime(CLOCK_REALTIME, &clock_time);
263 if (cpu_time_elapsed <= 0)
265 proc_time_elapsed = 1e9 * (proc_time.tv_sec -
last_proc_time.tv_sec)
267 cpu_user_percent = 100.0 * (proc_time_elapsed) / cpu_time_elapsed;
271 cpu_rt_percent = 100.0 * rt_time_elapsed / cpu_time_elapsed;
278 return cpu_rt_percent + cpu_user_percent;
void ERROR_MSG(const std::string &errmsg, Args... args)
int createTask(Task *task, void(*func)(void *), void *arg)
int setPeriod(Task *task, int64_t period)
void shutdown(RT::OS::Task *task)
void sleepTimestep(Task *task)
int initiate(RT::OS::Task *task)
void deleteTask(Task *task)
void sigdebug_handler(int sig, siginfo_t *si, void *)