Mercurial > hg > Papers > 2021 > anatofuz-master
changeset 103:63801f42ade3
update
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 06 Feb 2021 11:19:45 +0900 |
parents | 9f5c21b218af |
children | 46494d9aafb9 |
files | paper/chapter/04-interface.tex paper/master_paper.pdf paper/src/errorNotDef.sh paper/src/pickupAfter.cbc paper/src/pickupBefore.cbc |
diffstat | 5 files changed, 62 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/chapter/04-interface.tex Sat Feb 06 10:34:02 2021 +0900 +++ b/paper/chapter/04-interface.tex Sat Feb 06 11:19:45 2021 +0900 @@ -231,6 +231,7 @@ CodeGearの名前につけられるImplの名前は、GearsOSのシステムがCodeGearの識別に使うメタな情報と言える。 ユーザーレベルではInterfaceのAPIと同じ名前のCodeGearを実装できると、GearsOSのメタなCodeGearの処理と分離可能である。 この為Perlスクリプトで、InterfaceのImplementの場合はCodeGearの名前を自動で変換する機能を実装した。 +ここで変換するCodeGearの名前は、 CodeGearの定義部分と、継続で渡すCodeGearの名前の部分である。 generate\_stub.plはソースコードの情報を読み取るフェーズと、変換した情報を書き込むフェーズに別けられる。 まずは読み取りの際の処理をソースコード\ref{src:replaceCodeGearName1}に示す。 @@ -246,8 +247,20 @@ この際に書き込むCodeGearの名前は、定義のCodeGear名を正規表現でキャプチャし、変数\texttt{\$currentCodeGearName}に代入している。(5行目) 読み込み時に作製した、名前の変更があることを保存する連想配列\texttt{\$replaceCodeGearNames}に、今書き込もうとしているCodeGearの名前を問い合わせる。 連想配列側にCodeGearの名前に対応する値があった場合は書き換え対象なので、 \texttt{\$currentCodeGearName}を、ソースコード\ref{src:replaceCodeGearName1}で作製したCodeGearの名前に変換する。 +\lstinputlisting[label=src:replaceCodeGearName2, caption=CodeGearの名前の変更]{src/replaceCodeGearName2.pl} -\lstinputlisting[label=src:replaceCodeGearName2, caption=CodeGearの名前の変更]{src/replaceCodeGearName2.pl} +実際に変換される様子を見る。 +ソースコード\ref{src:pickupBefore}は、 Phils Interfaceの実装のソースコードの一部である。 +Phils Interfaceにあるpickup\_lforkと、 eatingのCodeGearの定義をしている。 +3行目ではcheckAndSetに継続として、 pickup\_rforkとeatingを渡している。 +これらはそれぞれPhils Interfceに定義があるCodeGearの名前であり、 このファイル中で実装している。 + +\lstinputlisting[label=src:pickupBefore, caption=PhilsInterfaceの実装]{src/pickupBefore.cbc} + +変換された結果をソースコード\ref{src:pickupAfter}に示す。 +まずCodeGearの宣言時に名前の末尾に実装の型名であるPhilsImplがついている。 +Gearefマクロに変換されている為見づらいが、 6行目、7行目でenumの定義に変換されてcontextに書き込まれているのが解る。 +\lstinputlisting[label=src:pickupAfter, caption=変換されたPhilsInterfaceの実装]{src/pickupAfter.cbc} \section{GearsCbCのInterfaceの実装時の問題} @@ -424,6 +437,10 @@ 呼び出し元のInterfaceの情報パースした結果、ヘッダファイルにAPIの定義がなかった場合は11行目の\texttt{unless}に処理が落ち、 エラー終了する。 これによってInterface呼び出しの問題が、 Perlスクリプトによって変換する前に検知可能になった。 +ソースコード\ref{src:errNotDef}の例では、Phils Interfaceの実装時にeating CodeGearの実装を忘れた際のエラーである。 +CMakeがエラーを検知し、ビルドが停止するために、 GearsOSの拡張構文レベルでのエラー検知が実現できている。 +\lstinputlisting[label=src:errNotDef, caption=未実装のInterfaceのAPIがあることを知らせるエラー]{src/errorNotDef.sh} + \section{par goto のInterface経由の呼び出しの対応} 従来のpar gotoではInterface経由の呼び出しは想定していなかった。 par gotoで継続したいCodeGearはInterfaceのAPIとしてではなく、 Interfaceを入力として受け取るCodeGearとして実装する必要があった。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/errorNotDef.sh Sat Feb 06 11:19:45 2021 +0900 @@ -0,0 +1,6 @@ +[ 33%] Generating c/examples/DPP2/PhilsImpl.c +[ERROR] Not define eating at examples/DPP2/PhilsImpl.cbc +make[3]: *** [CMakeFiles/DPP2.dir/build.make:101: c/examples/DPP2/PhilsImpl.c] Error 25 +make[2]: *** [CMakeFiles/Makefile2:442: CMakeFiles/DPP2.dir/all] Error 2 +make[1]: *** [CMakeFiles/Makefile2:450: CMakeFiles/DPP2.dir/rule] Error 2 +make: *** [Makefile:293: DPP2] Error 2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/pickupAfter.cbc Sat Feb 06 11:19:45 2021 +0900 @@ -0,0 +1,28 @@ +__code pickup_lforkPhilsImpl(struct Context *context,struct PhilsImpl* phils, enum Code next) { + struct AtomicT_int* left_fork = phils->Leftfork; + Gearef(context, AtomicT_int)->atomicT_int = (union Data*) left_fork; + Gearef(context, AtomicT_int)->oldData = -1; + Gearef(context, AtomicT_int)->newData = phils->self; + Gearef(context, AtomicT_int)->next = C_pickup_rforkPhilsImpl; + Gearef(context, AtomicT_int)->fail = C_eatingPhilsImpl; + goto meta(context, left_fork->checkAndSet); + +} + +__code pickup_lforkPhilsImpl_stub(struct Context* context) { + PhilsImpl* phils = (PhilsImpl*)GearImpl(context, Phils, phils); + enum Code next = Gearef(context, Phils)->next; + goto pickup_lforkPhilsImpl(context, phils, next); +} + +__code eatingPhilsImpl(struct Context *context,struct PhilsImpl* phils, enum Code next) { + printf("%d: eating\n", phils->self); + goto meta(context, C_putdown_rforkPhilsImpl); +} + +__code eatingPhilsImpl_stub(struct Context* context) { + PhilsImpl* phils = (PhilsImpl*)GearImpl(context, Phils, phils); + enum Code next = Gearef(context, Phils)->next; + goto eatingPhilsImpl(context, phils, next); +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/pickupBefore.cbc Sat Feb 06 11:19:45 2021 +0900 @@ -0,0 +1,10 @@ +__code pickup_lfork(struct PhilsImpl* phils, __code next(...)) { + struct AtomicT_int* left_fork = phils->Leftfork; + goto left_fork->checkAndSet(-1, phils->self, pickup_rfork, eating); + +} + +__code eating(struct PhilsImpl* phils, __code next(...)) { + printf("%d: eating\n", phils->self); + goto putdown_rfork(); +}