RTAI_SYSCALL_MODE unsigned long rt_bits_signal(BITS *bits, int setfun, unsigned long masks) { unsigned long flags, schedmap; RT_TASK *task; QUEUE *q; CHECK_BITS_MAGIC(bits); schedmap = 0; q = &bits->queue; flags = rt_global_save_flags_and_cli(); exec_fun[setfun](bits, masks); masks = bits->mask; while ((q = q->next) != &bits->queue) { task = q->task; if (test_fun[TEST_FUN(task)](bits, TEST_MASK(task))) { dequeue_blocked(task); rem_timed_task(task); if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_SEMAPHORE | RT_SCHED_DELAYED)) == RT_SCHED_READY) { enq_ready_task(task); #ifdef CONFIG_SMP set_bit(task->runnable_on_cpus & 0x1F, &schedmap); #endif } } } RT_SCHEDULE_MAP(schedmap); rt_global_restore_flags(flags); return masks; }
RTAI_SYSCALL_MODE unsigned long rt_bits_reset(BITS *bits, unsigned long mask) { unsigned long flags, schedmap, oldmask; RT_TASK *task; QUEUE *q; CHECK_BITS_MAGIC(bits); schedmap = 0; q = &bits->queue; flags = rt_global_save_flags_and_cli(); oldmask = bits->mask; bits->mask = mask; while ((q = q->next) != &bits->queue) { dequeue_blocked(task = q->task); rem_timed_task(task); if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_SEMAPHORE | RT_SCHED_DELAYED)) == RT_SCHED_READY) { enq_ready_task(task); #ifdef CONFIG_SMP set_bit(task->runnable_on_cpus & 0x1F, &schedmap); #endif } } bits->queue.prev = bits->queue.next = &bits->queue; RT_SCHEDULE_MAP(schedmap); rt_global_restore_flags(flags); return oldmask; }
int rt_bits_delete(BITS *bits) { unsigned long flags, schedmap; RT_TASK *task; QUEUE *q; CHECK_BITS_MAGIC(bits); schedmap = 0; q = &bits->queue; flags = rt_global_save_flags_and_cli(); bits->magic = 0; while ((q = q->next) != &bits->queue && (task = q->task)) { rem_timed_task(task); if (task->state != RT_SCHED_READY && (task->state &= ~(RT_SCHED_SEMAPHORE | RT_SCHED_DELAYED)) == RT_SCHED_READY) { task->blocked_on = RTP_OBJREM; enq_ready_task(task); #ifdef CONFIG_SMP set_bit(task->runnable_on_cpus & 0x1F, &schedmap); #endif } } RT_SCHEDULE_MAP(schedmap); rt_global_restore_flags(flags); return 0; }
RTAI_SYSCALL_MODE 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) { spinlock_t *lock; unsigned long flags, cpuid; RT_TASK *timer_manager; // timer initialization timer->uses_fpu = 0; if (pid >= 0) { if (!handler) { return -EINVAL; } timer->handler = handler; timer->data = data; } else { if (timer->handler != NULL || timer->handler == (void *)1) { timer->handler = (void *)1; timer->data = data; } } timer->priority = priority; REALTIME2COUNT(firing_time) timer->firing_time = firing_time; timer->period = period; if (!pid) { timer->task = 0; timer->cpuid = cpuid = NUM_CPUS > 1 ? rtai_cpuid() : 0; } else { timer->cpuid = cpuid = NUM_CPUS > 1 ? (timer->task)->runnable_on_cpus : 0; (timer->task)->priority = priority; rt_copy_to_user(timer->usptasklet, timer, sizeof(struct rt_usp_tasklet_struct)); } // timer insertion in timers_list flags = rt_spin_lock_irqsave(lock = &timers_lock[LIST_CPUID]); enq_timer(timer); rt_spin_unlock_irqrestore(flags, lock); // timers_manager priority inheritance if (timer->priority < (timer_manager = &timers_manager[LIST_CPUID])->priority) { timer_manager->priority = timer->priority; } // timers_task deadline inheritance flags = rt_global_save_flags_and_cli(); if (timers_list[LIST_CPUID].next == timer && (timer_manager->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); return 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); }
RTAI_SYSCALL_MODE int rt_timer_insert(struct rtdm_timer_struct *timer, int priority, RTIME firing_time, RTIME period, void (*handler)(unsigned long), unsigned long data) { spinlock_t *lock; unsigned long flags, cpuid; RT_TASK *timer_manager; if (!handler) { return -EINVAL; } timer->handler = handler; timer->data = data; timer->priority = priority; timer->firing_time = firing_time; timer->period = period; REALTIME2COUNT(firing_time) timer->cpuid = cpuid = NUM_CPUS > 1 ? rtai_cpuid() : 0; // timer insertion in timers_list flags = rt_spin_lock_irqsave(lock = &timers_lock[LIST_CPUID]); enq_timer(timer); rt_spin_unlock_irqrestore(flags, lock); // timers_manager priority inheritance if (timer->priority < (timer_manager = &timers_manager[LIST_CPUID])->priority) { timer_manager->priority = timer->priority; } // timers_task deadline inheritance flags = rt_global_save_flags_and_cli(); if (timers_list[LIST_CPUID].next == timer && (timer_manager->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); return 0; }