コード例 #1
0
static void rt_timers_manager(int dummy)
{
	static unsigned long cr0;

	RTIME now;
	struct rt_tasklet_struct *tmr, *timer;
	unsigned long flags;
	int priority, used_fpu;

	while (1) {
		rt_sleep_until((timers_list.next)->firing_time);
		now = timers_manager.resume_time + tuned.timers_tol[0];
// find all the timers to be fired, in priority order
		while (1) {
			used_fpu = 0;
			tmr = timer = &timers_list;
			priority = RT_LOWEST_PRIORITY;
			flags = rt_spin_lock_irqsave(&timers_lock);
			while ((tmr = tmr->next)->firing_time <= now) {
				if (tmr->priority < priority) {
					priority = (timer = tmr)->priority;
				}
			}
			timers_manager.priority = priority;
			rt_spin_unlock_irqrestore(flags, &timers_lock);
			if (timer == &timers_list) {
				break;
			}
			if (!timer->period) {
				flags = rt_spin_lock_irqsave(&timers_lock);
				(timer->next)->prev = timer->prev;
				(timer->prev)->next = timer->next;
				timer->next = timer->prev = timer;
				rt_spin_unlock_irqrestore(flags, &timers_lock);
			} else {
				set_timer_firing_time(timer, timer->firing_time + timer->period);
			}
			if (!timer->task) {
				if (!used_fpu && timer->uses_fpu) {
					used_fpu = 1;
					save_cr0_and_clts(cr0);
					save_fpenv(timers_manager.fpu_reg);
				}
				timer->handler(timer->data);
			} else {
				rt_task_resume(timer->task);
			}
		}
		if (used_fpu) {
			restore_fpenv(timers_manager.fpu_reg);
			restore_cr0(cr0);
		}
// set next timers_manager priority according to the highest priority timer
		asgn_min_prio();
// if no more timers in timers_struct remove timers_manager from tasks list
	}
}
コード例 #2
0
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);
}
コード例 #3
0
RTAI_SYSCALL_MODE void rt_set_timer_firing_time(struct rt_tasklet_struct *timer, RTIME firing_time)
{
	unsigned long flags;
	RT_TASK *timer_manager;

	set_timer_firing_time(timer, firing_time);
	flags = rt_global_save_flags_and_cli();
	if (timers_list[TIMER_CPUID].next == timer && ((timer_manager = &timers_manager[TIMER_CPUID])->state & RT_SCHED_DELAYED) && firing_time < timer_manager->resume_time) {
		timer_manager->resume_time = firing_time;
		rem_timed_task(timer_manager);
		enq_timed_task(timer_manager);
		rt_schedule();
	}
	rt_global_restore_flags(flags);
}
コード例 #4
0
static void rt_timers_manager(long cpuid)
{
	RTIME now;
	RT_TASK *timer_manager;
	struct rt_tasklet_struct *tmr, *timer, *timerl;
	spinlock_t *lock;
	unsigned long flags, timer_tol;
	int priority, used_fpu;

	timer_manager = &timers_manager[LIST_CPUID];
	timerl = &timers_list[LIST_CPUID];
	lock = &timers_lock[LIST_CPUID];
	timer_tol = tuned.timers_tol[LIST_CPUID];

	while (1) {
		int retval;
		retval = rt_sleep_until((timerl->next)->firing_time);
//		now = timer_manager->resume_time + timer_tol;
		now = rt_get_time() + timer_tol;
// find all the timers to be fired, in priority order
		while (1) {
			used_fpu = 0;
			tmr = timer = timerl;
			priority = RT_SCHED_LOWEST_PRIORITY;
			flags = rt_spin_lock_irqsave(lock);
			while ((tmr = tmr->next)->firing_time <= now) {
				if (tmr->priority < priority) {
					priority = (timer = tmr)->priority;
				}
			}
			rt_spin_unlock_irqrestore(flags, lock);
			if (timer == timerl) {
				if (timer_manager->priority > TimersManagerPrio) {
					timer_manager->priority = TimersManagerPrio;
				}
				break;
			}
			timer_manager->priority = priority;
#if 1
			flags = rt_spin_lock_irqsave(lock);
			rem_timer(timer);
			if (timer->period) {
				timer->firing_time += timer->period;
				enq_timer(timer);
			}
			rt_spin_unlock_irqrestore(flags, lock);
#else
			if (!timer->period) {
				flags = rt_spin_lock_irqsave(lock);
				rem_timer(timer);
				rt_spin_unlock_irqrestore(flags, lock);
			} else {
				set_timer_firing_time(timer, timer->firing_time + timer->period);
			}
#endif
	//	if (retval != RTE_TMROVRN) {
			tmr->overrun = 0;
			if (!timer->task) {
				if (!used_fpu && timer->uses_fpu) {
					used_fpu = 1;
					save_fpcr_and_enable_fpu(linux_cr0);
					save_fpenv(timer_manager->fpu_reg);
				}
				timer->handler(timer->data);
			} else {
				rt_task_resume(timer->task);
			}
	//	} else {
	//		tmr->overrun++;
	//	}
		}
		if (used_fpu) {
			restore_fpenv(timer_manager->fpu_reg);
			restore_fpcr(linux_cr0);
		}
// set next timers_manager priority according to the highest priority timer
		asgn_min_prio(LIST_CPUID);
// if no more timers in timers_struct remove timers_manager from tasks list
	}
}