changeset 27:a62d736db44e

stub and description loop
author tobaru
date Sun, 09 Feb 2020 15:29:56 +0900
parents ee9435951c31
children 53302e350642
files paper/GearsOS.tex paper/cbc_interface.tex paper/master_paper.pdf paper/master_paper.synctex.gz paper/src/dummy paper/src/stub_loaduvm paper/src/vm_impl_private.cbc
diffstat 7 files changed, 137 insertions(+), 127 deletions(-) [+]
line wrap: on
line diff
--- a/paper/GearsOS.tex	Sun Feb 09 14:12:59 2020 +0900
+++ b/paper/GearsOS.tex	Sun Feb 09 15:29:56 2020 +0900
@@ -32,7 +32,7 @@
 
 メタ計算は Meta Code Gear と Meta Data Gear を用いる。
 この2つはノーマルレベルからメタレベルの変換する時に使われる。
-メタレベルの変換は Perl スクリプトで実装している。
+メタレベルの変換は Perl スクリプトによる cmake で実装している。
 Gears OS での Meta Code Gear は Code Gear の直前、 直後に挿入され、メタ計算を実行する。
 それぞれの Code Gear, Meta Code Gear の継続には入力される Data Gear(Input Data Gear) と出力されるData Gear(Output Data Gear)が存在する。
 Code Gear 間の継続はノーマルレベルでは 図 \ref{fig:codegear} のように見えるが、メタレベルでの Code Gear は図 \ref{fig:meta_cg_dg} の下のように継続を行っている。
--- a/paper/cbc_interface.tex	Sun Feb 09 14:12:59 2020 +0900
+++ b/paper/cbc_interface.tex	Sun Feb 09 15:29:56 2020 +0900
@@ -53,7 +53,6 @@
 % 引数の Data Gear はその Code Gear の Input Data Gear になり、引数の Code Gear の中の引 数が Output Data Gear になる。Code Gear の第一引数には Interface を実装した Data Gear を渡す。これは、Code Gear の操作の対象となる Data Gear を設定し ており、後述する継続構文では引数として記述を行わない。
 
 
-\section{インターフェースの実装}
  インターフェースは Data Gear に対しての Code Gear とその Code Gear で扱われている Data Gear の集合を抽象化した Meta Data Gear で、vm.c に対応する実装は別で定義する。
 
 
@@ -82,7 +81,7 @@
 
 
 
-\section{インターフェース内の private メソッド}
+\section{インターフェースの実装}
 インターフェースで定義した Code Gear 以外の Code Gaer も記述することができる。
 この Code Gear は基本的にインターフェースで指定された Code Gear 内からのみ継続されるため、
 Java の private メソッドのように扱われる。
@@ -165,10 +164,10 @@
 vm\_impl.cbc の Code Gear であるloaduvmvm\_impl から goto で loaduvm\_ptesize\_checkvm\_impl に遷移する。
 vm.c での最初の if 文までの処理を 1つの Code Gear として loaduvm\_ptesize\_checkvm\_impl に記述する。(3行目~11行目)
 
-
+\section{CbC のループ処理}
  
 CbC では goto での状態遷移によって実装するので loop は if 文を使って実装する。
-遷移図を \ref{fig:cbc_for_private} で示す。
+遷移図を 図 \ref{fig:cbc_for_private} で示す。
 
  \begin{figure}[ht]
  \begin{center}
@@ -179,131 +178,35 @@
 \end{figure}
 
 
-\begin{lstlisting}[frame=lrbt,label=impl_vm_loaduvm,caption={\footnotesize privateでの loaduvm の実装}]
-#interface "vm_impl.h"
-
-__code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    char* addr = vm_impl->addr;
-
-    if ((uint) addr %PTE_SZ != 0) {
-       // goto panic
-    }
-
-    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
-}
-
-__code loaduvm_loopvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    uint i = vm_impl->i;
-    uint sz = vm_impl->sz;
-
-    if (i < sz) {
-        goto loaduvm_check_pgdir(vm_impl, next(ret, ...));
-    }
-
-    goto loaduvm_exit(vm_impl, next(ret, ...));
-}
-
+\lstinputlisting[frame=lrbt,label=impl_vm_loaduvm,caption={\footnotesize loaduvm の実装の記述}]{./src/vm_impl_private.cbc}
 
-static pte_t* walkpgdir (pde_t *pgdir, const void *va, int alloc)
-{   
-    pde_t *pde;
-    pte_t *pgtab;
-    
-    // pgdir points to the page directory, get the page direcotry entry (pde)
-    pde = &pgdir[PDE_IDX(va)];
-    
-    if (*pde & PE_TYPES) {
-        pgtab = (pte_t*) p2v(PT_ADDR(*pde));
-    
-    } else {
-        if (!alloc || (pgtab = (pte_t*) kpt_alloc()) == 0) {
-            return 0;
-        }
-        
-        // Make sure all those PTE_P bits are zero.
-        memset(pgtab, 0, PT_SZ);
-        
-        // The permissions here are overly generous, but they can
-        // be further restricted by the permissions in the page table
-        // entries, if necessary.
-        *pde = v2p(pgtab) | UPDE_TYPE;
-    }
-
-    return &pgtab[PTE_IDX(va)];
-}
+for文から末尾再起の変換について
+図 \ref{fig:cbc_for_private} のように loaduvm\_loopvm\_impl のif 文で ループの条件を書いて goto させ、loaduvm\_check\_PTE\_SZ で満たしてなければ loaduvm\_loopvm\_impl に goto することでループを実装している。
 
 
-__code loaduvm_check_pgdir(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    pte_t* pte = vm_impl->pte;
-    pde_t* pgdir = vm_impl->pgdir;
-    uint i = vm_impl->i;
-    char* addr = vm_impl->addr;
-    uint pa = vm_impl->pa;
-
-    if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
-        // goto panic
-    }
-    pa = PTE_ADDR(*pte);
-
-    vm_impl->pte = pte;
-    vm_impl->pgdir = pgdir;
-    vm_impl->addr = addr;
-    vm_impl->pa = pa;
-
-    goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
-}
+static なものはまだ書き直していないが後々実装する
 
-__code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    uint sz = vm_impl->sz;
-    uint i = vm_impl->i;
-    uint n = vm_impl->n;
-    struct inode* ip = vm_impl->ip;
-    uint pa = vm_impl->pa;
-    uint offset = vm_impl->offset;
-
-    if (sz - i < PTE_SZ) {
-        n = sz - i;
-    } else {
-        n = PTE_SZ;
-    }
-
-    if (readi(ip, p2v(pa), offset + i, n) != n) {
-        ret = -1;
-        goto next(ret, ...);
-    }
-
-    vm_impl->n = n;
-
-    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
-}
-
-__code loaduvm_exit(struct vm_impl* vm_impl, __code next(int ret, ...)) {
-    ret = 0;
-    goto next(ret, ...);
-}
-
-\end{lstlisting}
-
-for文から末尾再起の変換について
+\section{Meta Code Gear の記述}
+cmake によって生成されたメタ部分の記述について説明する。
+ファイルはビルドディレクトリ以下の /CMakeFiles/kernel.dir/c/ に生成される。
 
 
-static なものに関しては後々実装する
+ノーマルレベルの Code Gear と ノーマルレベルの Code Gear 名 の後ろに \_stub が付いた Meta Code Gearが対応する。
+例として loaduvm の生成された Code Gear と Meta Code Gear をソースコード \ref{loaduvm_stub} に示す。
+
+\lstinputlisting[frame=lrbt,label=loaduvm_stub,caption={\footnotesize loaduvm のメタ部分の記述}]{./src/stub_loaduvm}
+
 
 
 \section{インターフェースの呼び出し}
 定義したインターフェースの呼び出し方について説明する。
  CbC の場合 goto による遷移を行うので、関数呼び出しのように goto 以降のコードを実行できない。
-例として、ソースコード \ref{cbc_goto} の16行目のように goto によってインターフェースで定義した命令を行うと、戻ってこれないため17行目以降が実行されなくなる。
-
 
 \lstinputlisting[frame=lrbt,label=cbc_goto,caption={\footnotesize cbc インターフェースのgoto}]{./src/failure_example_userinit}
 
-\lstinputlisting[frame=lrbt,label=dummy,caption={\footnotesize dummy を使った呼び出し}]{./src/dummy}
-14行目から18行目の引数の設定に Gearef を使っているが、本来は CMake で生成しその部分には何も書かない。
-18行目の C\_vm\_void\_ret は return するための enum コードであり、これを使って関数呼び出しのように振る舞う。
+例として、ソースコード \ref{cbc_goto} の16行目のように goto によってインターフェースで定義した命令を行うと、戻ってこれないため17行目以降が実行されなくなる。
 
 
-1行目から6行目までの関数と cbc\_init\_vmm\_dummy の Code Gear はまとめて記述することも可能である。
-
-
-
+\lstinputlisting[frame=lrbt,label=dummy,caption={\footnotesize dummy を使った呼び出し}]{./src/dummy}
+7行目から11行目の引数の設定に Gearef を使っているが、本来は CMake で生成しその部分には何も書かない。
+11行目の C\_vm\_void\_ret は return するための enum コードであり、これを使って関数呼び出しのように振る舞う。
Binary file paper/master_paper.pdf has changed
Binary file paper/master_paper.synctex.gz has changed
--- a/paper/src/dummy	Sun Feb 09 14:12:59 2020 +0900
+++ b/paper/src/dummy	Sun Feb 09 15:29:56 2020 +0900
@@ -1,13 +1,6 @@
-void dummy(struct proc *p, char _binary_initcode_start[], char _binary_initcode_size[])
+void cbc_init_vmm_dummy(struct Context* cbc_context, struct proc* p, pde_t* pgdir, char* init, uint sz)
 {
     // inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
-    goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
-
-}
-
-
-
-__ncode cbc_init_vmm_dummy(struct Context* cbc_context, struct proc* p, pde_t* pgdir, char* init, uint sz){//:skip
 
     struct vm* vm = createvm_impl(cbc_context);
     // goto vm->init_vmm(vm, pgdir, init, sz , vm->void_ret);
@@ -19,7 +12,6 @@
     goto meta(cbc_context, vm->init_inituvm);
 }
 
-
 void userinit(void)
 {
     struct proc* p;
@@ -34,4 +26,8 @@
         panic("userinit: out of memory?");
     }
 
-    dummy(p, _binary_initcode_start, _binary_initcode_size);
+    cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+
+    p->sz = PTE_SZ;
+....
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/stub_loaduvm	Sun Feb 09 15:29:56 2020 +0900
@@ -0,0 +1,21 @@
+__code loaduvmvm_impl(struct Context *cbc_context,struct vm_impl* vm, pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz,  enum Code next) {
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->addr = addr;
+    Gearef(cbc_context, vm_impl)->ip = ip;
+    Gearef(cbc_context, vm_impl)->offset = offset;
+    Gearef(cbc_context, vm_impl)->sz = sz;
+    Gearef(cbc_context, vm_impl)->next = next;
+
+    goto meta(cbc_context, C_loaduvm_ptesize_checkvm_impl);
+}
+
+__code loaduvmvm_impl_stub(struct Context* cbc_context) {
+        vm_impl* vm = (vm_impl*)GearImpl(cbc_context, vm, vm);
+        pde_t* pgdir = Gearef(cbc_context, vm)->pgdir;
+        char* addr = Gearef(cbc_context, vm)->addr;
+        inode* ip = Gearef(cbc_context, vm)->ip;
+        uint offset = Gearef(cbc_context, vm)->offset;
+        uint sz = Gearef(cbc_context, vm)->sz;
+        enum Code next = Gearef(cbc_context, vm)->next;
+        goto loaduvmvm_impl(cbc_context, vm, pgdir, addr, ip, offset, sz, next);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/paper/src/vm_impl_private.cbc	Sun Feb 09 15:29:56 2020 +0900
@@ -0,0 +1,90 @@
+#interface "vm_impl.h"
+
+__code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl,char* addr,  __code next(int ret, ...)) {
+    if ((uint) addr %PTE_SZ != 0) {
+       char* msg = "addr % PTE_SZ != 0";
+       struct Err* err = createKernelError(&proc->cbc_context);
+       Gearef(cbc_context, Err)->msg = msg;
+       goto meta(cbc_context, err->panic);
+    }
+
+    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
+}
+
+__code loaduvm_loopvm_impl(struct vm_impl* vm_impl, uint i, uint sz,__code next(int ret, ...)) {
+    if (i < sz) {
+        goto loaduvm_check_pgdir(vm_impl, next(ret, ...));  
+    } 
+
+    goto loaduvm_exit(vm_impl, next(ret, ...));
+}
+
+
+static pte_t* walkpgdir (pde_t *pgdir, const void *va, int alloc)
+{
+    pde_t *pde;
+    pte_t *pgtab;
+
+    // pgdir points to the page directory, get the page direcotry entry (pde)
+    pde = &pgdir[PDE_IDX(va)];
+
+    if (*pde & PE_TYPES) {
+        pgtab = (pte_t*) p2v(PT_ADDR(*pde));
+
+    } else {
+        if (!alloc || (pgtab = (pte_t*) kpt_alloc()) == 0) {
+            return 0;
+        }
+
+        // Make sure all those PTE_P bits are zero.
+        memset(pgtab, 0, PT_SZ);
+
+        // The permissions here are overly generous, but they can
+        // be further restricted by the permissions in the page table
+        // entries, if necessary.
+        *pde = v2p(pgtab) | UPDE_TYPE;
+    }
+
+    return &pgtab[PTE_IDX(va)];
+}
+
+
+__code loaduvm_check_pgdir(struct vm_impl* vm_impl, pte_t* pte, pde_t* pgdir, uint i, char* addr, uint pa, __code next(int ret, ...)) {
+    if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
+       char* msg = "pte != walkpgdir...";
+       struct Err* err = createKernelError(&proc->cbc_context);
+       Gearef(cbc_context, Err)->msg = msg;
+       goto meta(cbc_context, err->panic);
+    } 
+    pa = PTE_ADDR(*pte);
+
+    Gearef(cbc_context, vm_impl)->pte   = pte;
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->addr  = addr;
+    Gearef(cbc_context, vm_impl)->pa    = pa;
+
+    goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
+}
+
+__code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, uint sz, uint i, uint n, struct inode* ip, uint pa, uint offset, __code next(int ret, ...)) {
+    
+    if (sz - i < PTE_SZ) {
+        n = sz - i;
+    } else {
+        n = PTE_SZ;
+    }
+
+    if (readi(ip, p2v(pa), offset + i, n) != n) {
+        ret = -1;
+        goto next(ret, ...);
+    }
+
+    Gearef(cbc_context, vm_impl)->n = n;
+ 
+    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
+}
+
+__code loaduvm_exit(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    ret = 0;
+    goto next(ret, ...);
+}