static __noinline uint32_t __down(semaphore_t *sem, uint32_t wait_state) { 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); local_intr_restore(intr_flag); schedule(); local_intr_save(intr_flag); wait_current_del(&(sem->wait_queue), wait); local_intr_restore(intr_flag); if (wait->wakeup_flags != wait_state) { return wait->wakeup_flags; } return 0; }
__attribute__ ((noinline)) __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 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; }
static int dev_stdin_read(char *buf, size_t len) { int ret = 0; bool intr_flag; local_intr_save(intr_flag); { while(1) { if(ret >= len) break; try_again: if (p_rpos < p_wpos) { char c = stdin_buffer[p_rpos % STDIN_BUFSIZE]; //FIXME kcons_putc(c); *buf ++ = c; p_rpos ++; ret ++; if(p_rpos >= p_wpos) break; } else { wait_t __wait, *wait = &__wait; wait_current_set(wait_queue, wait, WT_KBD); local_intr_restore(intr_flag); schedule(); local_intr_save(intr_flag); wait_current_del(wait_queue, wait); if (wait->wakeup_flags == WT_KBD) { goto try_again; } break; } } } local_intr_restore(intr_flag); return ret; }