changeset 17:c8fee0262ead

fix chapter5
author menikon
date Thu, 13 Feb 2020 01:50:45 +0900
parents b67e4c9f0374
children 18edad46e821
files final_main/appendix.tex final_main/chapter5.tex final_main/fig/iallocloop.graffle final_main/fig/iallocloop.pdf final_main/main.pdf final_main/main.tex final_main/src/fs1.dg final_main/src/fs_impl1.cbc final_main/src/fs_impl1.h final_main/src/ialloc.cbc final_main/src/iallocfs_impl.cbc
diffstat 11 files changed, 136 insertions(+), 125 deletions(-) [+]
line wrap: on
line diff
--- a/final_main/appendix.tex	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/appendix.tex	Thu Feb 13 01:50:45 2020 +0900
@@ -2,5 +2,5 @@
 
 \lstinputlisting[label=fs.ds,  caption=FileSystem の Interface]{src/fs.dg}
 \lstinputlisting[label=fs_impl.h,  caption=fs private のヘッダーファイル]{src/fs_impl.h}
-\lstinputlisting[label=fs_impl.cbc,  caption=fs の 実装]{src/fs_impl.cbc}
-\lstinputlisting[label=fs_impl_private.cbc,  caption=fs の 実装の private]{src/fs_impl_private.cbc}
\ No newline at end of file
+\lstinputlisting[label=fs_impl.cbc,  caption=fs Interface の実装]{src/fs_impl.cbc}
+\lstinputlisting[label=fs_impl_private.cbc,  caption=fs Interface の private 実装]{src/fs_impl_private.cbc}
\ No newline at end of file
--- a/final_main/chapter5.tex	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/chapter5.tex	Thu Feb 13 01:50:45 2020 +0900
@@ -21,11 +21,11 @@
 %\newpage
 FileSystem の Interface を記述したコードをソースコード\ref{fs_interface}に示す。
 
-\lstinputlisting[label=fs_interface,  caption=FileSystem の Interface (fs.dg)]{src/fs1.dg}
+\lstinputlisting[label=fs_interface,  caption=FileSystem の Interface (fs.dg一部抜粋)]{src/fs1.dg}
 
 1行目で Interface名を定義している。typedef struct の後に Interface名 (今回は fs) を書く。
 CodeGear は \_\_code CodeGear名 (引数) の形で記述する。第一引数である Impl* fs が CodeGear の型、第二引数以降は Interface の実装時に利用する CodeGear が必要とする引数が入る。
-CodeGaer は 2 行目から 18 行目のように ”\_\_code [CodeGear 名]([引数])”で記述する。この引数が input Data Gear になる。
+CodeGaer は 2 行目から 9 行目のように ”\_\_code [CodeGear 名]([引数])”で記述する。この引数が input Data Gear になる。
 
 \section{FileSystem の Interface の実装}
 
@@ -39,4 +39,20 @@
 インターフェースで定義した CodeGear 以外の CodeGaer も記述することができる。この Code Gear は基本的にインターフェースで指定された Code Gear 内からのみ継続されるため、Java の private メソッドのように扱われる。
 インターフェースと同じようにヘッダーファイルをソースコード\ref{fs_impl}で定義する。
 
-\lstinputlisting[label=fs_impl,  caption=fs private のヘッダーファイル(fs\_impl.h)]{src/fs_impl1.h}
+\lstinputlisting[label=fs_impl,  caption=fs private のヘッダーファイル(fs\_impl.h一部抜粋)]{src/fs_impl1.h}
+
+private での CbC の記述について説明する。記述量が多いため、if 文と for 文を書き換えた ialloc\_impl という関数で説明する。書き換えコードは以下のソースコード\ref{ialloc}とソースコード\ref{alloc}に示す。
+
+\lstinputlisting[label=ialoc,  caption=iallocfs\_impl の実装]{src/iallocfs_impl.cbc}
+fs\_impl.cbc の中でCodeGear である iallocfs\_impl が処理されると goto で private な実装である fs\_impl\_private.cbc 側の allocinode という CodeGear へと遷移する。
+
+\lstinputlisting[label=alloc,  caption=iallocfs\_impl の private 実装]{src/ialloc.cbc}
+private 側では iallocfs\_impl からの受け皿としての allocinode、for 文のループ条件を確認する allocinode\_loopcheck、ループした際の処理をする allocinode\_loop、ループから抜けた際の処理をする allocinode\_noloop の4つの CodeGearから成り立っている。 ループの条件に当てはまらない際は panicへと処理が移り処理が停止する。static なものはまだ書き直していないが後々実装する。これらの CodeGearの一連の挙動を図\ref{fig:iallocloop}に示す。
+
+\begin{figure}[ht]
+     \begin{center}
+     \includegraphics[width=100mm]{fig/iallocloop.pdf}
+     \end{center}
+     \caption{allocinode の ループによる遷移図}
+    \label{fig:iallocloop}
+\end{figure}
Binary file final_main/fig/iallocloop.graffle has changed
Binary file final_main/fig/iallocloop.pdf has changed
Binary file final_main/main.pdf has changed
--- a/final_main/main.tex	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/main.tex	Thu Feb 13 01:50:45 2020 +0900
@@ -106,6 +106,6 @@
 \input{thanks.tex}
 
 % 付録
-%\input{appendix.tex}
+\input{appendix.tex}
 
 \end{document}
--- a/final_main/src/fs1.dg	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/src/fs1.dg	Thu Feb 13 01:50:45 2020 +0900
@@ -7,14 +7,7 @@
     __code ilock(Impl* fs, struct inode* ip, __code next(...));
     __code iunlock(Impl* fs, struct inode* ip, __code next(...));
     __code iput(Impl* fs, struct inode* ip, __code next(...));
-    __code iunlockput(Impl* fs, struct inode* ip, __code next(...));
-    __code stati(Impl* fs , struct inode* ip, struct stat* st, __code next(...));
-    __code readi(Impl* fs, struct inode* ip, char* dst, uint off, uint tot, uint n, __code next(int ret, ...));
-    __code writei(Impl* fs, struct inode* ip, char* src, uint off, uint tot, uint n, __code next(int ret, ...));
-    __code namecmp(Impl* fs, const char* s, const char* t, __code next(int strncmp_val, ...));
-    __code dirlookup(Impl* fs, struct inode* dp, char* name, uint off, uint* poff, dirent* de, __code next(int ret, ...));
-    __code dirlink(struct fs_impl* fs, struct inode* ip, struct dirent* de, struct inode* dp, char* name, uint off, uint inum, __code next(...));
-    __code namei(Impl* fs, char* path, __code next(int namex_val, ...));
-    __code nameiparent(Impl* fs, char* path, char* name, __code next(int namex_val, ...));
-    __code next(...);
+
+....
+
 } fs;
--- a/final_main/src/fs_impl1.cbc	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/src/fs_impl1.cbc	Thu Feb 13 01:50:45 2020 +0900
@@ -149,90 +149,4 @@
     goto iput_check(fs, ip, next(...));
 }
 
-__code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) {
-    fs->next2 = next;
-    goto iunlockfs_impl(ip, fs->iput, ...);
-}
-
-typedef struct stat stat;
-__code statifs_impl(struct fs_impl* fs , struct inode* ip, struct stat* st, __code next(...)) { //:skip
-    st->dev = ip->dev;
-    st->ino = ip->inum;
-    st->type = ip->type;
-    st->nlink = ip->nlink;
-    st->size = ip->size;
-    goto next(...);
-}
-
-__code readifs_impl(struct fs_impl* fs, struct inode* ip, char* dst, uint off, uint tot, uint n, __code next(int ret, ...)) {
-    if (ip->type == T_DEV) {
-        goto readi_check_diskinode(fs, ip, dst, n, next(...));
-    }
-
-    if (off > ip->size || off + n < off) {
-        ret = -1;
-        goto next(ret, ...);
-    }
-
-    if (off + n > ip->size) {
-        n = ip->size - off;
-    }
-    Gearef(cbc_context, fs)->tot = 0;
-    goto readi_loopcheck(fs, tot, m, dst, off, n, next(...));
-}
-
-__code writeifs_impl(struct fs_impl* fs, struct inode* ip, char* src, uint off, uint tot, uint n, __code next(int ret, ...)) {
-    if (ip->type == T_DEV) {
-        goto writei_check_diskinode(fs, ip, src, n, next(...));
-    }
-
-    if (off > ip->size || off + n < off) {
-        ret = -1;
-        goto next(ret, ...);
-    }
-
-    if (off + n > MAXFILE * BSIZE) {
-        ret = -1;
-        goto next(ret, ...);
-    }
-    Gearef(cbc_context, fs)->tot = 0;
-    goto writei_loopcheck(fs, tot, m, src, off, n, next(...));
-}
-
-__code namecmpfs_impl(struct fs_impl* fs, const char* s, const char* t, __code next(int strncmp_val, ...)) {
-    strncmp_val = strncmp(s, t, DIRSIZ);
-    goto next(strncmp_val, ...);
-}
-
-__code dirlookupfs_impl(struct fs_impl* fs, struct inode* dp, char* name, uint off, uint* poff, dirent* de,  __code next(...)) { //:skip
-    if (dp->type != T_DIR) {
-       char* msg = "dirlookup not DIR";
-       struct Err* err = createKernelError(&proc->cbc_context);
-       Gearef(cbc_context, Err)->msg = msg;
-       goto meta(cbc_context, err->panic);
-    }
-    Gearef(cbc_context, fs)->off = 0;
-    goto dirlookup_loopcheck(fs, dp, name, off, poff, de, next(...));
-}
-
-__code dirlinkfs_impl(struct fs_impl* fs, struct inode* ip, struct dirent* de, struct inode* dp, char* name, uint off, uint inum, __code next(...)) { //:skip
-
-    if ((ip = dirlookup(dp, name, 0)) != 0) {
-        goto dirlink_namecheck(fs, ip, next(...));
-    }
-    Gearef(cbc_context, fs)->off = 0;
-    goto dirlink_loopcheck(fs, de, dp, off, next(...));
-}
-
-__code nameifs_impl(struct fs_impl* fs, char* path, __code next(int namex_val, ...)) {
-    char name[DIRSIZ];
-    namex_val = namex(path, 0, name);
-    goto next(namex_val, ...);
-}
-
-__code nameiparentfs_impl(struct fs_impl* fs, char* path, char* name, __code next(int namex_val, ...)) {
-
-    namex_val = namex(path, 1, name);
-    goto next(namex_val, ...);
-
-}
+....
--- a/final_main/src/fs_impl1.h	Wed Feb 12 19:54:53 2020 +0900
+++ b/final_main/src/fs_impl1.h	Thu Feb 13 01:50:45 2020 +0900
@@ -3,26 +3,7 @@
     __code allocinode_loop(Type* fs_impl, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...));
     __code allocinode_loopcheck(Type* fs_impl, uint inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...));
     __code allocinode_noloop(Type* fs_impl, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int ret, ...));
-    __code lockinode1(Type* fs_impl, struct inode *ip, struct buf *bp, struct dinode *dip, __code next(...));
-    __code lockinode2(Type* fs_impl, struct inode* ip, struct buf* bp, struct dinode* dip, __code next(...));
-    __code lockinode_sleepcheck(Type* fs_impl, struct inode* ip, __code next(...));
-    __code iput_check(Type* fs_impl, struct inode* ip, __code next(...));
-    __code iput_inode_nolink(Type* fs_impl, struct inode* ip, __code next(...));
-    __code readi_check_diskinode(Type* fs_impl,struct inode* ip, char* dst, uint n, next(int ret, ...));
-    __code readi_loopcheck(Type* fs_impl, uint tot, uint m, char* dst, uint off, uint n, __code next(...));
-    __code readi_loop(Type* fs_impl, struct inode *ip, struct buf* bp, uint tot, uint m, char* dst, uint off, uint n, __code next(...));
-    __code readi_noloop(Type* fs_impl, uint n, __code next(int ret, ...));
-    __code writei_check_diskinode(Type* fs_impl,struct inode* ip, char* src, uint n, __code next(int ret, ...));
-    __code writei_loopcheck(Type* fs_impl, uint tot, uint m, char* src, uint off, uint n, __code next(...));
-    __code writei_loop(Type* fs_impl, struct inode* ip, struct buf* bp, uint tot, uint m, char* src, uint off, uint n, __code next(...));
-    __code writei_noloop(Type* fs_impl, struct inode* ip, uint n, uint off, __code next(int ret, ...));
-    __code dirlookup_loopcheck(Type* fs_impl, struct inode* dp, char* name, uint off, uint* poff, dirent* de, next(...));
-    __code dirlookup_loop(Type* fs_impl, struct inode* dp, char* name, uint off, uint inum, uint* poff, dirent* de, __code next(int ret, ...));
-    __code dirlookup_noloop(Type* fs_impl, __code next(int ret, ...));
-    __code dirlink_namecheck(Type* fs_impl, struct inode* ip, __code next(int ret, ...));
-    __code dirlink_loopcheck(Type* fs_impl, struct dirent* de, struct inode* dp, uint off, __code next(...));
-    __code dirlink_loop(Type* fs_impl, struct dirent* de, struct inode* dp, uint off, uint inum, __code next(...));
-    __code dirlink_noloop(Type* fs_impl, struct dirent* de, struct inode* dp, uint off, uint inum, char* name, __code next(int ret, ...));
-    __code next(...);
-    __code next2(...);
+  
+....
+
 } fs_impl;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/final_main/src/ialloc.cbc	Thu Feb 13 01:50:45 2020 +0900
@@ -0,0 +1,102 @@
+#include "types.h"
+#include "defs.h"
+#include "param.h"
+#include "stat.h"
+#include "mmu.h"
+#include "proc.h"
+#include "spinlock.h"
+#include "buf.h"
+#include "fs.h"
+#include "file.h"
+#interface "fs_impl.h"
+#interface "Err.h"
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+/*
+fs_impl* createfs_impl2();
+*/
+
+__code allocinode(struct fs_impl* fs_impl, uint dev, struct superblock* sb, __code next(...)){ //:skip
+
+    readsb(dev, sb);
+    Gearef(cbc_context, fs_impl)->inum = 1;
+    goto allocinode_loopcheck(fs_impl, inum, dev, sb, bp, dip, next(...));
+
+}
+
+typedef struct buf buf;
+typedef struct dinode dinode;
+
+__code allocinode_loopcheck(struct fs_impl* fs_impl, uint inum, uint dev, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...)){ //:skip
+    if( inum < sb->ninodes){
+        goto allocinode_loop(fs_impl, inum, dev, type, sb, bp, dip, next(...));
+    }
+    char* msg = "failed allocinode...";
+    struct Err* err = createKernelError(&proc->cbc_context);
+    Gearef(cbc_context, Err)->msg = msg;
+    goto meta(cbc_context, err->panic);
+
+}
+
+__code allocinode_loop(struct fs_impl* fs_impl, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(...)){ //:skip
+    bp = bread(dev, IBLOCK(inum));
+    dip = (struct dinode*) bp->data + inum % IPB;
+    if(dip->type = 0){
+        goto allocinode_noloop(fs_impl, inum, dev, sb, bp, dip, next(...));
+    }
+
+    brelse(bp);
+    inum++;
+    goto allocinode_loopcheck(fs_impl, inum, dev, type, sb, bp, dip, next(...));
+}
+
+struct {
+    struct spinlock lock;
+    struct inode inode[NINODE];
+} icache;
+
+static struct inode* iget (uint dev, uint inum)
+{
+    struct inode *ip, *empty;
+
+    acquire(&icache.lock);
+
+    empty = 0;
+
+    for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) {
+        if (ip->ref > 0 && ip->dev == dev && ip->inum == inum) {
+            ip->ref++;
+            release(&icache.lock);
+            return ip;
+        }
+
+        if (empty == 0 && ip->ref == 0) {   
+            empty = ip;
+        }
+    }
+
+    if (empty == 0) {
+        panic("iget: no inodes");
+    }
+
+    ip = empty;
+    ip->dev = dev;
+    ip->inum = inum;
+    ip->ref = 1;
+    ip->flags = 0;
+    release(&icache.lock);
+
+    return ip;
+}
+
+__code allocinode_noloop(struct fs_impl* fs_impl, uint inum, uint dev, short type, struct superblock* sb, struct buf* bp, struct dinode* dip, __code next(int ret, ...)){ //:skip
+
+    memset(dip, 0, sizeof(*dip));
+    dip->type = type;
+    log_write(bp);
+    brelse(bp);
+
+    ret = iget(dev, inum);
+    goto next(ret, ...);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/final_main/src/iallocfs_impl.cbc	Thu Feb 13 01:50:45 2020 +0900
@@ -0,0 +1,5 @@
+#interface "fs.dg"
+
+__code iallocfs_impl(struct fs_impl* fs, uint dev, short type, __code next(...)) {
+    goto allocinode(fs, dev, sb, next(...));
+}