# HG changeset patch # User menikon # Date 1581526245 -32400 # Node ID c8fee0262eada0aa181bbc70af0d623f7543503c # Parent b67e4c9f037447af6469a06d7e2c089669a9491c fix chapter5 diff -r b67e4c9f0374 -r c8fee0262ead final_main/appendix.tex --- 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 diff -r b67e4c9f0374 -r c8fee0262ead final_main/chapter5.tex --- 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} diff -r b67e4c9f0374 -r c8fee0262ead final_main/fig/iallocloop.graffle Binary file final_main/fig/iallocloop.graffle has changed diff -r b67e4c9f0374 -r c8fee0262ead final_main/fig/iallocloop.pdf Binary file final_main/fig/iallocloop.pdf has changed diff -r b67e4c9f0374 -r c8fee0262ead final_main/main.pdf Binary file final_main/main.pdf has changed diff -r b67e4c9f0374 -r c8fee0262ead final_main/main.tex --- 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} diff -r b67e4c9f0374 -r c8fee0262ead final_main/src/fs1.dg --- 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; diff -r b67e4c9f0374 -r c8fee0262ead final_main/src/fs_impl1.cbc --- 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, ...); - -} +.... diff -r b67e4c9f0374 -r c8fee0262ead final_main/src/fs_impl1.h --- 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; diff -r b67e4c9f0374 -r c8fee0262ead final_main/src/ialloc.cbc --- /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, ...); + +} diff -r b67e4c9f0374 -r c8fee0262ead final_main/src/iallocfs_impl.cbc --- /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(...)); +}