void rt_set_timer_firing_time(struct rt_tasklet_struct *timer, RTIME firing_time) { unsigned long flags; set_timer_firing_time(timer, firing_time); flags = rt_global_save_flags_and_cli(); if (timers_list.next == timer && (timers_manager.state & DELAYED) && firing_time < timers_manager.resume_time) { timers_manager.resume_time = firing_time; rt_rem_timed_task(&timers_manager); rt_enq_timed_task(&timers_manager); RT_SCHEDULE(); } rt_global_restore_flags(flags); }
int rt_insert_timer(struct rt_tasklet_struct *timer, int priority, RTIME firing_time, RTIME period, void (*handler)(unsigned long), unsigned long data, int pid) { unsigned long flags; struct rt_tasklet_struct *tmr; // timer initialization if (!handler) { return -EINVAL; } timer->uses_fpu = 0; timer->priority = priority; timer->firing_time = firing_time; timer->period = period; timer->handler = handler; timer->data = data; if (!pid) { timer->task = 0; } else { (timer->task)->priority = priority; copy_to_user(timer->usptasklet, timer, sizeof(struct rt_tasklet_struct)); } // timer insertion in timers_list tmr = &timers_list; flags = rt_spin_lock_irqsave(&timers_lock); while (firing_time >= (tmr = tmr->next)->firing_time); timer->next = tmr; timer->prev = tmr->prev; (tmr->prev)->next = timer; tmr->prev = timer; rt_spin_unlock_irqrestore(flags, &timers_lock); // timers_manager priority inheritance if (timer->priority < timers_manager.priority) { timers_manager.priority = timer->priority; } // timers_task deadline inheritance flags = rt_global_save_flags_and_cli(); if (timers_list.next == timer && (timers_manager.state & DELAYED) && firing_time < timers_manager.resume_time) { timers_manager.resume_time = firing_time; rt_rem_timed_task(&timers_manager); rt_enq_timed_task(&timers_manager); RT_SCHEDULE(); } rt_global_restore_flags(flags); return 0; }
static inline void rt_exec_signal(RT_TASK *sigtask, RT_TASK *task) { unsigned long flags; flags = rt_global_save_flags_and_cli(); if (sigtask->suspdepth > 0 && !(--sigtask->suspdepth)) { if (task) { sigtask->priority = task->priority; if (!task->pstate++) { rem_ready_task(task); task->state |= RT_SCHED_SIGSUSP; } } sigtask->state &= ~RT_SCHED_SIGSUSP; sigtask->retval = (long)task; enq_ready_task(sigtask); RT_SCHEDULE(sigtask, rtai_cpuid()); } rt_global_restore_flags(flags); }