(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