(toppers-users 2445) TOPPERS/FI4 のバグ

takaya_kakizaki @ gmx.yamaha.com takaya_kakizaki @ gmx.yamaha.com
2006年 6月 13日 (火) 10:29:41 JST


柿崎と申します。
TOPPERS/FI4を評価していて以下のバグを発見しました。

ランデブポートを
タスクA:acp_por
タスクB:cal_por
の順に呼び出すと、cal_porの時点でエラーを吐くというものです。


ソースを追ってみましたら、
rendezvous.c の cal_porの中での記述が


        /*
         *  ランデブ受付待ちが解除されていたら(即ち、上の処理でビットパタ
ーンが
         *  一致していたら)、自タスクをランデブ終了待ちにする。
         *  そうでなければ、自タスクをランデブ呼出し待ち状態にする。
         */
        if (queue != NULL) {
                WINFO_POR winfo;
                RDVCB *rdvcb;
                winfo.msg = msg;
                winfo.msgsz = cmsgsz;
                winfo.rdvno = rdvno;
                winfo.maxrmsz = porcb->porinib->maxrmsz;
                rdvcb = &rdvcb_table[winfo.rdvno % TNUM_RDVNO_HASH];
                wobj_make_wait((WOBJCB *)rdvcb, (WINFO_WOBJ *)&winfo);
                if (wait_complete(tcb)) {
                        dispatch();
                }
                if (winfo.winfo.wercd == E_OK) {
                        ercd = winfo.msgsz;
                } else {
                        ercd = winfo.winfo.wercd;
                }
        } else {


となっていました。
しかし、受付待ちが解除されたら、自タスクは待ち状態に遷移するので
wait_completeの戻り値如何に関わらずdispatchを行う必要があると思うのですが
。

        /*
         *  ランデブ受付待ちが解除されていたら(即ち、上の処理でビットパタ
ーンが
         *  一致していたら)、自タスクをランデブ終了待ちにする。
         *  そうでなければ、自タスクをランデブ呼出し待ち状態にする。
         */
        if (queue != NULL) {
                WINFO_POR winfo;
                RDVCB *rdvcb;
                winfo.msg = msg;
                winfo.msgsz = cmsgsz;
                winfo.rdvno = rdvno;
                winfo.maxrmsz = porcb->porinib->maxrmsz;
                rdvcb = &rdvcb_table[winfo.rdvno % TNUM_RDVNO_HASH];
                wobj_make_wait((WOBJCB *)rdvcb, (WINFO_WOBJ *)&winfo);
        /******    変更後   ************/
                wait_complete(tcb);
                dispatch();
                if (winfo.winfo.wercd == E_OK) {
                        ercd = winfo.msgsz;
                } else {
                        ercd = winfo.winfo.wercd;
                }
        } else {

が、正しいコードではないでしょうか。


もうひとつ、可変長メモリブロックを獲得するときに
待ち状態にはいるとメモリを獲得できなくなります。

SYSCALL ER
get_mpl(ID mplid, UINT blksz, VP *p_blk)
{
        MPLCB   *mplcb;
        WINFO_MPL winfo;
        ER      ercd;

        LOG_GET_MPL_ENTER(mplid, blksz, p_blk);
        CHECK_DISPATCH();

        CHECK_MPLID(mplid);
        mplcb = get_mplcb(mplid);

        t_lock_cpu();
        T_CHECK_OBJECT_EXIST(mplcb);

        if (kmem_allocate(mplcb->free_list, blksz, p_blk)) {
                ercd = E_OK;
        } else {
                wobj_make_wait((WOBJCB *) mplcb, (WINFO_WOBJ *) &winfo);
                dispatch();
                ercd = winfo.winfo.wercd;
                if (ercd == E_OK) {
                        *p_blk = winfo.blk;
                }
        }

        t_unlock_cpu();

     exit:
        LOG_GET_MPL_LEAVE(ercd, p_blk);
        return(ercd);
}

これは変数の初期化忘れですかね。

SYSCALL ER
get_mpl(ID mplid, UINT blksz, VP *p_blk)
{
        MPLCB   *mplcb;
        WINFO_MPL winfo;
        ER      ercd;

        LOG_GET_MPL_ENTER(mplid, blksz, p_blk);
        CHECK_DISPATCH();

        CHECK_MPLID(mplid);
        mplcb = get_mplcb(mplid);

        t_lock_cpu();
        T_CHECK_OBJECT_EXIST(mplcb);

        if (kmem_allocate(mplcb->free_list, blksz, p_blk)) {
                ercd = E_OK;
        } else {
   /*  忘れた? */
       winfo.blksz = blksz;
                wobj_make_wait((WOBJCB *) mplcb, (WINFO_WOBJ *) &winfo);
                dispatch();
                ercd = winfo.winfo.wercd;
                if (ercd == E_OK) {
                        *p_blk = winfo.blk;
                }
        }

        t_unlock_cpu();

     exit:
        LOG_GET_MPL_LEAVE(ercd, p_blk);
        return(ercd);
}

以上、よろしくお願いします。

------------------------
柿崎 貴也
ヤマハ株式会社 サウンドネットワーク事業部
サウンドネット開発部
E-mail: kakizaki @ soundnet.yamaha.co.jp