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として実装する必要があった。
Binary file paper/master_paper.pdf has changed
--- /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();
+}