めのん@ひとりプログラミング同好会

このブログはすべてフィクションであり、実在の人物、団体とは一切関係ありません

Zig版ASP3カーネルのcan_actとter_tsk

こんばんは、めのんです!

今夜は違う話題にしようかとも考えたんですけど、これといったネタがなかったのでいつものようにZig版ASP3カーネルです。

前回はact_tskを見ましたので、今回はある意味それと対になるcan_actを見ていくことにします。 定義はact_tskと同じでkernel/task_manage.zigにあります。

///
///  タスク起動要求のキャンセル[NGKI1138]
///
pub fn can_act(tskid: ID) ItronError!c_uint {
    var p_tcb: *TCB = undefined;
    var retval: c_uint = undefined;

    traceLog("canActEnter", .{ tskid });
    errdefer |err| traceLog("canActLeave", .{ err });
    try checkContextTaskUnlock();               //[NGKI1139][NGKI1140]
    if (tskid == TSK_SELF) {
        p_tcb = p_runtsk.?;                     //[NGKI1146]
    }
    else {
        p_tcb = try checkAndGetTCB(tskid);      //[NGKI1141]
    }
    {
        target_impl.lockCpu();
        defer target_impl.unlockCpu();

        retval = p_tcb.flags.actque;            //[NGKI1144]
        p_tcb.flags.actque = 0;                 //[NGKI1144]
    }
    traceLog("canActLeave", .{ retval });
    return retval;
}

can_actというサービスコールは、タスクを休止状態にするんではなくてact_tskをキャンセルするためのものです。 act_tskのキューイング数が1しかないASP3カーネルではあまり使いどころはないかもしれませんね。 でもまったく無意味かというとそんなことはなくて、休止状態のタスクに対して呼び出したときなんかは意味があります。

ざっと見た感じではcan_actの内容はZigを学ぶ上では見所はとくになさそうですね。

続いてter_tskも見ていきます。 定義はkernel/task_term.zigにあります。

///
///  タスクの強制終了[NGKI1170]
///
pub fn ter_tsk(tskid : ID) ItronError!void {
    traceLog("terTskEnter", .{ tskid });
    errdefer |err| traceLog("terTskLeave", .{ err });
    try checkContextTaskUnlock();               //[NGKI1171][NGKI1172]
    const p_tcb = try checkAndGetTCB(tskid);    //[NGKI1173]
    try checkIllegalUse(p_tcb != p_runtsk);     //[NGKI1176]
    {
        target_impl.lockCpu();
        defer target_impl.unlockCpu();

        if (isDormant(p_tcb.tstat)) {           //[NGKI1177]
            return ItronError.ObjectStateError;
        }
        else {
            task_terminate(p_tcb);              //[NGKI3450]
            if (p_runtsk != p_schedtsk) {
                target_impl.dispatch();
            }
        }
    }
    traceLog("terTskLeave", .{ null });
}

ter_tskはタスクを休止状態に遷移させるサービスコールです。

カーネルを読み解く上では結構重要なサービスコールなんですが、Zigを学ぶという観点では見所はとくになさそうです。

振り返ってみるとact_tskがひとつの山だったのかもしれませんね。 act_tskに表れたZigの特徴を押さえておけば、あとは同じような言語仕様しか登場しません。

次回は待ち状態に遷移させるサービスコールを何かひとつ見ていきたいと思います。 slp_tskかdly_tskを考えていますが、予定は変わるかもしれませんよ。

それでは!!