ER ext_tsk(void) { ER ercd; LOG_EXT_TSK_ENTER(); CHECK_TSKCTX(); if (t_sense_lock()) { /* * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し * てからタスクを終了する.実装上は,サービスコール内でのCPU * ロックを省略すればよいだけ. */ } else { t_lock_cpu(); } if (disdsp) { /* * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ * チ許可状態にしてからタスクを終了する. */ disdsp = false; } if (!ipmflg) { /* * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す * る. */ t_set_ipm(TIPM_ENAALL); ipmflg = true; } dspflg = true; (void) make_non_runnable(p_runtsk); if (!queue_empty(&(p_runtsk->mutex_queue))) { (void) (*mtxhook_release_all)(p_runtsk); } #ifdef TOPPERS_SUPPORT_OVRHDR ovrtimer_stop(); #endif /* TOPPERS_SUPPORT_OVRHDR */ make_dormant(p_runtsk); if (p_runtsk->actque) { p_runtsk->actque = false; (void) make_active(p_runtsk); } exit_and_dispatch(); ercd = E_SYS; error_exit: LOG_EXT_TSK_LEAVE(ercd); return(ercd); }
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(); }
ER ext_tsk(void) { ER ercd; LOG_EXT_TSK_ENTER(); CHECK_TSKCTX(); if (t_sense_lock()) { /* * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し * てからタスクを終了する.実装上は,サービスコール内でのCPU * ロックを省略すればよいだけ. */ } else { t_lock_cpu(); } if (disdsp) { /* * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ * チ許可状態にしてからタスクを終了する. */ disdsp = false; } if (t_get_ipm() != TIPM_ENAALL) { /* * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す * る. */ t_set_ipm(TIPM_ENAALL); } dspflg = true; (void) make_non_runnable(p_runtsk); make_dormant(p_runtsk); if (p_runtsk->actque) { p_runtsk->actque = false; (void) make_active(p_runtsk); } exit_and_dispatch(); return(E_SYS); error_exit: LOG_EXT_TSK_LEAVE(ercd); return(ercd); }
ER ext_tsk(void) { ER ercd; PCB *t_p_pcb; PCB *my_p_pcb; TCB *p_runtsk; bool_t locked; LOG_EXT_TSK_ENTER(); CHECK_TSKCTX(); /* * CPUロック状態でext_tskが呼ばれた場合は,ロック取得時に割込みを許可 * しない. * ロック取得時に割込みを許可しないのは, 過度状態の場合にロックを取得 * できなかった場合に割込みを許可すると,割込みが入りサスペンド状態と * なってしまうためである. */ locked = t_sense_lock(); retry: if (locked) { my_p_pcb = acquire_tsk_lock_without_preemption_self(); } else { t_lock_cpu(); my_p_pcb = t_acquire_tsk_lock_self_without_runnable_check(); } p_runtsk = my_p_pcb->p_runtsk; /* 再起動時のマイグレーションなし */ if ((p_runtsk->actprc == TPRC_NONE) || (p_runtsk->actprc == my_p_pcb->prcid)) { /* * ディスパッチ禁止状態でext_tskが呼ばれた場合に対応して,ディスパッ * チ許可状態にしてからタスクを終了する. */ my_p_pcb->disdsp = false; /* * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tskが呼ばれ * た場合に対応して,IPMをTIPM_ENAALLにしてからタスクを終了する. */ t_set_ipm(TIPM_ENAALL); my_p_pcb->ipmflg = true; my_p_pcb->dspflg = true; /* * スピンロックを取得している場合は,スピンロックを解除する */ force_unlock_spin(my_p_pcb); (void) make_non_runnable(p_runtsk); make_dormant(p_runtsk); if (p_runtsk->actque) { p_runtsk->actque = false; p_runtsk->actprc = TPRC_NONE; (void) make_active(p_runtsk); } release_tsk_lock(my_p_pcb); exit_and_dispatch(); ercd = E_SYS; } else { /* 移動先のプロセッサのPCBを取得 */ t_p_pcb = get_mp_p_pcb(p_runtsk->actprc); /* 一旦タスクロックを離す */ release_tsk_lock(my_p_pcb); /* * 現在割り付けられているプロセッサと移動先のプロセッサのタスク * ロックを取得 */ if (locked) { acquire_dual_tsk_lock_without_preemption(p_runtsk, p_runtsk->actprc, &my_p_pcb, &t_p_pcb); } else { t_acquire_dual_tsk_lock(p_runtsk, p_runtsk->actprc, &my_p_pcb, &t_p_pcb); } /* * マイグレーション先のプロセッサが変更された場合はリトライ */ if (p_runtsk->actprc != t_p_pcb->prcid) { release_dual_tsk_lock(p_runtsk->p_pcb, t_p_pcb); goto retry; } /* * ここで各カーネル状態を変更するのは,ディスパッチ禁止状態と割込 * み優先度マスク全解除状態でない状態による過度状態の場合に,各カ * ーネル状態を変更してから,ロック取得関数で割込みを許可して割込 * みが入ると,割込みからのリターン時にディスパッチャが呼ばれてし * まい,休止状態となるためである. */ my_p_pcb->disdsp = false; t_set_ipm(TIPM_ENAALL); my_p_pcb->ipmflg = true; my_p_pcb->dspflg = true; force_unlock_spin(my_p_pcb); /* 現在コンテキストを捨ててマイグレーション */ exit_and_migrate(p_runtsk->actprc); ercd = E_SYS; } error_exit: LOG_EXT_TSK_LEAVE(ercd); return(ercd); }
ER ext_tsk(void) { ER ercd; PCB *my_p_pcb; TCB *p_runtsk; LOG_EXT_TSK_ENTER(); CHECK_TSKCTX(); /* * CPUロック状態でext_tskが呼ばれた場合は,ロック取得時に割込みを許可 * しない. * ロック取得時に割込みを許可しないのは, 過度状態の場合にロックを取得 * できなかった場合に割込みを許可すると,割込みが入りサスペンド状態と * なってしまうためである. * ディスパッチ禁止や割込み優先度マスク全解除状態でない場合の過度状態の * 場合は,割込みが入っても割込みの出口でディスパッチャに行かずに戻って * くるため問題ない. */ if (t_sense_lock()) { my_p_pcb = acquire_tsk_lock_without_preemption_self(); } else { t_lock_cpu(); my_p_pcb = t_acquire_tsk_lock_self_without_runnable_check(); } p_runtsk = my_p_pcb->p_runtsk; if (my_p_pcb->disdsp) { /* * ディスパッチ禁止状態でext_tskが呼ばれた場合に対応して,ディスパッ * チ許可状態にしてからタスクを終了する. */ my_p_pcb->disdsp = false; } if (!my_p_pcb->ipmflg) { /* * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tskが呼ばれ * た場合に対応して,IPMをTIPM_ENAALLにしてからタスクを終了する. */ t_set_ipm(TIPM_ENAALL); my_p_pcb->ipmflg = true; } my_p_pcb->dspflg = true; /* * スピンロックを取得している場合は,スピンロックを解除する */ force_unlock_spin(my_p_pcb); /* 再起動時のマイグレーションなし */ if ((p_runtsk->actprc == TPRC_NONE) || (p_runtsk->actprc == my_p_pcb->prcid)) { (void) make_non_runnable(p_runtsk); make_dormant(p_runtsk); if (p_runtsk->actque) { p_runtsk->actque = false; p_runtsk->actprc = TPRC_NONE; (void) make_active(p_runtsk); } release_tsk_lock(my_p_pcb); exit_and_dispatch(); ercd = E_SYS; } else { /* 現在コンテキストを捨ててマイグレーション */ exit_and_migrate(p_runtsk->actprc); ercd = E_SYS; } error_exit: LOG_EXT_TSK_LEAVE(ercd); return(ercd); }