static __noinline uint32_t __down(semaphore_t *sem, uint32_t wait_state, timer_t *timer) { assert(sem->valid); bool intr_flag; local_intr_save(intr_flag); if (sem->value > 0) { sem->value --; local_intr_restore(intr_flag); return 0; } wait_t __wait, *wait = &__wait; wait_current_set(&(sem->wait_queue), wait, wait_state); ipc_add_timer(timer); local_intr_restore(intr_flag); schedule(); local_intr_save(intr_flag); ipc_del_timer(timer); wait_current_del(&(sem->wait_queue), wait); local_intr_restore(intr_flag); if (wait->wakeup_flags != wait_state) { return wait->wakeup_flags; } return 0; }
static int recv_event(int *pid_store, int *event_store, timer_t *timer) { bool intr_flag; local_intr_save(intr_flag); wait_queue_t *wait_queue = &(current->event_box.wait_queue); if (wait_queue_empty(wait_queue)) { current->state = PROC_SLEEPING; current->wait_state = WT_EVENT_RECV; ipc_add_timer(timer); local_intr_restore(intr_flag); schedule(); local_intr_save(intr_flag); ipc_del_timer(timer); } int ret = -1; wait_t *wait; if ((wait = wait_queue_first(wait_queue)) != NULL) { struct proc_struct *proc = wait->proc; *pid_store = proc->pid, *event_store = proc->event_box.event, ret = 0; wakeup_wait(wait_queue, wait, WT_EVENT_SEND, 1); } local_intr_restore(intr_flag); return ret; }
__attribute__ ((noinline)) __down(semaphore_t * sem, uint32_t wait_state, timer_t * timer) { assert(sem->valid); bool intr_flag; spin_lock_irqsave(&sem->lock, intr_flag); if (sem->value > 0) { sem->value--; spin_unlock_irqrestore(&sem->lock, intr_flag); return 0; } wait_t __wait, *wait = &__wait; wait_current_set(&(sem->wait_queue), wait, wait_state); ipc_add_timer(timer); spin_unlock_irqrestore(&sem->lock, intr_flag); schedule(); spin_lock_irqsave(&sem->lock, intr_flag); ipc_del_timer(timer); wait_current_del(&(sem->wait_queue), wait); spin_unlock_irqrestore(&sem->lock, intr_flag); if (wait->wakeup_flags != wait_state) { return wait->wakeup_flags; } return 0; }
static uint32_t send_event(struct proc_struct *proc, timer_t *timer) { bool intr_flag; local_intr_save(intr_flag); wait_t __wait, *wait = &__wait; wait_queue_t *wait_queue = &(proc->event_box.wait_queue); wait_current_set(wait_queue, wait, WT_EVENT_SEND); ipc_add_timer(timer); local_intr_restore(intr_flag); schedule(); local_intr_save(intr_flag); ipc_del_timer(timer); wait_current_del(wait_queue, wait); local_intr_restore(intr_flag); if (wait->wakeup_flags != WT_EVENT_SEND) { return wait->wakeup_flags; } return 0; }