changeset 99:7b4d7d2446e6

update
author anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sat, 06 Feb 2021 07:11:56 +0900
parents a74c49fd0359
children 39001ece437e
files paper/chapter/03-gears.tex paper/master_paper.pdf paper/src/twiceMeta.c paper/src/twiceNormal.cbc
diffstat 4 files changed, 87 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/paper/chapter/03-gears.tex	Fri Feb 05 22:31:08 2021 +0900
+++ b/paper/chapter/03-gears.tex	Sat Feb 06 07:11:56 2021 +0900
@@ -291,7 +291,23 @@
 常に持っておきたい値は、 Impl側のDataGearの要素として定義する必要がある。
 
 \section{par goto}
-TODO
+\texttt{par goto}とはGearsOSの並列処理用の構文である。
+ソースコード\ref{src:twice}では、 配列を初期化するcreateArray、 配列要素を2倍するtwice、 配列の状況を出力するprintArrayを並列で動作させている。
+par gotoした処理がそれぞれ終了すると、 code2に継続する。
+\lstinputlisting[label=src:twice, caption=par gotoの呼び出し]{src/twiceNormal.cbc}
+
+GearsOSで並列処理をする場合、 Contextの複製などのメタレベルの計算を多数行わなければならない。
+ノーマルレベルからは通常のgoto文のように記述可能な構文を導入し、 メタレベルとの分離を行っている。
+メタレベルに変換された結果をソースコード\ref{src:twiceMeta}に示す。
+\texttt{par goto}でCodeGearへの継続を指定すると、\texttt{par goto}の数に応じてContextが生成される。
+CodeGearの実行は、割り当てられたContextが担当する。
+作製されたContextは一度大本のContextのtaskフィールドにアドレスが書き込まれ、初期化が行われる。
+InputDataGearとOutputDataGearのQueueの用意を行った後に、contextのTaskListにElement 各DataGearは構造体の形で表現されている。
+Elementはリスト構造を作製する際に使われるデータ構造で、 次のElementを取得できる。
+
+各CodeGearは入力のDataGearであるInputDataGearの依存関係が解決したら実行され、OutputDataGearの状況をTaskManagerに通知するようになっている。
+par gotoの場合はTaskManager関係のメタ計算を挟む必要があるため、 通常のgoto metaではなく、初回はgoto parGotoMetaが実行される。
+\lstinputlisting[label=src:twiceMeta, caption=par gotoのメタレベル計算]{src/twiceMeta.c}
 
 \section{GearsOSのビルドシステム}
 GearsOSではビルドツールにCMakeを利用している。
Binary file paper/master_paper.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/twiceMeta.c	Sat Feb 06 07:11:56 2021 +0900
@@ -0,0 +1,60 @@
+__code createTask1(struct Context *context,struct LoopCounter* loopCounter, struct TaskManager* taskManager) {
+    Array* array1 = &ALLOCATE(context, Array)->Array;
+    Array* array2 = &ALLOCATE(context, Array)->Array;
+    Timer* timer = createTimerImpl(context);
+
+    struct Element* element;
+                    context->task = NEW(struct Context);
+                    initContext(context->task);
+                    context->task->next = C_createArray;
+                    context->task->idgCount = 0;
+                    context->task->idg = context->task->dataNum;
+                    context->task->maxIdg = context->task->idg + 0;
+                    context->task->odg = context->task->maxIdg;
+                    context->task->maxOdg = context->task->odg + 2;
+    GET_META(array1)->wait = createSynchronizedQueue(context);
+    GET_META(timer)->wait = createSynchronizedQueue(context);
+    context->task->data[context->task->odg+0] = (union Data*)array1;
+    context->task->data[context->task->odg+1] = (union Data*)timer;
+                    element = &ALLOCATE(context, Element)->Element;
+                    element->data = (union Data*)context->task;
+                    element->next = context->taskList;
+                    context->taskList = element;
+                    context->task = NEW(struct Context);
+                    initContext(context->task);
+                    context->task->next = C_twice;
+                    context->task->idgCount = 1;
+                    context->task->idg = context->task->dataNum;
+                    context->task->maxIdg = context->task->idg + 1;
+                    context->task->odg = context->task->maxIdg;
+                    context->task->maxOdg = context->task->odg + 1;
+    context->task->iterate = 0;
+    context->task->iterator = createMultiDimIterator(context, split, 1, 1);
+    GET_META(array1)->wait = createSynchronizedQueue(context);
+    GET_META(array2)->wait = createSynchronizedQueue(context);
+    context->task->data[context->task->idg+0] = (union Data*)array1;
+    context->task->data[context->task->odg+0] = (union Data*)array2;
+                    element = &ALLOCATE(context, Element)->Element;
+                    element->data = (union Data*)context->task;
+                    element->next = context->taskList;
+                    context->taskList = element;
+                    context->task = NEW(struct Context);
+                    initContext(context->task);
+                    context->task->next = C_printArray;
+                    context->task->idgCount = 2;
+                    context->task->idg = context->task->dataNum;
+                    context->task->maxIdg = context->task->idg + 2;
+                    context->task->odg = context->task->maxIdg;
+                    context->task->maxOdg = context->task->odg + 0;
+    GET_META(array2)->wait = createSynchronizedQueue(context);
+    GET_META(timer)->wait = createSynchronizedQueue(context);
+    context->task->data[context->task->idg+0] = (union Data*)array2;
+    context->task->data[context->task->idg+1] = (union Data*)timer;
+                    element = &ALLOCATE(context, Element)->Element;
+                    element->data = (union Data*)context->task;
+                    element->next = context->taskList;
+                    context->taskList = element;
+    Gearef(context, TaskManager)->taskList = context->taskList;
+    Gearef(context, TaskManager)->next1 = C_code2;
+    goto parGotoMeta(context, C_code2);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/twiceNormal.cbc	Sat Feb 06 07:11:56 2021 +0900
@@ -0,0 +1,10 @@
+__code createTask1(struct LoopCounter* loopCounter, struct TaskManager* taskManager) {
+    Array* array1 = new Array();
+    Array* array2 = new Array();
+    Timer* timer = createTimerImpl(context);
+
+    par goto createArray(array1, timer, __exit);
+    par goto twice(array1, array2, iterate(split), __exit);
+    par goto printArray(array2, timer, __exit);
+    goto code2();
+}