# HG changeset patch # User menikon # Date 1581474491 -32400 # Node ID c8adccdd011a9a693a922519f9b022c2d5cc695f # Parent 14feebd2285cfc26d10d41845dddff16bcea6ef6 add src and slide diff -r 14feebd2285c -r c8adccdd011a final_main/chapter4.tex --- a/final_main/chapter4.tex Tue Feb 11 17:30:08 2020 +0900 +++ b/final_main/chapter4.tex Wed Feb 12 11:28:11 2020 +0900 @@ -24,6 +24,8 @@ \section{FilleSystem の API} +FileSystem について記述している fs.c ではファイルを操作、管理する際に様々な関数がプロセスやデバイスなどから呼び出され使用されている。 + fs.c に存在している関数とその挙動に関して具体的に以下に示す。 %関数や構造体などを解説しそのまま利用されているところをかく %FileSystemの構造よりも重要だからこっちの方のを優先的に説明したい! \begin{itemize} @@ -35,34 +37,60 @@ \\main.c で呼び出されて使用している。 \item ialloc - \\ + \\デバイスで指定されたタイプを新しい inode に割り当てる。 + \\mkfs.c で呼び出されて使用している。 \item iupdate - + \\変更されたメモリ内の inode をディスクにコピーする。 + \\fs.c で呼び出されて使用している。 + \item idup - + \\fs.c で呼び出されて使用している。 + \item ilock - + \\指定した inode をロックする。またその際に必要であるならば、ディスクから inode を読み込む。 + \\fs.c と exec.c で呼び出されて使用している。 + \item iunlock - + \\指定された inode のロックを解除する。 + \\fs.c と exec.c で呼び出されて使用している。 + \item iput - + \\メモリ内の inode への参照を削除する。 + %それが最後の参照であった場合、iノードキャッシュエントリはリサイクルできます。それが最後の参照であり、iノードにリンクがない場合、ディスク上のiノード(およびそのコンテンツ)を解放します。 + \\fs.c で呼び出されて使用している。 + \item iunlockput - + \\指定された inode のロックを解除してから iput を実行する。 + %後でまとめる + \\fs.c と exec.c で呼び出されて使用している。 + \item stati - + \\inode から ファイルに関する統計情報を複製する。 + \\fs.c で呼び出されて使用している。 + \item readi - + \\inode からデータを読み込む。 + \\fs.c と exec.c とvm.c で呼び出されて使用している。 + \item writei - + \\inode へデータを書き込む。 + \\fs.c で呼び出されて使用している。 + \item namecmp - + \\fs.c で呼び出されて使用している。 + \item dirlookup - + \\fs.c で呼び出されて使用している。 + \item dirlink - + \\fs.c で呼び出されて使用している。 + \item namei - + \\fs.c と exec.c で呼び出されて使用している。 + %src/usr/usertests.cでも呼び出されてる?要質問 + \item nameiparent - + \\fs.c で呼び出されて使用している。 + \end{itemize} diff -r 14feebd2285c -r c8adccdd011a final_main/chapter5.tex --- a/final_main/chapter5.tex Tue Feb 11 17:30:08 2020 +0900 +++ b/final_main/chapter5.tex Wed Feb 12 11:28:11 2020 +0900 @@ -1,5 +1,9 @@ \chapter{CbCによるFileSystemの書き換え} \section{書き換え方針} +%xv6 を CbC で書き換え、Gears OS の機能と置き換えることで Gears OS に OS の基本構造を持たせたい。 +%このためには xv6 をモジュール化することで、xv6 の機能を明らかにする必要がある。 +%xv6 の Interface を定義し、Gears OS の機能をこれに合わせることによって実現したい。 + %\newpage \section{FileSystem の Interface の定義(fs.dg)} \begin{figure}[ht] @@ -17,4 +21,4 @@ \section{FileSystem の Interface の実装(fs\_impl.cbc)} -\lstinputlisting[label=fs_interface_impl, caption=FileSystem の Interface の実装]{src/fs_impl.cbc} \ No newline at end of file +\lstinputlisting[label=fs_interface_impl, caption=FileSystem の Interface の実装]{src/fs_impl1.cbc} \ No newline at end of file diff -r 14feebd2285c -r c8adccdd011a final_main/main.pdf Binary file final_main/main.pdf has changed diff -r 14feebd2285c -r c8adccdd011a final_main/src/fs_impl.cbc --- a/final_main/src/fs_impl.cbc Tue Feb 11 17:30:08 2020 +0900 +++ b/final_main/src/fs_impl.cbc Wed Feb 12 11:28:11 2020 +0900 @@ -11,16 +11,6 @@ #interface "Err.h" #interface "fs.dg" -// ---- -// typedef struct fs_impl impl fs{ -// union Data* fs_impl; -// -// -// -// -// } fs_impl; -// ---- - fs* createfs_impl(struct Context* cbc_context) { struct fs* fs = new fs(); struct fs_impl* fs_impl = new fs_impl(); @@ -133,7 +123,6 @@ log_write(bp); brelse(bp); - goto next(...); } @@ -142,7 +131,7 @@ acquire(&icache.lock); ip->ref++; release(&icache.lock); - + goto next(ip, ...); } @@ -153,7 +142,7 @@ } __code iunlockfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { - + if (ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1) { char* msg = "iunlock"; struct Err* err = createKernelError(&proc->cbc_context); @@ -173,12 +162,11 @@ if (next == C_iputfs_impl) { next = fs->next2; } - goto iput_check(fs, ip, next(...)); - + goto iput_check(fs, ip, next(...)); } -__code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { - fs->next2 = next; +__code iunlockputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + fs->next2 = next; goto iunlockfs_impl(ip, fs->iput, ...); } @@ -210,15 +198,15 @@ } __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) { + 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, ...); @@ -234,7 +222,7 @@ } __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) { + if (dp->type != T_DIR) { char* msg = "dirlookup not DIR"; struct Err* err = createKernelError(&proc->cbc_context); Gearef(cbc_context, Err)->msg = msg; @@ -245,7 +233,6 @@ } __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 - // Check that name is not present. if ((ip = dirlookup(dp, name, 0)) != 0) { goto dirlink_namecheck(fs, ip, next(...)); } @@ -259,7 +246,6 @@ acquire(&icache.lock); - // Is the inode already cached? empty = 0; for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { @@ -273,8 +259,6 @@ empty = ip; } } - - // Recycle an inode cache entry. if (empty == 0) { panic("iget: no inodes"); } @@ -344,7 +328,6 @@ } if (nameiparent && *path == '\0') { - // Stop one level early. iunlock(ip); return ip; } @@ -378,4 +361,3 @@ goto next(namex_val, ...); } - diff -r 14feebd2285c -r c8adccdd011a final_main/src/fs_impl1.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/final_main/src/fs_impl1.cbc Wed Feb 12 11:28:11 2020 +0900 @@ -0,0 +1,238 @@ +#interface "Err.h" +#interface "fs.dg" + +fs* createfs_impl(struct Context* cbc_context) { + struct fs* fs = new fs(); + struct fs_impl* fs_impl = new fs_impl(); + fs->fs = (union Data*)fs_impl; + fs_impl->fs_impl = NULL; + fs_impl->sb = NULL; + fs_impl->ret = 0; + fs_impl->dev = 0; + fs_impl->type = 0; + fs_impl->bp = NULL; + fs_impl->dip = NULL; + fs_impl->inum = 0; + fs_impl->dp = NULL; + fs_impl->name = NULL; + fs_impl->off = 0; + fs_impl->poff = NULL; + fs_impl->de = NULL; + fs_impl->tot = 0; + fs_impl->m = 0; + fs_impl->dst = NULL; + fs_impl->n = 0; + fs_impl->src = NULL; + fs_impl->allocinode = C_allocinode; + fs_impl->allocinode_loop = C_allocinode_loop; + fs_impl->allocinode_loopcheck = C_allocinode_loopcheck; + fs_impl->allocinode_noloop = C_allocinode_noloop; + fs_impl->lockinode1 = C_lockinode1; + fs_impl->lockinode2 = C_lockinode2; + fs_impl->lockinode_sleepcheck = C_lockinode_sleepcheck; + fs_impl->iput_check = C_iput_check; + fs_impl->iput_inode_nolink = C_iput_inode_nolink; + fs_impl->readi_check_diskinode = C_readi_check_diskinode; + fs_impl->readi_loopcheck = C_readi_loopcheck; + fs_impl->readi_loop = C_readi_loop; + fs_impl->readi_noloop = C_readi_noloop; + fs_impl->writei_check_diskinode = C_writei_check_diskinode; + fs_impl->writei_loopcheck = C_writei_loopcheck; + fs_impl->writei_loop = C_writei_loop; + fs_impl->writei_noloop = C_writei_noloop; + fs_impl->dirlookup_loopcheck = C_dirlookup_loopcheck; + fs_impl->dirlookup_loop = C_dirlookup_loop; + fs_impl->dirlookup_noloop = C_dirlookup_noloop; + fs_impl->dirlink_namecheck = C_dirlink_namecheck; + fs_impl->dirlink_loopcheck = C_dirlink_loopcheck; + fs_impl->dirlink_loop = C_dirlink_loop; + fs_impl->dirlink_noloop = C_dirlink_noloop; + fs->readsb = C_readsbfs_impl; + fs->iinit = C_iinitfs_impl; + fs->ialloc = C_iallocfs_impl; + fs->iupdate = C_iupdatefs_impl; + fs->idup = C_idupfs_impl; + fs->ilock = C_ilockfs_impl; + fs->iunlock = C_iunlockfs_impl; + fs->iput = C_iputfs_impl; + fs->iunlockput = C_iunlockputfs_impl; + fs->stati = C_statifs_impl; + fs->readi = C_readifs_impl; + fs->writei = C_writeifs_impl; + fs->namecmp = C_namecmpfs_impl; + fs->dirlookup = C_dirlookupfs_impl; + fs->dirlink = C_dirlinkfs_impl; + fs->namei = C_nameifs_impl; + fs->nameiparent = C_nameiparentfs_impl; + return fs; +} + +typedef struct superblock superblock; +__code readsbfs_impl(struct fs_impl* fs, uint dev, struct superblock* sb, __code next(...)) { //:skip + + struct buf* bp; + + bp = bread(dev, 1); + memmove(sb, bp->data, sizeof(*sb)); + brelse(bp); + + goto next(...); +} + +__code iinitfs_impl(struct fs_impl* fs, __code next(...)) { + + initlock(&icache.lock, "icache"); + + goto next(...); +} + +__code iallocfs_impl(struct fs_impl* fs, uint dev, short type, __code next(...)) { + goto allocinode(fs, dev, sb, next(...)); +} + +__code iupdatefs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + + struct buf *bp; + struct dinode *dip; + + bp = bread(ip->dev, IBLOCK(ip->inum)); + + dip = (struct dinode*) bp->data + ip->inum % IPB; + dip->type = ip->type; + dip->major = ip->major; + dip->minor = ip->minor; + dip->nlink = ip->nlink; + dip->size = ip->size; + + memmove(dip->addrs, ip->addrs, sizeof(ip->addrs)); + log_write(bp); + brelse(bp); + + goto next(...); +} + +__code idupfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + + acquire(&icache.lock); + ip->ref++; + release(&icache.lock); + + goto next(ip, ...); +} + +__code ilockfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + + goto lockinode1(fs, ip, bp, dip, next(...)); +} + +__code iunlockfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + + if (ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1) { + char* msg = "iunlock"; + struct Err* err = createKernelError(&proc->cbc_context); + Gearef(cbc_context, Err)->msg = msg; + goto meta(cbc_context, err->panic); + } + + acquire(&icache.lock); + ip->flags &= ~I_BUSY; + wakeup(ip); + release(&icache.lock); + + goto next(...); +} + +__code iputfs_impl(struct fs_impl* fs, struct inode* ip, __code next(...)) { + if (next == C_iputfs_impl) { + next = fs->next2; + } + 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 14feebd2285c -r c8adccdd011a final_main/src/fs_impl_private.cbc --- a/final_main/src/fs_impl_private.cbc Tue Feb 11 17:30:08 2020 +0900 +++ b/final_main/src/fs_impl_private.cbc Wed Feb 12 11:28:11 2020 +0900 @@ -19,7 +19,7 @@ __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; + Gearef(cbc_context, fs_impl)->inum = 1; goto allocinode_loopcheck(fs_impl, inum, dev, sb, bp, dip, next(...)); } @@ -44,8 +44,8 @@ if(dip->type = 0){ goto allocinode_noloop(fs_impl, inum, dev, sb, bp, dip, next(...)); } - - brelse(bp); + + brelse(bp); inum++; goto allocinode_loopcheck(fs_impl, inum, dev, type, sb, bp, dip, next(...)); } @@ -61,7 +61,6 @@ acquire(&icache.lock); - // Is the inode already cached? empty = 0; for (ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++) { @@ -76,7 +75,6 @@ } } - // Recycle an inode cache entry. if (empty == 0) { panic("iget: no inodes"); } @@ -95,9 +93,9 @@ memset(dip, 0, sizeof(*dip)); dip->type = type; - log_write(bp); + log_write(bp); brelse(bp); - + ret = iget(dev, inum); goto next(ret, ...); @@ -114,7 +112,7 @@ acquire(&icache.lock); goto lockinode_sleepcheck(fs_impl, ip, next(...)); - + } @@ -156,7 +154,7 @@ __code iput_check(struct fs_impl* fs_impl, struct inode* ip, __code next(...)){ acquire(&icache.lock); - if (ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) { + if (ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0) { goto iput_inode_nolink(fs_impl, ip, next(...)); } ip->ref--; @@ -219,23 +217,23 @@ } __code iput_inode_nolink(struct fs_impl* fs_impl, struct inode* ip, __code next(...)){ - + if (ip->flags & I_BUSY) { char* msg = "iput busy"; struct Err* err = createKernelError(&proc->cbc_context); Gearef(cbc_context, Err)->msg = msg; goto meta(cbc_context, err->panic); - } - + } + ip->flags |= I_BUSY; release(&icache.lock); itrunc(ip); ip->type = 0; iupdate(ip); - + acquire(&icache.lock); ip->flags = 0; - wakeup(ip); + wakeup(ip); goto next(...); } @@ -313,7 +311,6 @@ bn -= NDIRECT; if (bn < NINDIRECT) { - // Load indirect block, allocating if necessary. if ((addr = ip->addrs[NDIRECT]) == 0) { ip->addrs[NDIRECT] = addr = balloc(ip->dev); } @@ -340,7 +337,7 @@ memmove(dst, bp->data + off % BSIZE, m); brelse(bp); tot += m; - off += m; + off += m; dst += m; goto readi_loopcheck(fs_impl, tot, m, dst, off, n, next(...)); } @@ -369,7 +366,7 @@ __code writei_loop(struct fs_impl* fs_impl, struct inode* ip, struct buf* bp, uint tot, uint m, char* src, uint off, uint n, __code next(...)){ //:skip bp = bread(ip->dev, bmap(ip, off / BSIZE)); - m = min(n - tot, BSIZE - off%BSIZE); + m = min(n - tot, BSIZE - off%BSIZE); memmove(bp->data + off % BSIZE, src, m); log_write(bp); brelse(bp); @@ -409,7 +406,6 @@ } if (namecmp(name, de->name) == 0) { - // entry matches path element if (poff) { *poff = off; } @@ -452,7 +448,7 @@ if (de->inum == 0) { goto dirlink_noloop(fs_impl, de, dp, off, inum, name, next(...)); } - + goto dirlink_loopcheck(fs_impl, de, dp, off + sizeof(de), next(...)); } diff -r 14feebd2285c -r c8adccdd011a rewrite_xv6_FileSystem_in_CbC.mm --- a/rewrite_xv6_FileSystem_in_CbC.mm Tue Feb 11 17:30:08 2020 +0900 +++ b/rewrite_xv6_FileSystem_in_CbC.mm Wed Feb 12 11:28:11 2020 +0900 @@ -86,7 +86,7 @@ - + diff -r 14feebd2285c -r c8adccdd011a slide/thesis_slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/slide/thesis_slide.md Wed Feb 12 11:28:11 2020 +0900 @@ -0,0 +1,98 @@ +title: CbC による xv6 の FileSystem の書き換え +author: Takahiro Sakamoto, Shinji Kono + +profile: 琉球大学工学部情報工学科並列信頼研 + +## 研究目的 + + +## Continuatuin based C + +## CbC のコード例 +* CbC では Code Gear は \_\_code Code Gear 名 (引数) の形で記述される +* Code Gear は戻り値を持たないので、関数とは異なり return 文は存在しない +* goto の後に Code Gear 名と引数を並べて、次の Code Gear の遷移を記述する + +## CbC のコード例 +* この goto の行き先を継続と呼び、このときの a+b が次の Code Gear への出力となる + +``` +__code cg0(int a, int b){ + goto cg1(a+b); +} + +__code cg1(int c){ + goto cg2(c); +} +``` + + + +## Interface +* Code Gear と Data Gear は Interface と呼ばれるまとまりとして記述される +* Interface は GearsOS でのモジュール化の仕組み +* Interface は使用される Data Gear の定義と、それに対する Code Gear の集合である +* Interface の操作に対応する Code Gear の引数は Interface に定義されている Data Gear を通して行われる + +## Interface の定義 +* Stack の Interface の例である +* typedef struct Interface 名で記述する +* Impl は実際に実装した際のデータ構造の型になる + +``` +typedef struct Stack { + union Data* stack; + union Data* data; + __code next(...); + __code whenEmpty(...); + + __code clear(Impl* stack, __code next(...)); + __code push(Impl* stack, union Data* data, __code next(...)); + __code pop(Impl* stack, __code next(union Data* ...)); + __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); + +} +``` +## Interface の定義 +* Data Gear は 操作する Data Gear と +操作に必要な全ての Data Gear Gear が記述されている +* \_\_code で記述されているものが操作の Code Gear である + +``` +typedef struct Stack { + union Data* stack; + union Data* data; + __code next(...); + __code whenEmpty(...); + + __code clear(Impl* stack, __code next(...)); + __code push(Impl* stack, union Data* data, __code next(...)); + __code pop(Impl* stack, __code next(union Data* ...)); + __code isEmpty(Impl* stack, __code next(...), __code whenEmpty(...)); + +} +``` +## Interface の実装の記述 +* ソースコードは Interface の実装の初期化のコードである +* 操作の Code Gear には実装した Code Gear の番号が代入されるが、ここを入れ替えることで、複数の実装を持つことができる +``` +Stack* createSingleLinkedStack(struct Context* context) { + struct Stack* stack = new Stack(); + struct SingleLinkedStack* singleLinkedStack = new SingleLinkedStack(); + stack->stack = (union Data*)singleLinkedStack; + singleLinkedStack->top = NULL; + stack->push = C_pushSingleLinkedStack; + stack->pop = C_popSingleLinkedStack; + stack->isEmpty = C_isEmptySingleLinkedStack; + stack->clear = C_clearSingleLinkedStack; + return stack; +} +``` +## xv6 の書き換えの方針 +* xv6 を CbC で書き換え、Gears OS の機能と置き換えることで Gears OS に OS の基本構造を持たせたい +* このためには xv6 をモジュール化することで、xv6 の機能を明らかにする必要がある +* xv6 の Interface を定義し、Gears OS の機能をこれに合わせることによって実現したい + +## CbC による FileSystem の書き換え + +## まとめと今後の方針