JSP_L1_CODE SYSCALL ER iras_tex(ID tskid, TEXPTN rasptn) { TCB *tcb; ER ercd; LOG_IRAS_TEX_ENTER(tskid, rasptn); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); CHECK_PAR(rasptn != 0); tcb = get_tcb(tskid); i_lock_cpu(); if (TSTAT_DORMANT(tcb->tstat) || tcb->tinib->texrtn == NULL) { ercd = E_OBJ; } else { tcb->texptn |= rasptn; if (tcb == runtsk && runtsk->enatex) { reqflg = TRUE; } ercd = E_OK; } i_unlock_cpu(); exit: LOG_IRAS_TEX_LEAVE(ercd); return(ercd); }
SYSCALL ER iset_flg(ID flgid, FLGPTN setptn) { FLGCB *flgcb; TCB *tcb; WINFO_FLG *winfo; ER ercd; LOG_ISET_FLG_ENTER(flgid, setptn); CHECK_INTCTX_UNL(); CHECK_FLGID(flgid); flgcb = get_flgcb(flgid); i_lock_cpu(); flgcb->flgptn |= setptn; if (!(queue_empty(&(flgcb->wait_queue)))) { tcb = (TCB *)(flgcb->wait_queue.next); winfo = (WINFO_FLG *)(tcb->winfo); if (eventflag_cond(flgcb, winfo->waiptn, winfo->wfmode, &(winfo->flgptn))) { queue_delete(&(tcb->task_queue)); if (wait_complete(tcb)) { reqflg = TRUE; } } } ercd = E_OK; i_unlock_cpu(); exit: LOG_ISET_FLG_LEAVE(ercd); return(ercd); }
ER irot_rdq(PRI tskpri) { QUEUE *p_queue; ER ercd; LOG_IROT_RDQ_ENTER(tskpri); CHECK_INTCTX_UNL(); CHECK_TPRI(tskpri); i_lock_cpu(); p_queue = &(ready_queue[INT_PRIORITY(tskpri)]); if (queue_empty(p_queue)) { ercd = E_OK; } else if ((((TCB *)(p_queue->p_next))->p_tinib->tskatr & TA_RSTR) != 0U) { ercd = E_NOSPT; } else { if (rotate_ready_queue(p_queue)) { reqflg = true; } ercd = E_OK; } i_unlock_cpu(); error_exit: LOG_IROT_RDQ_LEAVE(ercd); return(ercd); }
ER imrot_rdq(PRI tskpri, ID prcid) { ER ercd; PCB *p_pcb; PCB *my_p_pcb; LOG_IMROT_RDQ_ENTER(tskpri, prcid); CHECK_INTCTX_UNL(); CHECK_TPRI(tskpri); CHECK_PRCID(prcid); i_lock_cpu(); p_pcb = i_acquire_tsk_lock_prcid(prcid); if (rotate_ready_queue(INT_PRIORITY(tskpri), p_pcb)) { my_p_pcb = get_my_p_pcb(); my_p_pcb->reqflg = dispatch_request(p_pcb) ? true : my_p_pcb->reqflg; } ercd = E_OK; release_tsk_lock(p_pcb); i_unlock_cpu(); error_exit: LOG_IMROT_RDQ_LEAVE(ercd); return(ercd); }
ER irel_wai(ID tskid) { TCB *p_tcb; ER ercd; LOG_IREL_WAI_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else if (!TSTAT_WAITING(p_tcb->tstat)) { ercd = E_OBJ; } else { if (wait_release(p_tcb)) { reqflg = true; } ercd = E_OK; } i_unlock_cpu(); error_exit: LOG_IREL_WAI_LEAVE(ercd); return(ercd); }
ER ista_ovr(ID tskid, OVRTIM ovrtim) { TCB *p_tcb; ER ercd; LOG_ISTA_OVR_ENTER(tskid, ovrtim); CHECK_INTCTX_UNL(); CHECK_OBJ(ovrinib.ovrhdr != NULL); CHECK_TSKID(tskid); CHECK_PAR(0U < ovrtim && ovrtim <= TMAX_OVRTIM); p_tcb = get_tcb(tskid); i_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else { p_tcb->leftotm = ovrtim; ercd = E_OK; } i_unlock_cpu(); error_exit: LOG_ISTA_OVR_LEAVE(ercd); return(ercd); }
SYSCALL ER iwup_tsk(ID tskid) { TCB *tcb; UINT tstat; ER ercd; LOG_IWUP_TSK_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); tcb = get_tcb(tskid); i_lock_cpu(); if (TSTAT_DORMANT(tstat = tcb->tstat)) { ercd = E_OBJ; } else if ((tstat & TS_WAIT_SLEEP) != 0) { if (wait_complete(tcb)) { reqflg = TRUE; } ercd = E_OK; } else if (!(tcb->wupcnt)) { tcb->wupcnt = TRUE; ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); exit: LOG_IWUP_TSK_LEAVE(ercd); return(ercd); }
SYSCALL ER iact_tsk(ID tskid) { TCB *tcb; ER ercd; LOG_IACT_TSK_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); tcb = get_tcb(tskid); i_lock_cpu(); if (TSTAT_DORMANT(tcb->tstat)) { if (make_active(tcb)) { reqflg = TRUE; } ercd = E_OK; } else if (!(tcb->actcnt)) { tcb->actcnt = TRUE; ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); exit: LOG_IACT_TSK_LEAVE(ercd); return(ercd); }
ER istp_alm(ID almid) { ALMCB *p_almcb; ER ercd; LOG_ISTP_ALM_ENTER(almid); CHECK_INTCTX_UNL(); CHECK_ALMID(almid); p_almcb = get_almcb(almid); i_lock_cpu(); if (p_almcb->p_alminib->almatr == TA_NOEXS) { ercd = E_NOEXS; } else if (p_almcb->almsta) { p_almcb->almsta = false; tmevtb_dequeue(&(p_almcb->tmevtb)); } ercd = E_OK; i_unlock_cpu(); error_exit: LOG_ISTP_ALM_LEAVE(ercd); return(ercd); }
ER iena_wai(ID tskid) { TCB *p_tcb; ER ercd; LOG_IENA_WAI_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else if (TSTAT_DORMANT(p_tcb->tstat) || !(p_tcb->waifbd)) { ercd = E_OBJ; } else { p_tcb->waifbd = false; ercd = E_OK; } i_unlock_cpu(); error_exit: LOG_IENA_WAI_LEAVE(ercd); return(ercd); }
ER ipsnd_dtq(ID dtqid, intptr_t data) { DTQCB *p_dtqcb; bool_t reqdsp; ER ercd; LOG_IPSND_DTQ_ENTER(dtqid, data); CHECK_INTCTX_UNL(); CHECK_DTQID(dtqid); p_dtqcb = get_dtqcb(dtqid); i_lock_cpu(); if (send_data(p_dtqcb, data, &reqdsp)) { if (reqdsp) { reqflg = true; } ercd = E_OK; } else { ercd = E_TMOUT; } i_unlock_cpu(); error_exit: LOG_IPSND_DTQ_LEAVE(ercd); return(ercd); }
ER ista_alm(ID almid, RELTIM almtim) { ALMCB *p_almcb; ER ercd; LOG_ISTA_ALM_ENTER(almid, almtim); CHECK_INTCTX_UNL(); CHECK_ALMID(almid); CHECK_PAR(almtim <= TMAX_RELTIM); p_almcb = get_almcb(almid); i_lock_cpu(); if (p_almcb->p_alminib->almatr == TA_NOEXS) { ercd = E_NOEXS; } else if (p_almcb->almsta) { tmevtb_dequeue(&(p_almcb->tmevtb)); } else { p_almcb->almsta = true; } tmevtb_enqueue(&(p_almcb->tmevtb), almtim, (CBACK) call_almhdr, (void *) p_almcb); ercd = E_OK; i_unlock_cpu(); error_exit: LOG_ISTA_ALM_LEAVE(ercd); return(ercd); }
ER idis_wai(ID tskid) { TCB *p_tcb; ER ercd; LOG_IDIS_WAI_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else if (p_tcb->waifbd) { ercd = E_QOVR; } else if (i_sense_texmask(p_tcb)) { p_tcb->waifbd = true; ercd = E_OK; } else { ercd = E_OBJ; } i_unlock_cpu(); error_exit: LOG_IDIS_WAI_LEAVE(ercd); return(ercd); }
ER iact_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_IACT_TSK_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (TSTAT_DORMANT(p_tcb->tstat)) { if (make_active(p_tcb)) { reqflg = true; } ercd = E_OK; } else if (!(p_tcb->actque)) { p_tcb->actque = true; ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); error_exit: LOG_IACT_TSK_LEAVE(ercd); return(ercd); }
void call_cychdr(CYCCB *p_cyccb) { PRI saved_ipm; /* * 次回の起動のためのタイムイベントブロックを登録する. * * 同じタイムティックで周期ハンドラを再度起動すべき場合には,この * 関数からsignal_timeに戻った後に,再度この関数が呼ばれることにな * る. */ tmevtb_enqueue_cyc(p_cyccb, p_cyccb->evttim + p_cyccb->p_cycinib->cyctim); /* * 周期ハンドラを,CPUロック解除状態で呼び出す. */ saved_ipm = i_get_ipm(); i_unlock_cpu(); LOG_CYC_ENTER(p_cyccb); (*((CYCHDR)(p_cyccb->p_cycinib->cychdr)))(p_cyccb->p_cycinib->exinf); LOG_CYC_LEAVE(p_cyccb); if (!i_sense_lock()) { i_lock_cpu(); } i_set_ipm(saved_ipm); }
void call_almhdr(ALMCB *p_almcb) { PRI saved_ipm; /* * アラームハンドラを停止状態にする. */ p_almcb->almsta = false; /* * アラームハンドラを,CPUロック解除状態で呼び出す. */ saved_ipm = i_get_ipm(); i_unlock_cpu(); LOG_ALM_ENTER(p_almcb); (*((ALMHDR)(p_almcb->p_alminib->almhdr)))(p_almcb->p_alminib->exinf); LOG_ALM_LEAVE(p_almcb); if (!i_sense_lock()) { i_lock_cpu(); } i_set_ipm(saved_ipm); }
ER iact_tsk(ID tskid) { ER ercd; uint_t ipri; LOG_IACT_TSK_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); ipri = get_ipri(tskid); i_lock_cpu(); if (test_dormant(ipri)) { if(make_active(ipri)) { reqflg = true; } ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); error_exit: LOG_IACT_TSK_LEAVE(ercd); return(ercd); }
ER ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri) { PDQCB *p_pdqcb; bool_t reqdsp; ER ercd; LOG_IPSND_PDQ_ENTER(pdqid, data, datapri); CHECK_INTCTX_UNL(); CHECK_PDQID(pdqid); p_pdqcb = get_pdqcb(pdqid); CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri); i_lock_cpu(); if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) { ercd = E_NOEXS; } else if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) { if (reqdsp) { reqflg = true; } ercd = E_OK; } else { ercd = E_TMOUT; } i_unlock_cpu(); error_exit: LOG_IPSND_PDQ_LEAVE(ercd); return(ercd); }
SYSCALL ER isig_sem(ID semid) { SEMCB *semcb; TCB *tcb; ER ercd; LOG_ISIG_SEM_ENTER(semid); CHECK_INTCTX_UNL(); CHECK_SEMID(semid); semcb = get_semcb(semid); i_lock_cpu(); if (!queue_empty(&(semcb->wait_queue))) { tcb = (TCB *) queue_delete_next(&(semcb->wait_queue)); if (wait_complete(tcb)) { reqflg = TRUE; } ercd = E_OK; } else if (semcb->semcnt < semcb->seminib->maxsem) { semcb->semcnt += 1; ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); exit: LOG_ISIG_SEM_LEAVE(ercd); return(ercd); }
ER iwup_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_IWUP_TSK_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else if (TSTAT_WAIT_SLP(p_tcb->tstat)) { if (wait_complete(p_tcb)) { reqflg = true; } ercd = E_OK; } else if (!(p_tcb->wupque)) { p_tcb->wupque = true; ercd = E_OK; } else { ercd = E_QOVR; } i_unlock_cpu(); error_exit: LOG_IWUP_TSK_LEAVE(ercd); return(ercd); }
SYSCALL ER irel_wai(ID tskid) { TCB *tcb; ER ercd; LOG_IREL_WAI_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_TSKID(tskid); tcb = get_tcb(tskid); i_lock_cpu(); if (!(TSTAT_WAITING(tcb->tstat))) { ercd = E_OBJ; } else { if (wait_release(tcb)) { reqflg = TRUE; } ercd = E_OK; } i_unlock_cpu(); exit: LOG_IREL_WAI_LEAVE(ercd); return(ercd); }
ER istp_ovr(ID tskid) { TCB *p_tcb; ER ercd; LOG_ISTP_OVR_ENTER(tskid); CHECK_INTCTX_UNL(); CHECK_OBJ(ovrinib.ovrhdr != NULL); CHECK_TSKID(tskid); p_tcb = get_tcb(tskid); i_lock_cpu(); if (p_tcb->p_tinib->tskatr == TA_NOEXS) { ercd = E_NOEXS; } else { p_tcb->leftotm = 0U; ercd = E_OK; } i_unlock_cpu(); error_exit: LOG_ISTP_OVR_LEAVE(ercd); return(ercd); }
void signal_time(void) { TMEVTB *p_tmevtb; PCB *my_p_pcb; TEVTCB *my_p_tevtcb; assert(sense_context()); assert(!i_sense_lock()); i_lock_cpu(); my_p_pcb = i_acquire_tsk_lock_self(); my_p_tevtcb = my_p_pcb->p_tevtcb; /* * current_timeを更新する. */ my_p_tevtcb->current_time = my_p_tevtcb->next_time; /* * next_time,next_subtimeを更新する. */ #if TIC_DENO == 1U my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME; #else /* TIC_DENO == 1U */ my_p_tevtcb->next_subtime += TIC_NUME % TIC_DENO; my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME / TIC_DENO; if (my_p_tevtcb->next_subtime >= TIC_DENO) { my_p_tevtcb->next_subtime -= TIC_DENO; my_p_tevtcb->next_time += 1U; } #endif /* TIC_DENO == 1U */ /* * curent_timeよりイベント発生時刻の早い(または同じ)タイムイベン * トを,タイムイベントヒープから削除し,コールバック関数を呼び出 * す. */ while ((my_p_tevtcb->last_index) > 0 && EVTTIM_LE(my_p_tevtcb, TMEVT_NODE(my_p_tevtcb, 1).time, my_p_tevtcb->current_time)) { p_tmevtb = TMEVT_NODE(my_p_tevtcb, 1).p_tmevtb; tmevtb_delete_top(my_p_tevtcb); (*(p_tmevtb->callback))(p_tmevtb->arg); } /* * min_timeを更新する. */ my_p_tevtcb->min_time = my_p_tevtcb->current_time; release_tsk_lock(my_p_pcb); i_unlock_cpu(); }
SYSCALL void ext_tsk(void) { LOG_EXT_TSK_ENTER(); #ifdef ACTIVATED_STACK_SIZE /* * create_context と activate_context で,使用中のスタック領 * 域を破壊しないように,スタック上にダミー領域を確保する. */ (void) alloca(ACTIVATED_STACK_SIZE); #endif /* ACTIVATED_STACK_SIZE */ if (sense_context()) { /* * 非タスクコンテキストから ext_tsk が呼ばれた場合, * システムログにエラーを記録し,そのまま実行を続ける * が, 動作は保証されない. */ syslog_0(LOG_EMERG, "ext_tsk is called from non-task contexts."); } if (sense_lock()) { /* * CPUロック状態で ext_tsk が呼ばれた場合は,CPUロック * を解除してからタスクを終了する.実装上は,サービス * コール内でのCPUロックを省略すればよいだけ. */ syslog_0(LOG_WARNING, "ext_tsk is called from CPU locked state."); } else { if (sense_context()) { i_lock_cpu(); } else { t_lock_cpu(); } } if (!(enadsp)) { /* * ディスパッチ禁止状態で ext_tsk が呼ばれた場合は, * ディスパッチ許可状態にしてからタスクを終了する. */ syslog_0(LOG_WARNING, "ext_tsk is called from dispatch disabled state."); enadsp = TRUE; } exit_task(); }
void wait_tmout_ok(TCB *p_tcb) { p_tcb->p_winfo->wercd = E_OK; if (make_non_wait(p_tcb)) { reqflg = true; } /* * ここで優先度の高い割込みを受け付ける. */ i_unlock_cpu(); i_lock_cpu(); }
void wait_tmout(TCB *p_tcb) { wait_dequeue_wobj(p_tcb); p_tcb->p_winfo->wercd = E_TMOUT; if (make_non_wait(p_tcb)) { reqflg = true; } /* * ここで優先度の高い割込みを受け付ける. */ i_unlock_cpu(); i_lock_cpu(); }
ER iset_flg(ID flgid, FLGPTN setptn) { FLGCB *p_flgcb; QUEUE *p_queue; TCB *p_tcb; WINFO_FLG *p_winfo_flg; ER ercd; PCB *p_pcb; LOG_ISET_FLG_ENTER(flgid, setptn); CHECK_INTCTX_UNL(); CHECK_FLGID(flgid); p_flgcb = get_flgcb(flgid); i_lock_cpu(); i_acquire_obj_lock(&GET_OBJLOCK(p_flgcb)); p_flgcb->flgptn |= setptn; p_queue = p_flgcb->wait_queue.p_next; while (p_queue != &(p_flgcb->wait_queue)) { p_tcb = (TCB *) p_queue; /* フラグのセットを非破壊コードにできないため,リトライしない */ p_pcb = acquire_nested_tsk_lock_without_preemption(p_tcb); p_queue = p_queue->p_next; p_winfo_flg = (WINFO_FLG *)(&(p_tcb->winfo_obj)); if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn, p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) { queue_delete(&(p_tcb->task_queue)); if (wait_complete(p_tcb)) { if (dispatch_request(p_pcb)){ (get_my_p_pcb())->reqflg = true; } } if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) { release_nested_tsk_lock(p_pcb); break; } } release_nested_tsk_lock(p_pcb); } ercd = E_OK; release_obj_lock(&GET_OBJLOCK(p_flgcb)); i_unlock_cpu(); error_exit: LOG_ISET_FLG_LEAVE(ercd); return(ercd); }
void signal_time(void) { TMEVTB *p_tmevtb; assert(sense_context()); assert(!i_sense_lock()); i_lock_cpu(); /* * update current time */ current_time = next_time; /* * update next_time and next_sub time */ #if TIC_DENO == 1U next_time = current_time + TIC_NUME; #else /* TIC_DENO == 1U */ next_subtime += TIC_NUME % TIC_DENO; next_time = current_time + TIC_NUME / TIC_DENO; if (next_subtime >= TIC_DENO) { next_subtime -= TIC_DENO; next_time += 1U; } #endif /* TIC_DENO == 1U */ /* * if current time is not earlier than the earliest time event in time * event heap, it means a time event shall happen */ while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) { p_tmevtb = TMEVT_NODE(1).p_tmevtb; tmevtb_delete_top(); (*(p_tmevtb->callback))(p_tmevtb->arg); } /* * update min time */ min_time = current_time; i_unlock_cpu(); }
ER iget_tid(ID *p_tskid) { ER ercd; LOG_IGET_TID_ENTER(p_tskid); CHECK_INTCTX_UNL(); i_lock_cpu(); *p_tskid = (p_runtsk == NULL) ? TSK_NONE : TSKID(p_runtsk); ercd = E_OK; i_unlock_cpu(); error_exit: LOG_IGET_TID_LEAVE(ercd, *p_tskid); return(ercd); }
ER iloc_cpu(void) { ER ercd; LOG_ILOC_CPU_ENTER(); CHECK_INTCTX(); if (!i_sense_lock()) { i_lock_cpu(); } ercd = E_OK; error_exit: LOG_ILOC_CPU_LEAVE(ercd); return(ercd); }