next up previous contents index
Next: KLICの基本的な動作 Up: ゴールレコード Previous: 実行可能状態

  
中断状態

 

中断状態にあるときのゴールは、第2.10章 ([*]ページ)に 示すような構造になっている。この図に表われる構造、およびそれらに アクセスするためのマクロ群はsusp.hに記述されている。


  
Figure 2.10: 中断を表現するデータ構造
\begin{figure}\begin{center}
\epsfile{file=suspstruct.eps,width=.8\textwidth}
\end{center}\end{figure}

まず、中断要因になっている純粋未定義変数を、susprecなる 構造を指すようにセットする。このsusprec の先頭は、この未定義変数を 指させるようにする。つまり、中断要因変数と、susprec 先頭とは 二重ループになっている。このsusprecの2ワード目以降は、hookなる 構造になっている。このhook構造に中断中のgoalrec構造体がぶらさがる。 この構造を以下では中断構造 と呼ぶ。

また、中断時のゴールレコード(goalrec)の先頭(next フィールド)には、 そのゴールの優先度がINTタグ付きで格納されている。ゴールが再開可能になった時 には、このfieldで示される優先度のゴールキューに格納される。

struct hook {
  struct hook *next;
  union goal_or_consumer {
    long l;
    struct goalrec *g;
    struct consumer_object *o;
  } u;
};

struct susprec {
  q backpt;
  union {
    struct hook first_hook;
    long l;
  } u;
};

ひとつの未定義変数について、複数個のゴールが中断する場合には、このhookのnext フィールドにhook構造体が線型リストになる。susprec構造体に含まれるhook構造体も 含めたhook構造体のリストは、中断原因を同じくするhook構造体同士で環状の リストになる。つまり、末尾のhook構造体のnextは、susprecに含まれているhook 構造体のhook部分を指す。典型的には、1つのゴールしか 含まれない場合には図2.11で示すような形状になる。


  
Figure 2.11: 単一ゴールの際の中断構造
\begin{figure}\begin{center}
\epsfile{file=single-susp.eps,width=.4\textwidth}
\end{center}\end{figure}

これまでの図で「ゴール」がぶら下っている部分には、cunsumer objectが 来ることがある。このconsumer objectの構造は、data objectの構造と類似であり、 「通常のKL1のデータ」部分に出現するか、「中断ゴール群」のなかに出現するか、 だけが違っている。

ぶらさがっているのがゴールなのか、consumer なのかは、実行時に、 hook構造体のgoal/consumerへのポインタを含む2ワード目 (つまり、hook.u.l)のタグ部で判定される。

また、1つのゴールが複数の中断要因をOR待ちする、 いわゆる「多重待ち」の場合も基本的に構造は同じである。 すなわち、ゴールは一般的に複数のhook構造体より指されることがある。 図2.10中の「多重待ちゴール」に多重待ちをしている ゴールの例を挙げる。

 

ただし、多重待ちしているゴールがそのうちのつの要因が具体化されたため、 再開可能になることはあり、その場合には他の要因をしめす変数からは hook構造体を経由して指されたままになっている。 このような状況の時に、再度、他の要因の具体化のため、1つのゴールに対して、 複数回「再開」処理がなされることを防ぐためにはgoalrecのnextフィールドの タグ部分を参照すれば良い。すなわち、中断中はこのタグはINTタグが付けられている が、再開後には、通常の(goalrecを指す)ポインタとされ、INTタグは解除される。

これらの構造をアクセスするためにinclude/klic/susp.h 内で定義されているマクロ について以下で概説する。

is_consumer_hook(hook):
hookがconsumerであれば真、 goalならば偽。

tag_consumer_hook(hook):
hook にconsumerタグを付ける。

untag_consumer_hook(hook):
hookのconsumerタグを取りさる。

suspp(x):
x を(struct susprec *)にcastする。

allocnewsusp(var, srec):
1ワードセル1つ、およびsusprecを割りつけ、中断構造を作り、 varに指させる。新しいsusprecはsrecより指すようにする。

makenewsusp(var,srec,allocp):
1ワードセル1つ、およびsusprecを割りつけ、中断構造を作り、 varに指させる。新しいsusprecはsrecより指すようにする。allocpは ヒープトップである。

allochook(oldhook,newhook):
newhookとして新しいhook構造体 を割りつけ、oldhookの直後に指しこむ。

addhook(olddhook,newhook,allocp:
newhookとして新しいhook構造体 を割りつけ、oldhookの直後に指しこむ。



Sekita Daigo
1998-05-18