changeset 37:ae5601060567

update
author mir3636
date Thu, 07 Feb 2019 11:40:31 +0900
parents 68f10de82b87
children 1d8c163b7255
files paper/master_paper.pdf paper/xv6.tex
diffstat 2 files changed, 91 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
Binary file paper/master_paper.pdf has changed
--- a/paper/xv6.tex	Thu Feb 07 11:03:10 2019 +0900
+++ b/paper/xv6.tex	Thu Feb 07 11:40:31 2019 +0900
@@ -115,3 +115,94 @@
     }
 \end{lstlisting}
 
+ソースコード \ref{sys_read} は CbC で書き換えた read システムコールである。
+Code Gear であるため関数呼び出しではなく goto による継続となる。
+
+\begin{lstlisting}[frame=lrbt,label=sys_read,caption={\footnotesize read システムコール}]
+__code cbc_read(__code (*next)(int ret)){
+    struct file *f;
+    int n;
+    char *p;
+
+    if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) {
+        goto next(-1);
+    }
+    goto cbc_fileread(f, p, n, next);
+}
+
+int sys_read(void)
+{   
+    struct file *f;
+    int n;
+    char *p;
+    
+    if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) {
+        return -1;
+    }
+    
+    return fileread(f, p, n);
+}
+\end{lstlisting}
+
+継続で Code Gear 間を遷移するため関数呼び出しとは違い元の関数には戻ってこない。
+このため、書き換えの際には ソースコード \ref{fileread} のように分割する必要がある。
+
+\begin{lstlisting}[frame=lrbt,label=fileread,caption={\footnotesize fileread の CbC 書き換えの例}]
+__code cbc_fileread1 (int r)
+{
+    struct file *f = proc->cbc_arg.cbc_console_arg.f;
+    __code (*next)(int ret) = cbc_ret;
+    if (r > 0)
+        f->off += r;
+    iunlock(f->ip);
+    goto next(r);
+}
+
+__code cbc_fileread (struct file *f, char *addr, int n, __code (*next)(int ret))
+{
+    if (f->readable == 0) {
+        goto next(-1);
+    }
+
+    if (f->type == FD_PIPE) {
+        goto cbc_piperead(f->pipe, addr, n, next);
+        goto next(-1);
+    }
+
+    if (f->type == FD_INODE) {
+        ilock(f->ip);
+        proc->cbc_arg.cbc_console_arg.f = f;
+        goto cbc_readi(f->ip, addr, f->off, n, cbc_fileread1);
+    }
+
+    goto cbc_panic("fileread");
+}
+
+// Read from file f.
+int fileread (struct file *f, char *addr, int n)
+{
+    int r;
+
+    if (f->readable == 0) {
+        return -1;
+    }
+
+    if (f->type == FD_PIPE) {
+        return piperead(f->pipe, addr, n);
+    }
+
+    if (f->type == FD_INODE) {
+        ilock(f->ip);
+
+        if ((r = readi(f->ip, addr, f->off, n)) > 0) {
+            f->off += r;
+        }
+
+        iunlock(f->ip);
+
+        return r;
+    }
+
+    panic("fileread");
+}
+\end{lstlisting}