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; }
static inline int tbx_smx_wait_until(TBX *tbx, SEM *smx, RTIME time, RT_TASK *rt_current) { int timed = 0; unsigned long flags; flags = rt_global_save_flags_and_cli(); if (!(smx->count)) { tbx->waiting_nr++; rt_current->blocked_on = &smx->queue; rt_current->resume_time = time; rt_current->state |= (SEMAPHORE | DELAYED); rt_rem_ready_current(rt_current); enqueue_blocked(rt_current, &smx->queue, smx->qtype); rt_enq_timed_task(rt_current); rt_schedule(); if (rt_current->blocked_on) { dequeue_blocked(rt_current); timed = 1; tbx->waiting_nr--; } } else { smx->count = 0; } rt_global_restore_flags(flags); return timed; }
RTAI_SYSCALL_MODE int _rt_bits_wait(BITS *bits, int testfun, unsigned long testmasks, int exitfun, unsigned long exitmasks, unsigned long *resulting_mask, int space) { RT_TASK *rt_current; unsigned long flags, mask = 0; int retval; CHECK_BITS_MAGIC(bits); flags = rt_global_save_flags_and_cli(); if (!test_fun[testfun](bits, testmasks)) { void *retpnt; long bits_test[2]; rt_current = RT_CURRENT; TEST_BUF(rt_current, bits_test); TEST_FUN(rt_current) = testfun; TEST_MASK(rt_current) = testmasks; rt_current->state |= RT_SCHED_SEMAPHORE; rem_ready_current(rt_current); enqueue_blocked(rt_current, &bits->queue, 1); rt_schedule(); if (unlikely((retpnt = rt_current->blocked_on) != NULL)) { if (likely(retpnt != RTP_OBJREM)) { dequeue_blocked(rt_current); retval = RTE_UNBLKD; } else { rt_current->prio_passed_to = NULL; retval = RTE_OBJREM; } goto retmask; } } retval = 0; mask = bits->mask; exec_fun[exitfun](bits, exitmasks); retmask: rt_global_restore_flags(flags); if (resulting_mask) { if (space) { *resulting_mask = mask; } else { rt_copy_to_user(resulting_mask, &mask, sizeof(mask)); } } return retval; }
static inline void tbx_smx_signal(TBX* tbx, SEM *smx) { unsigned long flags; RT_TASK *task; flags = rt_global_save_flags_and_cli(); if ((task = (smx->queue.next)->task)) { tbx->waiting_nr--; dequeue_blocked(task); rt_rem_timed_task(task); if ((task->state &= ~(SEMAPHORE | DELAYED)) == READY) { rt_enq_ready_task(task); rt_schedule(); } } else { smx->count = 1; } rt_global_restore_flags(flags); }