INTERNAL_QUAL int rtos_task_is_self(const RTOS_TASK* task) { RT_TASK* self = rt_buddy(); if (self == 0) return -1; // non-rtai thread. We could try to compare pthreads like in gnulinux ? if ( self == task->rtaitask ) return 1; return 0; }
void *ThreadImplLxrt35::runThread(void *arg) { ThreadImplLxrt35 *self = static_cast<ThreadImplLxrt35*>(arg); if (self->m_rt_start_sync == NULL) { // Technically, this can never happen because this condition is // already checked in the Start() function. But who knows! PRINTF("ERROR: NULL thread start barrier!\n"); } else { self->m_rt_task = rt_task_init(getpid() + pthread_self_rt(), abs(self->m_priority), DEFAULT_STACK_SIZE, 0); if (self->m_rt_task == NULL) { PRINTF("ERROR: Cannot initialize LXRT task %lu!\n", self->m_thread_id); PRINTF(" Probably another thread with the same name already exists.\n"); // Let the thread, which started us, continue! pthread_barrier_wait_rt(self->m_rt_start_sync); } else { if (self->m_priority < 0) { rt_make_hard_real_time(); if (!rt_is_hard_real_time(rt_buddy())) { PRINTF("ERROR: Setting thread %lu to hard real-time failed!\n", self->m_thread_id); } else { // Everything worked as expected, so no message here. } } else { // This is a soft realtime thread, so nothing additional has // to be done here. } pthread_barrier_wait_rt(self->m_rt_start_sync); self->m_thread->runThread(); // Remark: It does not hurt to call this in a soft realtime // thread, so just skip the hard realtime test. rt_make_soft_real_time(); } } return NULL; }
INTERNAL_QUAL int rtos_task_set_scheduler(RTOS_TASK* t, int s) { if ( t->rtaitask == 0 || t->rtaitask != rt_buddy() ) { return -1; } if (rtos_task_check_scheduler(&s) == -1) return -1; if (s == SCHED_LXRT_HARD) rt_make_hard_real_time(); else if ( s == SCHED_LXRT_SOFT) rt_make_soft_real_time(); return 0; }
static inline void send_to_mbx(FILE *fs, struct LOGMSG msg) { RT_TASK *buddy; msg.msg[MAX_MSG_SIZE - 1] = 0; if (++msg.nch >= (MAX_MSG_SIZE - 1)) { msg.nch = MAX_MSG_SIZE - 1; } if (!(buddy = rt_buddy()) || (buddy && !rt_is_hard_real_time(buddy))) { fprintf(stderr, msg.msg); } else { msg.fs = fs; rt_mbx_send_if(logmbx, &msg, sizeof(int) + sizeof(FILE *) + msg.nch); } }
void *ThreadImplLxrt33::runThread(void *arg) { ThreadImplLxrt33 *self = static_cast<ThreadImplLxrt33*>(arg); self->m_rt_task = rt_task_init(getpid() + pthread_self_rt(), abs(self->m_priority), DEFAULT_STACK_SIZE, 0); if (self->m_rt_task == NULL) { PRINTF("ERROR: Cannot initialize LXRT task %lu!\n", self->m_thread_id); PRINTF(" Probably another thread with the same name already exists.\n"); } else { rt_task_use_fpu(self->m_rt_task, 1); if (self->m_priority < 0) { rt_make_hard_real_time(); if (!rt_is_hard_real_time(rt_buddy())) { PRINTF("ERROR: Setting thread %lu to hard real-time failed!\n", self->m_thread_id); } else { // Everything worked as expected, so no message here. } } else { // This is a soft realtime thread, so nothing additional has to // be done here. } self->m_thread->runThread(); rt_make_soft_real_time(); // TODO: Check if this is correct. The RTAI 3.5 and 3.8 // implementations leave this to a call to join(). rt_task_delete(self->m_rt_task); self->m_rt_task = NULL; } return NULL; }
INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK* mytask, NANO_TIME nanosecs ) { if (mytask->rtaitask == 0) return; if (rt_buddy() == mytask->rtaitask) { // do not suspend/resume my own thread // do best effort to change period. rtos_task_set_period(mytask,nanosecs); return; } // other thread is instructing us: if (nanosecs == 0) { // in RTAI, to drop from periodic to non periodic, do a // suspend/resume cycle. rt_task_suspend( mytask->rtaitask ); rt_task_resume( mytask->rtaitask ); } else { // same for the inverse rt_task_suspend( mytask->rtaitask ); rt_task_make_periodic_relative_ns(mytask->rtaitask, 0, nanosecs); } }
void PeriodicThreadImplLxrt38::makePeriodic() { rt_task_make_periodic_relative_ns(rt_buddy(), 0, m_period.toNSec()); }