/* * receive an message from mail box * mbox: mail box * msg: message buffer * timeout: receive's max wait time * <0 -- wait forever; 0 -- no wait; >0 -- wait for timeout ticks * retrun: RERROR on failed, RTIMEOUT on timeout, RAGAIN on busy, ROK on success. */ int mbox_pend(mbox_t *mbox, uint32_t *msg, int timeout) { uint32_t f, len; int ret = RERROR; struct dtask *myself; if(mbox && (mbox->flag & IPC_FLAG_VALID)) { ret = ROK; SYS_FSAVE(f); len = queue_buffer_get(&mbox->buf, msg); SYS_FRESTORE(f); if(len == 0) { if(timeout == 0) ret = RAGAIN; else { SYS_FSAVE(f); myself = current; current->wakeup_cause = RERROR; if(timeout > 0) { assert(current->t_delay.param[0] == TASK_T(current)); assert(!(current->flags & TASK_FLAGS_DELAYING)); ptimer_start(&sysdelay_queue, ¤t->t_delay, timeout); current->flags |= TASK_FLAGS_DELAYING; } #ifdef INCLUDE_JOURNAL journal_ipc_pend((ipc_t *)mbox, timeout); #endif // INCLUDE_JOURNAL task_block(&(mbox->taskq)); SYS_FRESTORE(f); /* at this point, wakeup cause is modified */ switch ((ret = myself->wakeup_cause)) { case ROK: SYS_FSAVE(f); len = queue_buffer_get(&mbox->buf, msg); SYS_FRESTORE(f); if(len <= 0) ret = RERROR; /* double check for length */ break; case RTIMEOUT: case RSIGNAL: default: break; } } } } return ret; }
void k9_task_sleep(unsigned tmout) { uint32 old; old = k9_cpu_intr_dis(); task_block(tmout); k9_cpu_intr_restore(old); }
static int ev_wait(unsigned nwait, struct k9_ev_wait_desc *wait, unsigned tmout) { cur_task->u->blocked->ev->nwait = nwait; cur_task->u->blocked->ev->wait = wait; for ( ; nwait; --nwait, ++wait) { wait->flag = 0; list_insert(wait->list_node, LIST_END(wait->ev->list)); wait->task = cur_task; } task_block(tmout); return (cur_task->u->blocked->rc); }
/*-----------------------------------------------------------------------*/ int task_delay(uint32_t tick) { int ret = RERROR; uint32_t f; if(tick > 0){ SYS_FSAVE(f); assert(current->t_delay.onexpired_func == task_timeout); assert(current->t_delay.param[0] == TASK_T(current)); ret = ptimer_start(&sysdelay_queue, ¤t->t_delay, tick); if(ret == ROK){ current->flags |= TASK_FLAGS_DELAYING; task_block(NULL); } SYS_FRESTORE(f); } return ret; }