Mercurial > hg > Papers > 2021 > anatofuz-master
changeset 62:45395005373f
update
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 03 Feb 2021 13:00:02 +0900 |
parents | e1dbf6e648ad |
children | eaa7a127027b |
files | paper/chapter/02-cbc.tex paper/master_paper.pdf paper/src/cbc_example_test.cbc |
diffstat | 3 files changed, 93 insertions(+), 8 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/chapter/02-cbc.tex Wed Feb 03 00:24:14 2021 +0900 +++ b/paper/chapter/02-cbc.tex Wed Feb 03 13:00:02 2021 +0900 @@ -31,6 +31,19 @@ 各CodeGearの入力として受けるDataGearをInputDataGearと呼ぶ。 逆に次の継続に渡すDataGearをOutputDataGearと呼ぶ。 +\section{CbCを使った例題} +ソースコード\ref{src:cbcexample_test}にCbCを使った例題を示す。 +\lstinputlisting[label=src:cbcexample_test, caption=CbCの例題]{src/cbc_example_test.cbc} + + +この例では構造体\texttt{struct Test}をcodegear1に渡し、その次にcodegear2に継続している。 +codegear2からはcodegear3にgotoし、 最後にexitする。 +この例題をアセンブラに変換した結果を示す。 +初回のmainからcodeGear1への継続は、 CbCコンパイラの仕様上関数呼び出しが行われる。 +それ以外のcodegear2からcodegear3などのgotoは、jmp命令が実行される。 +jmp命令はプログラムカウンタを切り替えるのみの命令であるため、 callと違いスタックの操作をしていないことが分かる。 + + \section{CbCを使ったシステムコールディスパッチの例題} CbCを用いてMITが開発した教育用のOSであるxv6\cite{xv6}の書き換えを行った。 @@ -48,21 +61,58 @@ CodeGearを元にプログラミングをするにつれて、 CodeGearの入出力のDataも重要であることが解ってきた。 \section{メタ計算} +メタ計算のメタとは、高次元などの意味を持つ言葉であり、特定の物の上位に位置するものである。 +メタ計算の場合は計算に必要な計算や、 計算を行うのに必要な計算を指す。 +GearsOSでのメタ計算は、 通常の計算を管理しているOSレベルの計算などを指す。 +OSから見たメタ計算は、自分自身を検証する計算などになる。 + +ノーマルレベルの計算からすると、メタ計算は通常隠蔽される。 +これはUNIXのプログラムを実行する際に、 OSのスケジューラーのことを意識せずに実行可能であることなどから分かる。 +新しいプロセスを作製する場合は\texttt{fork}システムコールを実行する必要がある。 +システムコールの先はOSが処理を行う。 +forkシステムコールの処理をOSが計算するが、 この計算はユーザープログラムから見るとメタ計算である。 +システムコールの中で何が起こっているかはユーザーレベルでは判断できず、 返り値などのAPIを経由して情報を取得する。 +現状のUNIXではメタ計算はこの様なシステムコールの形としても表現される。 + + +メタデータなどはデータのデータであり、 データを扱う上で必要なデータ情報を意味する。 +プログラムの中でプログラムを生成するものをメタプログラミングなどと呼ぶ。 +メタ計算やメタプログラムは、プログラム自身の検証などにとって重要な機能である。 +しかしメタレベルの計算をノーマルレベルで自在に記述してしまうと、 ノーマルレベルでの信頼性に問題が発生する。 +メタレベルではポインタ操作や資源管理を行うため、メモリオーバーフローなどの問題を簡単に引き起こしてしまう。 +メタレベルの計算とノーマルレベルの計算を適切に分離しつつ、 ノーマルレベルから安全にメタレベルの計算を呼び出す手法が必要となる。 + + プログラミング言語からメタ計算を取り扱う場合、 言語の特性に応じて様々な手法が使われてきた。 関数型プログラミングの見方では、 メタ計算はモナドの形で表現されていた。\cite{moggi-monad} OSの研究ではメタ計算の記述に型付きアセンブラを用いることもある。\cite{Yang:2010:SLI:1806596.1806610} +通常ユーザーがメタレベルのコードを扱う場合は特定のAPIを経由することになる。 +プログラム実行中のスタックの中には、 プログラムが現在実行している関数までのフレームや、各関数でアロケートされた変数などの情報が入る。 +これらを環境と呼ぶ。 +現状のプログラミング言語やOSでは、 この環境を常に持ち歩かなければならない。 +ノーマルレベルとメタレベルを分離しようとすると、 環境の保存について考慮しなければならず、 結果的にシステムコールなどのAPIを使わなければならない。 +システムコールを利用しても、 保存されている環境が常に存在する。 +この暗黙の環境のことを常に意識しなければならず、 既存言語でノーマルレベルとメタレベルの分離を完全に行うのは難しい。 + + +CbCではgoto文による軽量継続によって、 スタックをgotoの度に捨てていく。 +そもそもスタックが存在しないため、 暗黙の環境も存在せずに自由にプログラミングが可能となる。 +その為従来のプログラミング言語ではできなかった、ノーマルレベルとメタレベルのコードの分離が容易に行える。 + CbCでのメタ計算はCodeGear、 DataGearの単位がそのまま使用できる。 -メタ計算で使われるこれらの単位はそれぞれ、 MetaCodeGear、 MetaDataGearと呼ばれる。 - +メタ計算を行うCodeGearや、 メタな情報を持つDataGearが存在する。 +これらの単位はそれぞれ、 MetaCodeGear、 MetaDataGearと呼ばれる。 \section{MetaCodeGear} -GearsOSでは、 CodeGearとDataGearを元にプログラミングを行う。 -遷移する各CodeGearの実行に必要なデータの整合性の確認などのメタ計算は、 MetaCodeGearと呼ばれる各CodeGearごと実装されたCodeGearで計算を行う。 -このMetaCodeGearの中で参照されるDataGearをMetaDataGearと呼ぶ。 -また、 対象のCodeGearの直前で実行されるMetaCodeGearをStubCodeGearと呼ぶ。 -MetaCodeGearやMetaDataGearは、プログラマが直接実装することはなく、 現在はPerlスクリプトによってGearsOSのビルド時に生成される。 +遷移する各CodeGearの実行に必要なデータの整合性の確認などはメタ計算である。 +この計算はMetaCodeGearと呼ばれる各CodeGearごと実装されたCodeGearで計算を行う。 + +特に対象のCodeGearの直前で実行されるMetaCodeGearをStubCodeGearと呼ぶ。 +MetaCodeGearやMetaDataGearは、プログラマが直接実装せず、 PerlスクリプトによってGearsOSのビルド時に生成される。 +ただしPerlスクリプトはすでに書かれていたStubCodeGearは上書きしない。 +スクリプトに問題がある場合や、 細かな調整をしたい場合はプログラマが直接実装可能である。 CodeGearから別のCodeGearに遷移する際のDataGearなどの関係性を、図\ref{meta-cg-dg}に示す。 \begin{figure}[tb] @@ -82,4 +132,4 @@ 基本はC言語の構造体そのものであるが、 DataGearの場合はデータに付随するメタ情報も取り扱う。 これはデータ自身がどういう型を持っているかなどの情報である。 ほかに計算を実行するCPU、 GPUの情報や、 計算に必要なすべてのDataGearの管理などの実行環境のメタデータもDataGearの形で表現される。 -このメタデータを扱うDataGearをMetaDataGearと呼ぶ。 \ No newline at end of file +このメタデータを扱うDataGearをMetaDataGearと呼ぶ。
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/paper/src/cbc_example_test.cbc Wed Feb 03 13:00:02 2021 +0900 @@ -0,0 +1,35 @@ +extern int printf(const char*,...); + +typedef struct test { + int number; + char* string; +} TEST; + + +__code codegear1(TEST); +__code codegear2(TEST); +__code codegear3(TEST); + +__code codegear1(TEST testin){ + TEST testout; + testout.number = testin.number + 1; + testout.string = testin.string; + goto codegear2(testout); +} + +__code codegear2(TEST testin){ + TEST testout; + testout.number = testin.number; + testout.string = "Hello"; + goto codegear3(testout); +} + +__code codegear3(TEST testin){ + printf("number = %d\t string= %s\n",testin.number,testin.string); + goto exit(0); +} + +int main(){ + TEST test = {0,0}; + goto codegear1(test); +}