Formatted *.c files

feat/start
hheik 2024-04-29 22:15:43 +03:00
parent f5b93ef12f
commit 8102452c7f
45 changed files with 6910 additions and 7633 deletions

4
.clang-format Normal file
View File

@ -0,0 +1,4 @@
SortIncludes: Never
UseTab: Always
IndentWidth: 4
TabWidth: 4

View File

@ -13,7 +13,6 @@
// * Only one process at a time can use a buffer, // * Only one process at a time can use a buffer,
// so do not keep them longer than necessary. // so do not keep them longer than necessary.
#include "types.h" #include "types.h"
#include "param.h" #include "param.h"
#include "spinlock.h" #include "spinlock.h"
@ -33,9 +32,7 @@ struct {
struct buf head; struct buf head;
} bcache; } bcache;
void void binit(void) {
binit(void)
{
struct buf *b; struct buf *b;
initlock(&bcache.lock, "bcache"); initlock(&bcache.lock, "bcache");
@ -55,9 +52,7 @@ binit(void)
// Look through buffer cache for block on device dev. // Look through buffer cache for block on device dev.
// If not found, allocate a buffer. // If not found, allocate a buffer.
// In either case, return locked buffer. // In either case, return locked buffer.
static struct buf* static struct buf *bget(uint dev, uint blockno) {
bget(uint dev, uint blockno)
{
struct buf *b; struct buf *b;
acquire(&bcache.lock); acquire(&bcache.lock);
@ -89,9 +84,7 @@ bget(uint dev, uint blockno)
} }
// Return a locked buf with the contents of the indicated block. // Return a locked buf with the contents of the indicated block.
struct buf* struct buf *bread(uint dev, uint blockno) {
bread(uint dev, uint blockno)
{
struct buf *b; struct buf *b;
b = bget(dev, blockno); b = bget(dev, blockno);
@ -103,9 +96,7 @@ bread(uint dev, uint blockno)
} }
// Write b's contents to disk. Must be locked. // Write b's contents to disk. Must be locked.
void void bwrite(struct buf *b) {
bwrite(struct buf *b)
{
if (!holdingsleep(&b->lock)) if (!holdingsleep(&b->lock))
panic("bwrite"); panic("bwrite");
virtio_disk_rw(b, 1); virtio_disk_rw(b, 1);
@ -113,9 +104,7 @@ bwrite(struct buf *b)
// Release a locked buffer. // Release a locked buffer.
// Move to the head of the most-recently-used list. // Move to the head of the most-recently-used list.
void void brelse(struct buf *b) {
brelse(struct buf *b)
{
if (!holdingsleep(&b->lock)) if (!holdingsleep(&b->lock))
panic("brelse"); panic("brelse");
@ -136,18 +125,14 @@ brelse(struct buf *b)
release(&bcache.lock); release(&bcache.lock);
} }
void void bpin(struct buf *b) {
bpin(struct buf *b) {
acquire(&bcache.lock); acquire(&bcache.lock);
b->refcnt++; b->refcnt++;
release(&bcache.lock); release(&bcache.lock);
} }
void void bunpin(struct buf *b) {
bunpin(struct buf *b) {
acquire(&bcache.lock); acquire(&bcache.lock);
b->refcnt--; b->refcnt--;
release(&bcache.lock); release(&bcache.lock);
} }

View File

@ -30,12 +30,12 @@
// called by printf(), and to echo input characters, // called by printf(), and to echo input characters,
// but not from write(). // but not from write().
// //
void void consputc(int c) {
consputc(int c)
{
if (c == BACKSPACE) { if (c == BACKSPACE) {
// if the user typed backspace, overwrite with a space. // if the user typed backspace, overwrite with a space.
uartputc_sync('\b'); uartputc_sync(' '); uartputc_sync('\b'); uartputc_sync('\b');
uartputc_sync(' ');
uartputc_sync('\b');
} else { } else {
uartputc_sync(c); uartputc_sync(c);
} }
@ -55,9 +55,7 @@ struct {
// //
// user write()s to the console go here. // user write()s to the console go here.
// //
int int consolewrite(int user_src, uint64 src, int n) {
consolewrite(int user_src, uint64 src, int n)
{
int i; int i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@ -76,9 +74,7 @@ consolewrite(int user_src, uint64 src, int n)
// user_dist indicates whether dst is a user // user_dist indicates whether dst is a user
// or kernel address. // or kernel address.
// //
int int consoleread(int user_dst, uint64 dst, int n) {
consoleread(int user_dst, uint64 dst, int n)
{
uint target; uint target;
int c; int c;
char cbuf; char cbuf;
@ -132,9 +128,7 @@ consoleread(int user_dst, uint64 dst, int n)
// do erase/kill processing, append to cons.buf, // do erase/kill processing, append to cons.buf,
// wake up consoleread() if a whole line has arrived. // wake up consoleread() if a whole line has arrived.
// //
void void consoleintr(int c) {
consoleintr(int c)
{
acquire(&cons.lock); acquire(&cons.lock);
switch (c) { switch (c) {
@ -178,9 +172,7 @@ consoleintr(int c)
release(&cons.lock); release(&cons.lock);
} }
void void consoleinit(void) {
consoleinit(void)
{
initlock(&cons.lock, "cons"); initlock(&cons.lock, "cons");
uartinit(); uartinit();

View File

@ -9,8 +9,7 @@
static int loadseg(pde_t *, uint64, struct inode *, uint, uint); static int loadseg(pde_t *, uint64, struct inode *, uint, uint);
int flags2perm(int flags) int flags2perm(int flags) {
{
int perm = 0; int perm = 0;
if (flags & 0x1) if (flags & 0x1)
perm = PTE_X; perm = PTE_X;
@ -19,9 +18,7 @@ int flags2perm(int flags)
return perm; return perm;
} }
int int exec(char *path, char **argv) {
exec(char *path, char **argv)
{
char *s, *last; char *s, *last;
int i, off; int i, off;
uint64 argc, sz = 0, sp, ustack[MAXARG], stackbase; uint64 argc, sz = 0, sp, ustack[MAXARG], stackbase;
@ -62,7 +59,8 @@ exec(char *path, char **argv)
if (ph.vaddr % PGSIZE != 0) if (ph.vaddr % PGSIZE != 0)
goto bad; goto bad;
uint64 sz1; uint64 sz1;
if((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz, flags2perm(ph.flags))) == 0) if ((sz1 = uvmalloc(pagetable, sz, ph.vaddr + ph.memsz,
flags2perm(ph.flags))) == 0)
goto bad; goto bad;
sz = sz1; sz = sz1;
if (loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0) if (loadseg(pagetable, ph.vaddr, ip, ph.off, ph.filesz) < 0)
@ -144,9 +142,8 @@ exec(char *path, char **argv)
// va must be page-aligned // va must be page-aligned
// and the pages from va to va+sz must already be mapped. // and the pages from va to va+sz must already be mapped.
// Returns 0 on success, -1 on failure. // Returns 0 on success, -1 on failure.
static int static int loadseg(pagetable_t pagetable, uint64 va, struct inode *ip,
loadseg(pagetable_t pagetable, uint64 va, struct inode *ip, uint offset, uint sz) uint offset, uint sz) {
{
uint i, n; uint i, n;
uint64 pa; uint64 pa;

View File

@ -19,16 +19,10 @@ struct {
struct file file[NFILE]; struct file file[NFILE];
} ftable; } ftable;
void void fileinit(void) { initlock(&ftable.lock, "ftable"); }
fileinit(void)
{
initlock(&ftable.lock, "ftable");
}
// Allocate a file structure. // Allocate a file structure.
struct file* struct file *filealloc(void) {
filealloc(void)
{
struct file *f; struct file *f;
acquire(&ftable.lock); acquire(&ftable.lock);
@ -44,9 +38,7 @@ filealloc(void)
} }
// Increment ref count for file f. // Increment ref count for file f.
struct file* struct file *filedup(struct file *f) {
filedup(struct file *f)
{
acquire(&ftable.lock); acquire(&ftable.lock);
if (f->ref < 1) if (f->ref < 1)
panic("filedup"); panic("filedup");
@ -56,9 +48,7 @@ filedup(struct file *f)
} }
// Close file f. (Decrement ref count, close when reaches 0.) // Close file f. (Decrement ref count, close when reaches 0.)
void void fileclose(struct file *f) {
fileclose(struct file *f)
{
struct file ff; struct file ff;
acquire(&ftable.lock); acquire(&ftable.lock);
@ -84,9 +74,7 @@ fileclose(struct file *f)
// Get metadata about file f. // Get metadata about file f.
// addr is a user virtual address, pointing to a struct stat. // addr is a user virtual address, pointing to a struct stat.
int int filestat(struct file *f, uint64 addr) {
filestat(struct file *f, uint64 addr)
{
struct proc *p = myproc(); struct proc *p = myproc();
struct stat st; struct stat st;
@ -103,9 +91,7 @@ filestat(struct file *f, uint64 addr)
// Read from file f. // Read from file f.
// addr is a user virtual address. // addr is a user virtual address.
int int fileread(struct file *f, uint64 addr, int n) {
fileread(struct file *f, uint64 addr, int n)
{
int r = 0; int r = 0;
if (f->readable == 0) if (f->readable == 0)
@ -131,9 +117,7 @@ fileread(struct file *f, uint64 addr, int n)
// Write to file f. // Write to file f.
// addr is a user virtual address. // addr is a user virtual address.
int int filewrite(struct file *f, uint64 addr, int n) {
filewrite(struct file *f, uint64 addr, int n)
{
int r, ret = 0; int r, ret = 0;
if (f->writable == 0) if (f->writable == 0)
@ -179,4 +163,3 @@ filewrite(struct file *f, uint64 addr, int n)
return ret; return ret;
} }

View File

@ -27,9 +27,7 @@
struct superblock sb; struct superblock sb;
// Read the super block. // Read the super block.
static void static void readsb(int dev, struct superblock *sb) {
readsb(int dev, struct superblock *sb)
{
struct buf *bp; struct buf *bp;
bp = bread(dev, 1); bp = bread(dev, 1);
@ -38,8 +36,7 @@ readsb(int dev, struct superblock *sb)
} }
// Init fs // Init fs
void void fsinit(int dev) {
fsinit(int dev) {
readsb(dev, &sb); readsb(dev, &sb);
if (sb.magic != FSMAGIC) if (sb.magic != FSMAGIC)
panic("invalid file system"); panic("invalid file system");
@ -47,9 +44,7 @@ fsinit(int dev) {
} }
// Zero a block. // Zero a block.
static void static void bzero(int dev, int bno) {
bzero(int dev, int bno)
{
struct buf *bp; struct buf *bp;
bp = bread(dev, bno); bp = bread(dev, bno);
@ -62,9 +57,7 @@ bzero(int dev, int bno)
// Allocate a zeroed disk block. // Allocate a zeroed disk block.
// returns 0 if out of disk space. // returns 0 if out of disk space.
static uint static uint balloc(uint dev) {
balloc(uint dev)
{
int b, bi, m; int b, bi, m;
struct buf *bp; struct buf *bp;
@ -88,9 +81,7 @@ balloc(uint dev)
} }
// Free a disk block. // Free a disk block.
static void static void bfree(int dev, uint b) {
bfree(int dev, uint b)
{
struct buf *bp; struct buf *bp;
int bi, m; int bi, m;
@ -178,9 +169,7 @@ struct {
struct inode inode[NINODE]; struct inode inode[NINODE];
} itable; } itable;
void void iinit() {
iinit()
{
int i = 0; int i = 0;
initlock(&itable.lock, "itable"); initlock(&itable.lock, "itable");
@ -195,9 +184,7 @@ static struct inode* iget(uint dev, uint inum);
// Mark it as allocated by giving it type type. // Mark it as allocated by giving it type type.
// Returns an unlocked but allocated and referenced inode, // Returns an unlocked but allocated and referenced inode,
// or NULL if there is no free inode. // or NULL if there is no free inode.
struct inode* struct inode *ialloc(uint dev, short type) {
ialloc(uint dev, short type)
{
int inum; int inum;
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
@ -222,9 +209,7 @@ ialloc(uint dev, short type)
// Must be called after every change to an ip->xxx field // Must be called after every change to an ip->xxx field
// that lives on disk. // that lives on disk.
// Caller must hold ip->lock. // Caller must hold ip->lock.
void void iupdate(struct inode *ip) {
iupdate(struct inode *ip)
{
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
@ -243,9 +228,7 @@ iupdate(struct inode *ip)
// Find the inode with number inum on device dev // Find the inode with number inum on device dev
// and return the in-memory copy. Does not lock // and return the in-memory copy. Does not lock
// the inode and does not read it from disk. // the inode and does not read it from disk.
static struct inode* static struct inode *iget(uint dev, uint inum) {
iget(uint dev, uint inum)
{
struct inode *ip, *empty; struct inode *ip, *empty;
acquire(&itable.lock); acquire(&itable.lock);
@ -278,9 +261,7 @@ iget(uint dev, uint inum)
// Increment reference count for ip. // Increment reference count for ip.
// Returns ip to enable ip = idup(ip1) idiom. // Returns ip to enable ip = idup(ip1) idiom.
struct inode* struct inode *idup(struct inode *ip) {
idup(struct inode *ip)
{
acquire(&itable.lock); acquire(&itable.lock);
ip->ref++; ip->ref++;
release(&itable.lock); release(&itable.lock);
@ -289,9 +270,7 @@ idup(struct inode *ip)
// Lock the given inode. // Lock the given inode.
// Reads the inode from disk if necessary. // Reads the inode from disk if necessary.
void void ilock(struct inode *ip) {
ilock(struct inode *ip)
{
struct buf *bp; struct buf *bp;
struct dinode *dip; struct dinode *dip;
@ -317,9 +296,7 @@ ilock(struct inode *ip)
} }
// Unlock the given inode. // Unlock the given inode.
void void iunlock(struct inode *ip) {
iunlock(struct inode *ip)
{
if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1) if (ip == 0 || !holdingsleep(&ip->lock) || ip->ref < 1)
panic("iunlock"); panic("iunlock");
@ -333,9 +310,7 @@ iunlock(struct inode *ip)
// to it, free the inode (and its content) on disk. // to it, free the inode (and its content) on disk.
// All calls to iput() must be inside a transaction in // All calls to iput() must be inside a transaction in
// case it has to free the inode. // case it has to free the inode.
void void iput(struct inode *ip) {
iput(struct inode *ip)
{
acquire(&itable.lock); acquire(&itable.lock);
if (ip->ref == 1 && ip->valid && ip->nlink == 0) { if (ip->ref == 1 && ip->valid && ip->nlink == 0) {
@ -362,9 +337,7 @@ iput(struct inode *ip)
} }
// Common idiom: unlock, then put. // Common idiom: unlock, then put.
void void iunlockput(struct inode *ip) {
iunlockput(struct inode *ip)
{
iunlock(ip); iunlock(ip);
iput(ip); iput(ip);
} }
@ -379,9 +352,7 @@ iunlockput(struct inode *ip)
// Return the disk block address of the nth block in inode ip. // Return the disk block address of the nth block in inode ip.
// If there is no such block, bmap allocates one. // If there is no such block, bmap allocates one.
// returns 0 if out of disk space. // returns 0 if out of disk space.
static uint static uint bmap(struct inode *ip, uint bn) {
bmap(struct inode *ip, uint bn)
{
uint addr, *a; uint addr, *a;
struct buf *bp; struct buf *bp;
@ -422,9 +393,7 @@ bmap(struct inode *ip, uint bn)
// Truncate inode (discard contents). // Truncate inode (discard contents).
// Caller must hold ip->lock. // Caller must hold ip->lock.
void void itrunc(struct inode *ip) {
itrunc(struct inode *ip)
{
int i, j; int i, j;
struct buf *bp; struct buf *bp;
uint *a; uint *a;
@ -454,9 +423,7 @@ itrunc(struct inode *ip)
// Copy stat information from inode. // Copy stat information from inode.
// Caller must hold ip->lock. // Caller must hold ip->lock.
void void stati(struct inode *ip, struct stat *st) {
stati(struct inode *ip, struct stat *st)
{
st->dev = ip->dev; st->dev = ip->dev;
st->ino = ip->inum; st->ino = ip->inum;
st->type = ip->type; st->type = ip->type;
@ -468,9 +435,7 @@ stati(struct inode *ip, struct stat *st)
// Caller must hold ip->lock. // Caller must hold ip->lock.
// If user_dst==1, then dst is a user virtual address; // If user_dst==1, then dst is a user virtual address;
// otherwise, dst is a kernel address. // otherwise, dst is a kernel address.
int int readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n) {
readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
{
uint tot, m; uint tot, m;
struct buf *bp; struct buf *bp;
@ -502,9 +467,7 @@ readi(struct inode *ip, int user_dst, uint64 dst, uint off, uint n)
// Returns the number of bytes successfully written. // Returns the number of bytes successfully written.
// If the return value is less than the requested n, // If the return value is less than the requested n,
// there was an error of some kind. // there was an error of some kind.
int int writei(struct inode *ip, int user_src, uint64 src, uint off, uint n) {
writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
{
uint tot, m; uint tot, m;
struct buf *bp; struct buf *bp;
@ -540,17 +503,11 @@ writei(struct inode *ip, int user_src, uint64 src, uint off, uint n)
// Directories // Directories
int int namecmp(const char *s, const char *t) { return strncmp(s, t, DIRSIZ); }
namecmp(const char *s, const char *t)
{
return strncmp(s, t, DIRSIZ);
}
// Look for a directory entry in a directory. // Look for a directory entry in a directory.
// If found, set *poff to byte offset of entry. // If found, set *poff to byte offset of entry.
struct inode* struct inode *dirlookup(struct inode *dp, char *name, uint *poff) {
dirlookup(struct inode *dp, char *name, uint *poff)
{
uint off, inum; uint off, inum;
struct dirent de; struct dirent de;
@ -576,9 +533,7 @@ dirlookup(struct inode *dp, char *name, uint *poff)
// Write a new directory entry (name, inum) into the directory dp. // Write a new directory entry (name, inum) into the directory dp.
// Returns 0 on success, -1 on failure (e.g. out of disk blocks). // Returns 0 on success, -1 on failure (e.g. out of disk blocks).
int int dirlink(struct inode *dp, char *name, uint inum) {
dirlink(struct inode *dp, char *name, uint inum)
{
int off; int off;
struct dirent de; struct dirent de;
struct inode *ip; struct inode *ip;
@ -619,9 +574,7 @@ dirlink(struct inode *dp, char *name, uint inum)
// skipelem("a", name) = "", setting name = "a" // skipelem("a", name) = "", setting name = "a"
// skipelem("", name) = skipelem("////", name) = 0 // skipelem("", name) = skipelem("////", name) = 0
// //
static char* static char *skipelem(char *path, char *name) {
skipelem(char *path, char *name)
{
char *s; char *s;
int len; int len;
@ -648,9 +601,7 @@ skipelem(char *path, char *name)
// If parent != 0, return the inode for the parent and copy the final // If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes. // path element into name, which must have room for DIRSIZ bytes.
// Must be called inside a transaction since it calls iput(). // Must be called inside a transaction since it calls iput().
static struct inode* static struct inode *namex(char *path, int nameiparent, char *name) {
namex(char *path, int nameiparent, char *name)
{
struct inode *ip, *next; struct inode *ip, *next;
if (*path == '/') if (*path == '/')
@ -683,15 +634,11 @@ namex(char *path, int nameiparent, char *name)
return ip; return ip;
} }
struct inode* struct inode *namei(char *path) {
namei(char *path)
{
char name[DIRSIZ]; char name[DIRSIZ];
return namex(path, 0, name); return namex(path, 0, name);
} }
struct inode* struct inode *nameiparent(char *path, char *name) {
nameiparent(char *path, char *name)
{
return namex(path, 1, name); return namex(path, 1, name);
} }

View File

@ -23,16 +23,12 @@ struct {
struct run *freelist; struct run *freelist;
} kmem; } kmem;
void void kinit() {
kinit()
{
initlock(&kmem.lock, "kmem"); initlock(&kmem.lock, "kmem");
freerange(end, (void *)PHYSTOP); freerange(end, (void *)PHYSTOP);
} }
void void freerange(void *pa_start, void *pa_end) {
freerange(void *pa_start, void *pa_end)
{
char *p; char *p;
p = (char *)PGROUNDUP((uint64)pa_start); p = (char *)PGROUNDUP((uint64)pa_start);
for (; p + PGSIZE <= (char *)pa_end; p += PGSIZE) for (; p + PGSIZE <= (char *)pa_end; p += PGSIZE)
@ -43,9 +39,7 @@ freerange(void *pa_start, void *pa_end)
// which normally should have been returned by a // which normally should have been returned by a
// call to kalloc(). (The exception is when // call to kalloc(). (The exception is when
// initializing the allocator; see kinit above.) // initializing the allocator; see kinit above.)
void void kfree(void *pa) {
kfree(void *pa)
{
struct run *r; struct run *r;
if (((uint64)pa % PGSIZE) != 0 || (char *)pa < end || (uint64)pa >= PHYSTOP) if (((uint64)pa % PGSIZE) != 0 || (char *)pa < end || (uint64)pa >= PHYSTOP)
@ -65,9 +59,7 @@ kfree(void *pa)
// Allocate one 4096-byte page of physical memory. // Allocate one 4096-byte page of physical memory.
// Returns a pointer that the kernel can use. // Returns a pointer that the kernel can use.
// Returns 0 if the memory cannot be allocated. // Returns 0 if the memory cannot be allocated.
void * void *kalloc(void) {
kalloc(void)
{
struct run *r; struct run *r;
acquire(&kmem.lock); acquire(&kmem.lock);

View File

@ -51,9 +51,7 @@ struct log log;
static void recover_from_log(void); static void recover_from_log(void);
static void commit(); static void commit();
void void initlog(int dev, struct superblock *sb) {
initlog(int dev, struct superblock *sb)
{
if (sizeof(struct logheader) >= BSIZE) if (sizeof(struct logheader) >= BSIZE)
panic("initlog: too big logheader"); panic("initlog: too big logheader");
@ -65,13 +63,12 @@ initlog(int dev, struct superblock *sb)
} }
// Copy committed blocks from log to their home location // Copy committed blocks from log to their home location
static void static void install_trans(int recovering) {
install_trans(int recovering)
{
int tail; int tail;
for (tail = 0; tail < log.lh.n; tail++) { for (tail = 0; tail < log.lh.n; tail++) {
struct buf *lbuf = bread(log.dev, log.start+tail+1); // read log block struct buf *lbuf =
bread(log.dev, log.start + tail + 1); // read log block
struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst struct buf *dbuf = bread(log.dev, log.lh.block[tail]); // read dst
memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst memmove(dbuf->data, lbuf->data, BSIZE); // copy block to dst
bwrite(dbuf); // write dst to disk bwrite(dbuf); // write dst to disk
@ -83,9 +80,7 @@ install_trans(int recovering)
} }
// Read the log header from disk into the in-memory log header // Read the log header from disk into the in-memory log header
static void static void read_head(void) {
read_head(void)
{
struct buf *buf = bread(log.dev, log.start); struct buf *buf = bread(log.dev, log.start);
struct logheader *lh = (struct logheader *)(buf->data); struct logheader *lh = (struct logheader *)(buf->data);
int i; int i;
@ -99,9 +94,7 @@ read_head(void)
// Write in-memory log header to disk. // Write in-memory log header to disk.
// This is the true point at which the // This is the true point at which the
// current transaction commits. // current transaction commits.
static void static void write_head(void) {
write_head(void)
{
struct buf *buf = bread(log.dev, log.start); struct buf *buf = bread(log.dev, log.start);
struct logheader *hb = (struct logheader *)(buf->data); struct logheader *hb = (struct logheader *)(buf->data);
int i; int i;
@ -113,9 +106,7 @@ write_head(void)
brelse(buf); brelse(buf);
} }
static void static void recover_from_log(void) {
recover_from_log(void)
{
read_head(); read_head();
install_trans(1); // if committed, copy from log to disk install_trans(1); // if committed, copy from log to disk
log.lh.n = 0; log.lh.n = 0;
@ -123,9 +114,7 @@ recover_from_log(void)
} }
// called at the start of each FS system call. // called at the start of each FS system call.
void void begin_op(void) {
begin_op(void)
{
acquire(&log.lock); acquire(&log.lock);
while (1) { while (1) {
if (log.committing) { if (log.committing) {
@ -143,9 +132,7 @@ begin_op(void)
// called at the end of each FS system call. // called at the end of each FS system call.
// commits if this was the last outstanding operation. // commits if this was the last outstanding operation.
void void end_op(void) {
end_op(void)
{
int do_commit = 0; int do_commit = 0;
acquire(&log.lock); acquire(&log.lock);
@ -175,9 +162,7 @@ end_op(void)
} }
// Copy modified blocks from cache to log. // Copy modified blocks from cache to log.
static void static void write_log(void) {
write_log(void)
{
int tail; int tail;
for (tail = 0; tail < log.lh.n; tail++) { for (tail = 0; tail < log.lh.n; tail++) {
@ -190,9 +175,7 @@ write_log(void)
} }
} }
static void static void commit() {
commit()
{
if (log.lh.n > 0) { if (log.lh.n > 0) {
write_log(); // Write modified blocks from cache to log write_log(); // Write modified blocks from cache to log
write_head(); // Write header to disk -- the real commit write_head(); // Write header to disk -- the real commit
@ -211,9 +194,7 @@ commit()
// modify bp->data[] // modify bp->data[]
// log_write(bp) // log_write(bp)
// brelse(bp) // brelse(bp)
void void log_write(struct buf *b) {
log_write(struct buf *b)
{
int i; int i;
acquire(&log.lock); acquire(&log.lock);
@ -233,4 +214,3 @@ log_write(struct buf *b)
} }
release(&log.lock); release(&log.lock);
} }

View File

@ -7,14 +7,13 @@
volatile static int started = 0; volatile static int started = 0;
// start() jumps here in supervisor mode on all CPUs. // start() jumps here in supervisor mode on all CPUs.
void void main() {
main()
{
if (cpuid() == 0) { if (cpuid() == 0) {
consoleinit(); consoleinit();
printfinit(); printfinit();
printf("\n"); printf("\n");
printf("xv6 kernel is booting\n"); printf("xv6 kernel is booting\n");
// printf("rustlib: add(1, 2) = %d\n", add(1, 2));
printf("\n"); printf("\n");
kinit(); // physical page allocator kinit(); // physical page allocator
kvminit(); // create kernel page table kvminit(); // create kernel page table

View File

@ -19,9 +19,7 @@ struct pipe {
int writeopen; // write fd is still open int writeopen; // write fd is still open
}; };
int int pipealloc(struct file **f0, struct file **f1) {
pipealloc(struct file **f0, struct file **f1)
{
struct pipe *pi; struct pipe *pi;
pi = 0; pi = 0;
@ -55,9 +53,7 @@ pipealloc(struct file **f0, struct file **f1)
return -1; return -1;
} }
void void pipeclose(struct pipe *pi, int writable) {
pipeclose(struct pipe *pi, int writable)
{
acquire(&pi->lock); acquire(&pi->lock);
if (writable) { if (writable) {
pi->writeopen = 0; pi->writeopen = 0;
@ -73,9 +69,7 @@ pipeclose(struct pipe *pi, int writable)
release(&pi->lock); release(&pi->lock);
} }
int int pipewrite(struct pipe *pi, uint64 addr, int n) {
pipewrite(struct pipe *pi, uint64 addr, int n)
{
int i = 0; int i = 0;
struct proc *pr = myproc(); struct proc *pr = myproc();
@ -102,9 +96,7 @@ pipewrite(struct pipe *pi, uint64 addr, int n)
return i; return i;
} }
int int piperead(struct pipe *pi, uint64 addr, int n) {
piperead(struct pipe *pi, uint64 addr, int n)
{
int i; int i;
struct proc *pr = myproc(); struct proc *pr = myproc();
char ch; char ch;

View File

@ -8,17 +8,13 @@
// the riscv Platform Level Interrupt Controller (PLIC). // the riscv Platform Level Interrupt Controller (PLIC).
// //
void void plicinit(void) {
plicinit(void)
{
// set desired IRQ priorities non-zero (otherwise disabled). // set desired IRQ priorities non-zero (otherwise disabled).
*(uint32 *)(PLIC + UART0_IRQ * 4) = 1; *(uint32 *)(PLIC + UART0_IRQ * 4) = 1;
*(uint32 *)(PLIC + VIRTIO0_IRQ * 4) = 1; *(uint32 *)(PLIC + VIRTIO0_IRQ * 4) = 1;
} }
void void plicinithart(void) {
plicinithart(void)
{
int hart = cpuid(); int hart = cpuid();
// set enable bits for this hart's S-mode // set enable bits for this hart's S-mode
@ -30,18 +26,14 @@ plicinithart(void)
} }
// ask the PLIC what interrupt we should serve. // ask the PLIC what interrupt we should serve.
int int plic_claim(void) {
plic_claim(void)
{
int hart = cpuid(); int hart = cpuid();
int irq = *(uint32 *)PLIC_SCLAIM(hart); int irq = *(uint32 *)PLIC_SCLAIM(hart);
return irq; return irq;
} }
// tell the PLIC we've served this IRQ. // tell the PLIC we've served this IRQ.
void void plic_complete(int irq) {
plic_complete(int irq)
{
int hart = cpuid(); int hart = cpuid();
*(uint32 *)PLIC_SCLAIM(hart) = irq; *(uint32 *)PLIC_SCLAIM(hart) = irq;
} }

View File

@ -25,9 +25,7 @@ static struct {
static char digits[] = "0123456789abcdef"; static char digits[] = "0123456789abcdef";
static void static void printint(int xx, int base, int sign) {
printint(int xx, int base, int sign)
{
char buf[16]; char buf[16];
int i; int i;
uint x; uint x;
@ -49,9 +47,7 @@ printint(int xx, int base, int sign)
consputc(buf[i]); consputc(buf[i]);
} }
static void static void printptr(uint64 x) {
printptr(uint64 x)
{
int i; int i;
consputc('0'); consputc('0');
consputc('x'); consputc('x');
@ -60,9 +56,7 @@ printptr(uint64 x)
} }
// Print to the console. only understands %d, %x, %p, %s. // Print to the console. only understands %d, %x, %p, %s.
void void printf(char *fmt, ...) {
printf(char *fmt, ...)
{
va_list ap; va_list ap;
int i, c, locking; int i, c, locking;
char *s; char *s;
@ -115,9 +109,7 @@ printf(char *fmt, ...)
release(&pr.lock); release(&pr.lock);
} }
void void panic(char *s) {
panic(char *s)
{
pr.locking = 0; pr.locking = 0;
printf("panic: "); printf("panic: ");
printf(s); printf(s);
@ -127,9 +119,7 @@ panic(char *s)
; ;
} }
void void printfinit(void) {
printfinit(void)
{
initlock(&pr.lock, "pr"); initlock(&pr.lock, "pr");
pr.locking = 1; pr.locking = 1;
} }

View File

@ -29,9 +29,7 @@ struct spinlock wait_lock;
// Allocate a page for each process's kernel stack. // Allocate a page for each process's kernel stack.
// Map it high in memory, followed by an invalid // Map it high in memory, followed by an invalid
// guard page. // guard page.
void void proc_mapstacks(pagetable_t kpgtbl) {
proc_mapstacks(pagetable_t kpgtbl)
{
struct proc *p; struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) { for (p = proc; p < &proc[NPROC]; p++) {
@ -44,9 +42,7 @@ proc_mapstacks(pagetable_t kpgtbl)
} }
// initialize the proc table. // initialize the proc table.
void void procinit(void) {
procinit(void)
{
struct proc *p; struct proc *p;
initlock(&pid_lock, "nextpid"); initlock(&pid_lock, "nextpid");
@ -61,27 +57,21 @@ procinit(void)
// Must be called with interrupts disabled, // Must be called with interrupts disabled,
// to prevent race with process being moved // to prevent race with process being moved
// to a different CPU. // to a different CPU.
int int cpuid() {
cpuid()
{
int id = r_tp(); int id = r_tp();
return id; return id;
} }
// Return this CPU's cpu struct. // Return this CPU's cpu struct.
// Interrupts must be disabled. // Interrupts must be disabled.
struct cpu* struct cpu *mycpu(void) {
mycpu(void)
{
int id = cpuid(); int id = cpuid();
struct cpu *c = &cpus[id]; struct cpu *c = &cpus[id];
return c; return c;
} }
// Return the current struct proc *, or zero if none. // Return the current struct proc *, or zero if none.
struct proc* struct proc *myproc(void) {
myproc(void)
{
push_off(); push_off();
struct cpu *c = mycpu(); struct cpu *c = mycpu();
struct proc *p = c->proc; struct proc *p = c->proc;
@ -89,9 +79,7 @@ myproc(void)
return p; return p;
} }
int int allocpid() {
allocpid()
{
int pid; int pid;
acquire(&pid_lock); acquire(&pid_lock);
@ -106,9 +94,7 @@ allocpid()
// If found, initialize state required to run in the kernel, // If found, initialize state required to run in the kernel,
// and return with p->lock held. // and return with p->lock held.
// If there are no free procs, or a memory allocation fails, return 0. // If there are no free procs, or a memory allocation fails, return 0.
static struct proc* static struct proc *allocproc(void) {
allocproc(void)
{
struct proc *p; struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) { for (p = proc; p < &proc[NPROC]; p++) {
@ -152,9 +138,7 @@ found:
// free a proc structure and the data hanging from it, // free a proc structure and the data hanging from it,
// including user pages. // including user pages.
// p->lock must be held. // p->lock must be held.
static void static void freeproc(struct proc *p) {
freeproc(struct proc *p)
{
if (p->trapframe) if (p->trapframe)
kfree((void *)p->trapframe); kfree((void *)p->trapframe);
p->trapframe = 0; p->trapframe = 0;
@ -173,9 +157,7 @@ freeproc(struct proc *p)
// Create a user page table for a given process, with no user memory, // Create a user page table for a given process, with no user memory,
// but with trampoline and trapframe pages. // but with trampoline and trapframe pages.
pagetable_t pagetable_t proc_pagetable(struct proc *p) {
proc_pagetable(struct proc *p)
{
pagetable_t pagetable; pagetable_t pagetable;
// An empty page table. // An empty page table.
@ -187,16 +169,16 @@ proc_pagetable(struct proc *p)
// at the highest user virtual address. // at the highest user virtual address.
// only the supervisor uses it, on the way // only the supervisor uses it, on the way
// to/from user space, so not PTE_U. // to/from user space, so not PTE_U.
if(mappages(pagetable, TRAMPOLINE, PGSIZE, if (mappages(pagetable, TRAMPOLINE, PGSIZE, (uint64)trampoline,
(uint64)trampoline, PTE_R | PTE_X) < 0){ PTE_R | PTE_X) < 0) {
uvmfree(pagetable, 0); uvmfree(pagetable, 0);
return 0; return 0;
} }
// map the trapframe page just below the trampoline page, for // map the trapframe page just below the trampoline page, for
// trampoline.S. // trampoline.S.
if(mappages(pagetable, TRAPFRAME, PGSIZE, if (mappages(pagetable, TRAPFRAME, PGSIZE, (uint64)(p->trapframe),
(uint64)(p->trapframe), PTE_R | PTE_W) < 0){ PTE_R | PTE_W) < 0) {
uvmunmap(pagetable, TRAMPOLINE, 1, 0); uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmfree(pagetable, 0); uvmfree(pagetable, 0);
return 0; return 0;
@ -207,9 +189,7 @@ proc_pagetable(struct proc *p)
// Free a process's page table, and free the // Free a process's page table, and free the
// physical memory it refers to. // physical memory it refers to.
void void proc_freepagetable(pagetable_t pagetable, uint64 sz) {
proc_freepagetable(pagetable_t pagetable, uint64 sz)
{
uvmunmap(pagetable, TRAMPOLINE, 1, 0); uvmunmap(pagetable, TRAMPOLINE, 1, 0);
uvmunmap(pagetable, TRAPFRAME, 1, 0); uvmunmap(pagetable, TRAPFRAME, 1, 0);
uvmfree(pagetable, sz); uvmfree(pagetable, sz);
@ -218,20 +198,15 @@ proc_freepagetable(pagetable_t pagetable, uint64 sz)
// a user program that calls exec("/init") // a user program that calls exec("/init")
// assembled from ../user/initcode.S // assembled from ../user/initcode.S
// od -t xC ../user/initcode // od -t xC ../user/initcode
uchar initcode[] = { uchar initcode[] = {0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x45, 0x02, 0x97,
0x17, 0x05, 0x00, 0x00, 0x13, 0x05, 0x45, 0x02, 0x05, 0x00, 0x00, 0x93, 0x85, 0x35, 0x02, 0x93, 0x08,
0x97, 0x05, 0x00, 0x00, 0x93, 0x85, 0x35, 0x02, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x93, 0x08, 0x20,
0x93, 0x08, 0x70, 0x00, 0x73, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xef, 0xf0, 0x9f, 0xff,
0x93, 0x08, 0x20, 0x00, 0x73, 0x00, 0x00, 0x00, 0x2f, 0x69, 0x6e, 0x69, 0x74, 0x00, 0x00, 0x24, 0x00,
0xef, 0xf0, 0x9f, 0xff, 0x2f, 0x69, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
0x74, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00
};
// Set up first user process. // Set up first user process.
void void userinit(void) {
userinit(void)
{
struct proc *p; struct proc *p;
p = allocproc(); p = allocproc();
@ -256,9 +231,7 @@ userinit(void)
// Grow or shrink user memory by n bytes. // Grow or shrink user memory by n bytes.
// Return 0 on success, -1 on failure. // Return 0 on success, -1 on failure.
int int growproc(int n) {
growproc(int n)
{
uint64 sz; uint64 sz;
struct proc *p = myproc(); struct proc *p = myproc();
@ -276,9 +249,7 @@ growproc(int n)
// Create a new process, copying the parent. // Create a new process, copying the parent.
// Sets up child kernel stack to return as if from fork() system call. // Sets up child kernel stack to return as if from fork() system call.
int int fork(void) {
fork(void)
{
int i, pid; int i, pid;
struct proc *np; struct proc *np;
struct proc *p = myproc(); struct proc *p = myproc();
@ -327,9 +298,7 @@ fork(void)
// Pass p's abandoned children to init. // Pass p's abandoned children to init.
// Caller must hold wait_lock. // Caller must hold wait_lock.
void void reparent(struct proc *p) {
reparent(struct proc *p)
{
struct proc *pp; struct proc *pp;
for (pp = proc; pp < &proc[NPROC]; pp++) { for (pp = proc; pp < &proc[NPROC]; pp++) {
@ -343,9 +312,7 @@ reparent(struct proc *p)
// Exit the current process. Does not return. // Exit the current process. Does not return.
// An exited process remains in the zombie state // An exited process remains in the zombie state
// until its parent calls wait(). // until its parent calls wait().
void void exit(int status) {
exit(int status)
{
struct proc *p = myproc(); struct proc *p = myproc();
if (p == initproc) if (p == initproc)
@ -387,9 +354,7 @@ exit(int status)
// Wait for a child process to exit and return its pid. // Wait for a child process to exit and return its pid.
// Return -1 if this process has no children. // Return -1 if this process has no children.
int int wait(uint64 addr) {
wait(uint64 addr)
{
struct proc *pp; struct proc *pp;
int havekids, pid; int havekids, pid;
struct proc *p = myproc(); struct proc *p = myproc();
@ -408,7 +373,8 @@ wait(uint64 addr)
if (pp->state == ZOMBIE) { if (pp->state == ZOMBIE) {
// Found one. // Found one.
pid = pp->pid; pid = pp->pid;
if(addr != 0 && copyout(p->pagetable, addr, (char *)&pp->xstate, if (addr != 0 &&
copyout(p->pagetable, addr, (char *)&pp->xstate,
sizeof(pp->xstate)) < 0) { sizeof(pp->xstate)) < 0) {
release(&pp->lock); release(&pp->lock);
release(&wait_lock); release(&wait_lock);
@ -441,9 +407,7 @@ wait(uint64 addr)
// - swtch to start running that process. // - swtch to start running that process.
// - eventually that process transfers control // - eventually that process transfers control
// via swtch back to the scheduler. // via swtch back to the scheduler.
void void scheduler(void) {
scheduler(void)
{
struct proc *p; struct proc *p;
struct cpu *c = mycpu(); struct cpu *c = mycpu();
@ -478,9 +442,7 @@ scheduler(void)
// be proc->intena and proc->noff, but that would // be proc->intena and proc->noff, but that would
// break in the few places where a lock is held but // break in the few places where a lock is held but
// there's no process. // there's no process.
void void sched(void) {
sched(void)
{
int intena; int intena;
struct proc *p = myproc(); struct proc *p = myproc();
@ -499,9 +461,7 @@ sched(void)
} }
// Give up the CPU for one scheduling round. // Give up the CPU for one scheduling round.
void void yield(void) {
yield(void)
{
struct proc *p = myproc(); struct proc *p = myproc();
acquire(&p->lock); acquire(&p->lock);
p->state = RUNNABLE; p->state = RUNNABLE;
@ -511,9 +471,7 @@ yield(void)
// A fork child's very first scheduling by scheduler() // A fork child's very first scheduling by scheduler()
// will swtch to forkret. // will swtch to forkret.
void void forkret(void) {
forkret(void)
{
static int first = 1; static int first = 1;
// Still holding p->lock from scheduler. // Still holding p->lock from scheduler.
@ -532,9 +490,7 @@ forkret(void)
// Atomically release lock and sleep on chan. // Atomically release lock and sleep on chan.
// Reacquires lock when awakened. // Reacquires lock when awakened.
void void sleep(void *chan, struct spinlock *lk) {
sleep(void *chan, struct spinlock *lk)
{
struct proc *p = myproc(); struct proc *p = myproc();
// Must acquire p->lock in order to // Must acquire p->lock in order to
@ -563,9 +519,7 @@ sleep(void *chan, struct spinlock *lk)
// Wake up all processes sleeping on chan. // Wake up all processes sleeping on chan.
// Must be called without any p->lock. // Must be called without any p->lock.
void void wakeup(void *chan) {
wakeup(void *chan)
{
struct proc *p; struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) { for (p = proc; p < &proc[NPROC]; p++) {
@ -582,9 +536,7 @@ wakeup(void *chan)
// Kill the process with the given pid. // Kill the process with the given pid.
// The victim won't exit until it tries to return // The victim won't exit until it tries to return
// to user space (see usertrap() in trap.c). // to user space (see usertrap() in trap.c).
int int kill(int pid) {
kill(int pid)
{
struct proc *p; struct proc *p;
for (p = proc; p < &proc[NPROC]; p++) { for (p = proc; p < &proc[NPROC]; p++) {
@ -603,17 +555,13 @@ kill(int pid)
return -1; return -1;
} }
void void setkilled(struct proc *p) {
setkilled(struct proc *p)
{
acquire(&p->lock); acquire(&p->lock);
p->killed = 1; p->killed = 1;
release(&p->lock); release(&p->lock);
} }
int int killed(struct proc *p) {
killed(struct proc *p)
{
int k; int k;
acquire(&p->lock); acquire(&p->lock);
@ -625,9 +573,7 @@ killed(struct proc *p)
// Copy to either a user address, or kernel address, // Copy to either a user address, or kernel address,
// depending on usr_dst. // depending on usr_dst.
// Returns 0 on success, -1 on error. // Returns 0 on success, -1 on error.
int int either_copyout(int user_dst, uint64 dst, void *src, uint64 len) {
either_copyout(int user_dst, uint64 dst, void *src, uint64 len)
{
struct proc *p = myproc(); struct proc *p = myproc();
if (user_dst) { if (user_dst) {
return copyout(p->pagetable, dst, src, len); return copyout(p->pagetable, dst, src, len);
@ -640,9 +586,7 @@ either_copyout(int user_dst, uint64 dst, void *src, uint64 len)
// Copy from either a user address, or kernel address, // Copy from either a user address, or kernel address,
// depending on usr_src. // depending on usr_src.
// Returns 0 on success, -1 on error. // Returns 0 on success, -1 on error.
int int either_copyin(void *dst, int user_src, uint64 src, uint64 len) {
either_copyin(void *dst, int user_src, uint64 src, uint64 len)
{
struct proc *p = myproc(); struct proc *p = myproc();
if (user_src) { if (user_src) {
return copyin(p->pagetable, dst, src, len); return copyin(p->pagetable, dst, src, len);
@ -655,17 +599,10 @@ either_copyin(void *dst, int user_src, uint64 src, uint64 len)
// Print a process listing to console. For debugging. // Print a process listing to console. For debugging.
// Runs when user types ^P on console. // Runs when user types ^P on console.
// No lock to avoid wedging a stuck machine further. // No lock to avoid wedging a stuck machine further.
void void procdump(void) {
procdump(void)
{
static char *states[] = { static char *states[] = {
[UNUSED] "unused", [UNUSED] "unused", [USED] "used", [SLEEPING] "sleep ",
[USED] "used", [RUNNABLE] "runble", [RUNNING] "run ", [ZOMBIE] "zombie"};
[SLEEPING] "sleep ",
[RUNNABLE] "runble",
[RUNNING] "run ",
[ZOMBIE] "zombie"
};
struct proc *p; struct proc *p;
char *state; char *state;

View File

@ -12,16 +12,11 @@
#include "fs.h" #include "fs.h"
#include "buf.h" #include "buf.h"
void void ramdiskinit(void) {}
ramdiskinit(void)
{
}
// If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID. // If B_DIRTY is set, write buf to disk, clear B_DIRTY, set B_VALID.
// Else if B_VALID is not set, read buf from disk, set B_VALID. // Else if B_VALID is not set, read buf from disk, set B_VALID.
void void ramdiskrw(struct buf *b) {
ramdiskrw(struct buf *b)
{
if (!holdingsleep(&b->lock)) if (!holdingsleep(&b->lock))
panic("ramdiskrw: buf not locked"); panic("ramdiskrw: buf not locked");
if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID) if ((b->flags & (B_VALID | B_DIRTY)) == B_VALID)

View File

@ -9,18 +9,14 @@
#include "proc.h" #include "proc.h"
#include "sleeplock.h" #include "sleeplock.h"
void void initsleeplock(struct sleeplock *lk, char *name) {
initsleeplock(struct sleeplock *lk, char *name)
{
initlock(&lk->lk, "sleep lock"); initlock(&lk->lk, "sleep lock");
lk->name = name; lk->name = name;
lk->locked = 0; lk->locked = 0;
lk->pid = 0; lk->pid = 0;
} }
void void acquiresleep(struct sleeplock *lk) {
acquiresleep(struct sleeplock *lk)
{
acquire(&lk->lk); acquire(&lk->lk);
while (lk->locked) { while (lk->locked) {
sleep(lk, &lk->lk); sleep(lk, &lk->lk);
@ -30,9 +26,7 @@ acquiresleep(struct sleeplock *lk)
release(&lk->lk); release(&lk->lk);
} }
void void releasesleep(struct sleeplock *lk) {
releasesleep(struct sleeplock *lk)
{
acquire(&lk->lk); acquire(&lk->lk);
lk->locked = 0; lk->locked = 0;
lk->pid = 0; lk->pid = 0;
@ -40,9 +34,7 @@ releasesleep(struct sleeplock *lk)
release(&lk->lk); release(&lk->lk);
} }
int int holdingsleep(struct sleeplock *lk) {
holdingsleep(struct sleeplock *lk)
{
int r; int r;
acquire(&lk->lk); acquire(&lk->lk);
@ -50,6 +42,3 @@ holdingsleep(struct sleeplock *lk)
release(&lk->lk); release(&lk->lk);
return r; return r;
} }

View File

@ -8,9 +8,7 @@
#include "proc.h" #include "proc.h"
#include "defs.h" #include "defs.h"
void void initlock(struct spinlock *lk, char *name) {
initlock(struct spinlock *lk, char *name)
{
lk->name = name; lk->name = name;
lk->locked = 0; lk->locked = 0;
lk->cpu = 0; lk->cpu = 0;
@ -18,9 +16,7 @@ initlock(struct spinlock *lk, char *name)
// Acquire the lock. // Acquire the lock.
// Loops (spins) until the lock is acquired. // Loops (spins) until the lock is acquired.
void void acquire(struct spinlock *lk) {
acquire(struct spinlock *lk)
{
push_off(); // disable interrupts to avoid deadlock. push_off(); // disable interrupts to avoid deadlock.
if (holding(lk)) if (holding(lk))
panic("acquire"); panic("acquire");
@ -43,9 +39,7 @@ acquire(struct spinlock *lk)
} }
// Release the lock. // Release the lock.
void void release(struct spinlock *lk) {
release(struct spinlock *lk)
{
if (!holding(lk)) if (!holding(lk))
panic("release"); panic("release");
@ -73,9 +67,7 @@ release(struct spinlock *lk)
// Check whether this cpu is holding the lock. // Check whether this cpu is holding the lock.
// Interrupts must be off. // Interrupts must be off.
int int holding(struct spinlock *lk) {
holding(struct spinlock *lk)
{
int r; int r;
r = (lk->locked && lk->cpu == mycpu()); r = (lk->locked && lk->cpu == mycpu());
return r; return r;
@ -85,9 +77,7 @@ holding(struct spinlock *lk)
// it takes two pop_off()s to undo two push_off()s. Also, if interrupts // it takes two pop_off()s to undo two push_off()s. Also, if interrupts
// are initially off, then push_off, pop_off leaves them off. // are initially off, then push_off, pop_off leaves them off.
void void push_off(void) {
push_off(void)
{
int old = intr_get(); int old = intr_get();
intr_off(); intr_off();
@ -96,9 +86,7 @@ push_off(void)
mycpu()->noff += 1; mycpu()->noff += 1;
} }
void void pop_off(void) {
pop_off(void)
{
struct cpu *c = mycpu(); struct cpu *c = mycpu();
if (intr_get()) if (intr_get())
panic("pop_off - interruptible"); panic("pop_off - interruptible");

View File

@ -17,9 +17,7 @@ uint64 timer_scratch[NCPU][5];
extern void timervec(); extern void timervec();
// entry.S jumps here in machine mode on stack0. // entry.S jumps here in machine mode on stack0.
void void start() {
start()
{
// set M Previous Privilege mode to Supervisor, for mret. // set M Previous Privilege mode to Supervisor, for mret.
unsigned long x = r_mstatus(); unsigned long x = r_mstatus();
x &= ~MSTATUS_MPP_MASK; x &= ~MSTATUS_MPP_MASK;
@ -59,9 +57,7 @@ start()
// at timervec in kernelvec.S, // at timervec in kernelvec.S,
// which turns them into software interrupts for // which turns them into software interrupts for
// devintr() in trap.c. // devintr() in trap.c.
void void timerinit() {
timerinit()
{
// each CPU has a separate source of timer interrupts. // each CPU has a separate source of timer interrupts.
int id = r_mhartid(); int id = r_mhartid();

View File

@ -1,8 +1,6 @@
#include "types.h" #include "types.h"
void* void *memset(void *dst, int c, uint n) {
memset(void *dst, int c, uint n)
{
char *cdst = (char *)dst; char *cdst = (char *)dst;
int i; int i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@ -11,9 +9,7 @@ memset(void *dst, int c, uint n)
return dst; return dst;
} }
int int memcmp(const void *v1, const void *v2, uint n) {
memcmp(const void *v1, const void *v2, uint n)
{
const uchar *s1, *s2; const uchar *s1, *s2;
s1 = v1; s1 = v1;
@ -27,9 +23,7 @@ memcmp(const void *v1, const void *v2, uint n)
return 0; return 0;
} }
void* void *memmove(void *dst, const void *src, uint n) {
memmove(void *dst, const void *src, uint n)
{
const char *s; const char *s;
char *d; char *d;
@ -51,15 +45,11 @@ memmove(void *dst, const void *src, uint n)
} }
// memcpy exists to placate GCC. Use memmove. // memcpy exists to placate GCC. Use memmove.
void* void *memcpy(void *dst, const void *src, uint n) {
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n); return memmove(dst, src, n);
} }
int int strncmp(const char *p, const char *q, uint n) {
strncmp(const char *p, const char *q, uint n)
{
while (n > 0 && *p && *p == *q) while (n > 0 && *p && *p == *q)
n--, p++, q++; n--, p++, q++;
if (n == 0) if (n == 0)
@ -67,9 +57,7 @@ strncmp(const char *p, const char *q, uint n)
return (uchar)*p - (uchar)*q; return (uchar)*p - (uchar)*q;
} }
char* char *strncpy(char *s, const char *t, int n) {
strncpy(char *s, const char *t, int n)
{
char *os; char *os;
os = s; os = s;
@ -81,9 +69,7 @@ strncpy(char *s, const char *t, int n)
} }
// Like strncpy but guaranteed to NUL-terminate. // Like strncpy but guaranteed to NUL-terminate.
char* char *safestrcpy(char *s, const char *t, int n) {
safestrcpy(char *s, const char *t, int n)
{
char *os; char *os;
os = s; os = s;
@ -95,13 +81,10 @@ safestrcpy(char *s, const char *t, int n)
return os; return os;
} }
int int strlen(const char *s) {
strlen(const char *s)
{
int n; int n;
for (n = 0; s[n]; n++) for (n = 0; s[n]; n++)
; ;
return n; return n;
} }

View File

@ -8,11 +8,10 @@
#include "defs.h" #include "defs.h"
// Fetch the uint64 at addr from the current process. // Fetch the uint64 at addr from the current process.
int int fetchaddr(uint64 addr, uint64 *ip) {
fetchaddr(uint64 addr, uint64 *ip)
{
struct proc *p = myproc(); struct proc *p = myproc();
if(addr >= p->sz || addr+sizeof(uint64) > p->sz) // both tests needed, in case of overflow if (addr >= p->sz ||
addr + sizeof(uint64) > p->sz) // both tests needed, in case of overflow
return -1; return -1;
if (copyin(p->pagetable, (char *)ip, addr, sizeof(*ip)) != 0) if (copyin(p->pagetable, (char *)ip, addr, sizeof(*ip)) != 0)
return -1; return -1;
@ -21,18 +20,14 @@ fetchaddr(uint64 addr, uint64 *ip)
// Fetch the nul-terminated string at addr from the current process. // Fetch the nul-terminated string at addr from the current process.
// Returns length of string, not including nul, or -1 for error. // Returns length of string, not including nul, or -1 for error.
int int fetchstr(uint64 addr, char *buf, int max) {
fetchstr(uint64 addr, char *buf, int max)
{
struct proc *p = myproc(); struct proc *p = myproc();
if (copyinstr(p->pagetable, buf, addr, max) < 0) if (copyinstr(p->pagetable, buf, addr, max) < 0)
return -1; return -1;
return strlen(buf); return strlen(buf);
} }
static uint64 static uint64 argraw(int n) {
argraw(int n)
{
struct proc *p = myproc(); struct proc *p = myproc();
switch (n) { switch (n) {
case 0: case 0:
@ -53,27 +48,17 @@ argraw(int n)
} }
// Fetch the nth 32-bit system call argument. // Fetch the nth 32-bit system call argument.
void void argint(int n, int *ip) { *ip = argraw(n); }
argint(int n, int *ip)
{
*ip = argraw(n);
}
// Retrieve an argument as a pointer. // Retrieve an argument as a pointer.
// Doesn't check for legality, since // Doesn't check for legality, since
// copyin/copyout will do that. // copyin/copyout will do that.
void void argaddr(int n, uint64 *ip) { *ip = argraw(n); }
argaddr(int n, uint64 *ip)
{
*ip = argraw(n);
}
// Fetch the nth word-sized system call argument as a null-terminated string. // Fetch the nth word-sized system call argument as a null-terminated string.
// Copies into buf, at most max. // Copies into buf, at most max.
// Returns string length if OK (including nul), -1 if error. // Returns string length if OK (including nul), -1 if error.
int int argstr(int n, char *buf, int max) {
argstr(int n, char *buf, int max)
{
uint64 addr; uint64 addr;
argaddr(n, &addr); argaddr(n, &addr);
return fetchstr(addr, buf, max); return fetchstr(addr, buf, max);
@ -105,32 +90,16 @@ extern uint64 sys_close(void);
// An array mapping syscall numbers from syscall.h // An array mapping syscall numbers from syscall.h
// to the function that handles the system call. // to the function that handles the system call.
static uint64 (*syscalls[])(void) = { static uint64 (*syscalls[])(void) = {
[SYS_fork] sys_fork, [SYS_fork] sys_fork, [SYS_exit] sys_exit, [SYS_wait] sys_wait,
[SYS_exit] sys_exit, [SYS_pipe] sys_pipe, [SYS_read] sys_read, [SYS_kill] sys_kill,
[SYS_wait] sys_wait, [SYS_exec] sys_exec, [SYS_fstat] sys_fstat, [SYS_chdir] sys_chdir,
[SYS_pipe] sys_pipe, [SYS_dup] sys_dup, [SYS_getpid] sys_getpid, [SYS_sbrk] sys_sbrk,
[SYS_read] sys_read, [SYS_sleep] sys_sleep, [SYS_uptime] sys_uptime, [SYS_open] sys_open,
[SYS_kill] sys_kill, [SYS_write] sys_write, [SYS_mknod] sys_mknod, [SYS_unlink] sys_unlink,
[SYS_exec] sys_exec, [SYS_link] sys_link, [SYS_mkdir] sys_mkdir, [SYS_close] sys_close,
[SYS_fstat] sys_fstat,
[SYS_chdir] sys_chdir,
[SYS_dup] sys_dup,
[SYS_getpid] sys_getpid,
[SYS_sbrk] sys_sbrk,
[SYS_sleep] sys_sleep,
[SYS_uptime] sys_uptime,
[SYS_open] sys_open,
[SYS_write] sys_write,
[SYS_mknod] sys_mknod,
[SYS_unlink] sys_unlink,
[SYS_link] sys_link,
[SYS_mkdir] sys_mkdir,
[SYS_close] sys_close,
}; };
void void syscall(void) {
syscall(void)
{
int num; int num;
struct proc *p = myproc(); struct proc *p = myproc();
@ -140,8 +109,7 @@ syscall(void)
// and store its return value in p->trapframe->a0 // and store its return value in p->trapframe->a0
p->trapframe->a0 = syscalls[num](); p->trapframe->a0 = syscalls[num]();
} else { } else {
printf("%d %s: unknown sys call %d\n", printf("%d %s: unknown sys call %d\n", p->pid, p->name, num);
p->pid, p->name, num);
p->trapframe->a0 = -1; p->trapframe->a0 = -1;
} }
} }

View File

@ -18,9 +18,7 @@
// Fetch the nth word-sized system call argument as a file descriptor // Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file. // and return both the descriptor and the corresponding struct file.
static int static int argfd(int n, int *pfd, struct file **pf) {
argfd(int n, int *pfd, struct file **pf)
{
int fd; int fd;
struct file *f; struct file *f;
@ -36,9 +34,7 @@ argfd(int n, int *pfd, struct file **pf)
// Allocate a file descriptor for the given file. // Allocate a file descriptor for the given file.
// Takes over file reference from caller on success. // Takes over file reference from caller on success.
static int static int fdalloc(struct file *f) {
fdalloc(struct file *f)
{
int fd; int fd;
struct proc *p = myproc(); struct proc *p = myproc();
@ -51,9 +47,7 @@ fdalloc(struct file *f)
return -1; return -1;
} }
uint64 uint64 sys_dup(void) {
sys_dup(void)
{
struct file *f; struct file *f;
int fd; int fd;
@ -65,9 +59,7 @@ sys_dup(void)
return fd; return fd;
} }
uint64 uint64 sys_read(void) {
sys_read(void)
{
struct file *f; struct file *f;
int n; int n;
uint64 p; uint64 p;
@ -79,9 +71,7 @@ sys_read(void)
return fileread(f, p, n); return fileread(f, p, n);
} }
uint64 uint64 sys_write(void) {
sys_write(void)
{
struct file *f; struct file *f;
int n; int n;
uint64 p; uint64 p;
@ -94,9 +84,7 @@ sys_write(void)
return filewrite(f, p, n); return filewrite(f, p, n);
} }
uint64 uint64 sys_close(void) {
sys_close(void)
{
int fd; int fd;
struct file *f; struct file *f;
@ -107,9 +95,7 @@ sys_close(void)
return 0; return 0;
} }
uint64 uint64 sys_fstat(void) {
sys_fstat(void)
{
struct file *f; struct file *f;
uint64 st; // user pointer to struct stat uint64 st; // user pointer to struct stat
@ -120,9 +106,7 @@ sys_fstat(void)
} }
// Create the path new as a link to the same inode as old. // Create the path new as a link to the same inode as old.
uint64 uint64 sys_link(void) {
sys_link(void)
{
char name[DIRSIZ], new[MAXPATH], old[MAXPATH]; char name[DIRSIZ], new[MAXPATH], old[MAXPATH];
struct inode *dp, *ip; struct inode *dp, *ip;
@ -170,9 +154,7 @@ bad:
} }
// Is the directory dp empty except for "." and ".." ? // Is the directory dp empty except for "." and ".." ?
static int static int isdirempty(struct inode *dp) {
isdirempty(struct inode *dp)
{
int off; int off;
struct dirent de; struct dirent de;
@ -185,9 +167,7 @@ isdirempty(struct inode *dp)
return 1; return 1;
} }
uint64 uint64 sys_unlink(void) {
sys_unlink(void)
{
struct inode *ip, *dp; struct inode *ip, *dp;
struct dirent de; struct dirent de;
char name[DIRSIZ], path[MAXPATH]; char name[DIRSIZ], path[MAXPATH];
@ -242,9 +222,7 @@ bad:
return -1; return -1;
} }
static struct inode* static struct inode *create(char *path, short type, short major, short minor) {
create(char *path, short type, short major, short minor)
{
struct inode *ip, *dp; struct inode *ip, *dp;
char name[DIRSIZ]; char name[DIRSIZ];
@ -301,9 +279,7 @@ create(char *path, short type, short major, short minor)
return 0; return 0;
} }
uint64 uint64 sys_open(void) {
sys_open(void)
{
char path[MAXPATH]; char path[MAXPATH];
int fd, omode; int fd, omode;
struct file *f; struct file *f;
@ -370,9 +346,7 @@ sys_open(void)
return fd; return fd;
} }
uint64 uint64 sys_mkdir(void) {
sys_mkdir(void)
{
char path[MAXPATH]; char path[MAXPATH];
struct inode *ip; struct inode *ip;
@ -386,9 +360,7 @@ sys_mkdir(void)
return 0; return 0;
} }
uint64 uint64 sys_mknod(void) {
sys_mknod(void)
{
struct inode *ip; struct inode *ip;
char path[MAXPATH]; char path[MAXPATH];
int major, minor; int major, minor;
@ -406,9 +378,7 @@ sys_mknod(void)
return 0; return 0;
} }
uint64 uint64 sys_chdir(void) {
sys_chdir(void)
{
char path[MAXPATH]; char path[MAXPATH];
struct inode *ip; struct inode *ip;
struct proc *p = myproc(); struct proc *p = myproc();
@ -431,9 +401,7 @@ sys_chdir(void)
return 0; return 0;
} }
uint64 uint64 sys_exec(void) {
sys_exec(void)
{
char path[MAXPATH], *argv[MAXARG]; char path[MAXPATH], *argv[MAXARG];
int i; int i;
uint64 uargv, uarg; uint64 uargv, uarg;
@ -474,9 +442,7 @@ sys_exec(void)
return -1; return -1;
} }
uint64 uint64 sys_pipe(void) {
sys_pipe(void)
{
uint64 fdarray; // user pointer to array of two integers uint64 fdarray; // user pointer to array of two integers
struct file *rf, *wf; struct file *rf, *wf;
int fd0, fd1; int fd0, fd1;
@ -494,7 +460,8 @@ sys_pipe(void)
return -1; return -1;
} }
if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 || if (copyout(p->pagetable, fdarray, (char *)&fd0, sizeof(fd0)) < 0 ||
copyout(p->pagetable, fdarray+sizeof(fd0), (char *)&fd1, sizeof(fd1)) < 0){ copyout(p->pagetable, fdarray + sizeof(fd0), (char *)&fd1,
sizeof(fd1)) < 0) {
p->ofile[fd0] = 0; p->ofile[fd0] = 0;
p->ofile[fd1] = 0; p->ofile[fd1] = 0;
fileclose(rf); fileclose(rf);

View File

@ -6,38 +6,24 @@
#include "spinlock.h" #include "spinlock.h"
#include "proc.h" #include "proc.h"
uint64 uint64 sys_exit(void) {
sys_exit(void)
{
int n; int n;
argint(0, &n); argint(0, &n);
exit(n); exit(n);
return 0; // not reached return 0; // not reached
} }
uint64 uint64 sys_getpid(void) { return myproc()->pid; }
sys_getpid(void)
{
return myproc()->pid;
}
uint64 uint64 sys_fork(void) { return fork(); }
sys_fork(void)
{
return fork();
}
uint64 uint64 sys_wait(void) {
sys_wait(void)
{
uint64 p; uint64 p;
argaddr(0, &p); argaddr(0, &p);
return wait(p); return wait(p);
} }
uint64 uint64 sys_sbrk(void) {
sys_sbrk(void)
{
uint64 addr; uint64 addr;
int n; int n;
@ -48,9 +34,7 @@ sys_sbrk(void)
return addr; return addr;
} }
uint64 uint64 sys_sleep(void) {
sys_sleep(void)
{
int n; int n;
uint ticks0; uint ticks0;
@ -68,9 +52,7 @@ sys_sleep(void)
return 0; return 0;
} }
uint64 uint64 sys_kill(void) {
sys_kill(void)
{
int pid; int pid;
argint(0, &pid); argint(0, &pid);
@ -79,9 +61,7 @@ sys_kill(void)
// return how many clock tick interrupts have occurred // return how many clock tick interrupts have occurred
// since start. // since start.
uint64 uint64 sys_uptime(void) {
sys_uptime(void)
{
uint xticks; uint xticks;
acquire(&tickslock); acquire(&tickslock);

View File

@ -16,26 +16,16 @@ void kernelvec();
extern int devintr(); extern int devintr();
void void trapinit(void) { initlock(&tickslock, "time"); }
trapinit(void)
{
initlock(&tickslock, "time");
}
// set up to take exceptions and traps while in the kernel. // set up to take exceptions and traps while in the kernel.
void void trapinithart(void) { w_stvec((uint64)kernelvec); }
trapinithart(void)
{
w_stvec((uint64)kernelvec);
}
// //
// handle an interrupt, exception, or system call from user space. // handle an interrupt, exception, or system call from user space.
// called from trampoline.S // called from trampoline.S
// //
void void usertrap(void) {
usertrap(void)
{
int which_dev = 0; int which_dev = 0;
if ((r_sstatus() & SSTATUS_SPP) != 0) if ((r_sstatus() & SSTATUS_SPP) != 0)
@ -86,9 +76,7 @@ usertrap(void)
// //
// return to user space // return to user space
// //
void void usertrapret(void) {
usertrapret(void)
{
struct proc *p = myproc(); struct proc *p = myproc();
// we're about to switch the destination of traps from // we're about to switch the destination of traps from
@ -131,9 +119,7 @@ usertrapret(void)
// interrupts and exceptions from kernel code go here via kernelvec, // interrupts and exceptions from kernel code go here via kernelvec,
// on whatever the current kernel stack is. // on whatever the current kernel stack is.
void void kerneltrap() {
kerneltrap()
{
int which_dev = 0; int which_dev = 0;
uint64 sepc = r_sepc(); uint64 sepc = r_sepc();
uint64 sstatus = r_sstatus(); uint64 sstatus = r_sstatus();
@ -160,9 +146,7 @@ kerneltrap()
w_sstatus(sstatus); w_sstatus(sstatus);
} }
void void clockintr() {
clockintr()
{
acquire(&tickslock); acquire(&tickslock);
ticks++; ticks++;
wakeup(&ticks); wakeup(&ticks);
@ -174,13 +158,10 @@ clockintr()
// returns 2 if timer interrupt, // returns 2 if timer interrupt,
// 1 if other device, // 1 if other device,
// 0 if not recognized. // 0 if not recognized.
int int devintr() {
devintr()
{
uint64 scause = r_scause(); uint64 scause = r_scause();
if((scause & 0x8000000000000000L) && if ((scause & 0x8000000000000000L) && (scause & 0xff) == 9) {
(scause & 0xff) == 9){
// this is a supervisor external interrupt, via PLIC. // this is a supervisor external interrupt, via PLIC.
// irq indicates which device interrupted. // irq indicates which device interrupted.
@ -218,4 +199,3 @@ devintr()
return 0; return 0;
} }
} }

View File

@ -49,9 +49,7 @@ extern volatile int panicked; // from printf.c
void uartstart(); void uartstart();
void void uartinit(void) {
uartinit(void)
{
// disable interrupts. // disable interrupts.
WriteReg(IER, 0x00); WriteReg(IER, 0x00);
@ -83,9 +81,7 @@ uartinit(void)
// because it may block, it can't be called // because it may block, it can't be called
// from interrupts; it's only suitable for use // from interrupts; it's only suitable for use
// by write(). // by write().
void void uartputc(int c) {
uartputc(int c)
{
acquire(&uart_tx_lock); acquire(&uart_tx_lock);
if (panicked) { if (panicked) {
@ -103,14 +99,11 @@ uartputc(int c)
release(&uart_tx_lock); release(&uart_tx_lock);
} }
// alternate version of uartputc() that doesn't // alternate version of uartputc() that doesn't
// use interrupts, for use by kernel printf() and // use interrupts, for use by kernel printf() and
// to echo characters. it spins waiting for the uart's // to echo characters. it spins waiting for the uart's
// output register to be empty. // output register to be empty.
void void uartputc_sync(int c) {
uartputc_sync(int c)
{
push_off(); push_off();
if (panicked) { if (panicked) {
@ -130,9 +123,7 @@ uartputc_sync(int c)
// in the transmit buffer, send it. // in the transmit buffer, send it.
// caller must hold uart_tx_lock. // caller must hold uart_tx_lock.
// called from both the top- and bottom-half. // called from both the top- and bottom-half.
void void uartstart() {
uartstart()
{
while (1) { while (1) {
if (uart_tx_w == uart_tx_r) { if (uart_tx_w == uart_tx_r) {
// transmit buffer is empty. // transmit buffer is empty.
@ -158,9 +149,7 @@ uartstart()
// read one input character from the UART. // read one input character from the UART.
// return -1 if none is waiting. // return -1 if none is waiting.
int int uartgetc(void) {
uartgetc(void)
{
if (ReadReg(LSR) & 0x01) { if (ReadReg(LSR) & 0x01) {
// input data is ready. // input data is ready.
return ReadReg(RHR); return ReadReg(RHR);
@ -172,9 +161,7 @@ uartgetc(void)
// handle a uart interrupt, raised because input has // handle a uart interrupt, raised because input has
// arrived, or the uart is ready for more output, or // arrived, or the uart is ready for more output, or
// both. called from devintr(). // both. called from devintr().
void void uartintr(void) {
uartintr(void)
{
// read and process incoming characters. // read and process incoming characters.
while (1) { while (1) {
int c = uartgetc(); int c = uartgetc();

View File

@ -2,7 +2,8 @@
// driver for qemu's virtio disk device. // driver for qemu's virtio disk device.
// uses qemu's mmio interface to virtio. // uses qemu's mmio interface to virtio.
// //
// qemu ... -drive file=fs.img,if=none,format=raw,id=x0 -device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0 // qemu ... -drive file=fs.img,if=none,format=raw,id=x0 -device
// virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
// //
#include "types.h" #include "types.h"
@ -58,16 +59,13 @@ static struct disk {
} disk; } disk;
void void virtio_disk_init(void) {
virtio_disk_init(void)
{
uint32 status = 0; uint32 status = 0;
initlock(&disk.vdisk_lock, "virtio_disk"); initlock(&disk.vdisk_lock, "virtio_disk");
if (*R(VIRTIO_MMIO_MAGIC_VALUE) != 0x74726976 || if (*R(VIRTIO_MMIO_MAGIC_VALUE) != 0x74726976 ||
*R(VIRTIO_MMIO_VERSION) != 2 || *R(VIRTIO_MMIO_VERSION) != 2 || *R(VIRTIO_MMIO_DEVICE_ID) != 2 ||
*R(VIRTIO_MMIO_DEVICE_ID) != 2 ||
*R(VIRTIO_MMIO_VENDOR_ID) != 0x554d4551) { *R(VIRTIO_MMIO_VENDOR_ID) != 0x554d4551) {
panic("could not find virtio disk"); panic("could not find virtio disk");
} }
@ -153,9 +151,7 @@ virtio_disk_init(void)
} }
// find a free descriptor, mark it non-free, return its index. // find a free descriptor, mark it non-free, return its index.
static int static int alloc_desc() {
alloc_desc()
{
for (int i = 0; i < NUM; i++) { for (int i = 0; i < NUM; i++) {
if (disk.free[i]) { if (disk.free[i]) {
disk.free[i] = 0; disk.free[i] = 0;
@ -166,9 +162,7 @@ alloc_desc()
} }
// mark a descriptor as free. // mark a descriptor as free.
static void static void free_desc(int i) {
free_desc(int i)
{
if (i >= NUM) if (i >= NUM)
panic("free_desc 1"); panic("free_desc 1");
if (disk.free[i]) if (disk.free[i])
@ -182,9 +176,7 @@ free_desc(int i)
} }
// free a chain of descriptors. // free a chain of descriptors.
static void static void free_chain(int i) {
free_chain(int i)
{
while (1) { while (1) {
int flag = disk.desc[i].flags; int flag = disk.desc[i].flags;
int nxt = disk.desc[i].next; int nxt = disk.desc[i].next;
@ -198,9 +190,7 @@ free_chain(int i)
// allocate three descriptors (they need not be contiguous). // allocate three descriptors (they need not be contiguous).
// disk transfers always use three descriptors. // disk transfers always use three descriptors.
static int static int alloc3_desc(int *idx) {
alloc3_desc(int *idx)
{
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
idx[i] = alloc_desc(); idx[i] = alloc_desc();
if (idx[i] < 0) { if (idx[i] < 0) {
@ -212,9 +202,7 @@ alloc3_desc(int *idx)
return 0; return 0;
} }
void void virtio_disk_rw(struct buf *b, int write) {
virtio_disk_rw(struct buf *b, int write)
{
uint64 sector = b->blockno * (BSIZE / 512); uint64 sector = b->blockno * (BSIZE / 512);
acquire(&disk.vdisk_lock); acquire(&disk.vdisk_lock);
@ -291,9 +279,7 @@ virtio_disk_rw(struct buf *b, int write)
release(&disk.vdisk_lock); release(&disk.vdisk_lock);
} }
void void virtio_disk_intr() {
virtio_disk_intr()
{
acquire(&disk.vdisk_lock); acquire(&disk.vdisk_lock);
// the device won't raise another interrupt until we tell it // the device won't raise another interrupt until we tell it

View File

@ -16,9 +16,7 @@ extern char etext[]; // kernel.ld sets this to end of kernel code.
extern char trampoline[]; // trampoline.S extern char trampoline[]; // trampoline.S
// Make a direct-map page table for the kernel. // Make a direct-map page table for the kernel.
pagetable_t pagetable_t kvmmake(void) {
kvmmake(void)
{
pagetable_t kpgtbl; pagetable_t kpgtbl;
kpgtbl = (pagetable_t)kalloc(); kpgtbl = (pagetable_t)kalloc();
@ -37,7 +35,8 @@ kvmmake(void)
kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext - KERNBASE, PTE_R | PTE_X); kvmmap(kpgtbl, KERNBASE, KERNBASE, (uint64)etext - KERNBASE, PTE_R | PTE_X);
// map kernel data and the physical RAM we'll make use of. // map kernel data and the physical RAM we'll make use of.
kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP-(uint64)etext, PTE_R | PTE_W); kvmmap(kpgtbl, (uint64)etext, (uint64)etext, PHYSTOP - (uint64)etext,
PTE_R | PTE_W);
// map the trampoline for trap entry/exit to // map the trampoline for trap entry/exit to
// the highest virtual address in the kernel. // the highest virtual address in the kernel.
@ -50,17 +49,11 @@ kvmmake(void)
} }
// Initialize the one kernel_pagetable // Initialize the one kernel_pagetable
void void kvminit(void) { kernel_pagetable = kvmmake(); }
kvminit(void)
{
kernel_pagetable = kvmmake();
}
// Switch h/w page table register to the kernel's page table, // Switch h/w page table register to the kernel's page table,
// and enable paging. // and enable paging.
void void kvminithart() {
kvminithart()
{
// wait for any previous writes to the page table memory to finish. // wait for any previous writes to the page table memory to finish.
sfence_vma(); sfence_vma();
@ -82,9 +75,7 @@ kvminithart()
// 21..29 -- 9 bits of level-1 index. // 21..29 -- 9 bits of level-1 index.
// 12..20 -- 9 bits of level-0 index. // 12..20 -- 9 bits of level-0 index.
// 0..11 -- 12 bits of byte offset within the page. // 0..11 -- 12 bits of byte offset within the page.
pte_t * pte_t *walk(pagetable_t pagetable, uint64 va, int alloc) {
walk(pagetable_t pagetable, uint64 va, int alloc)
{
if (va >= MAXVA) if (va >= MAXVA)
panic("walk"); panic("walk");
@ -105,9 +96,7 @@ walk(pagetable_t pagetable, uint64 va, int alloc)
// Look up a virtual address, return the physical address, // Look up a virtual address, return the physical address,
// or 0 if not mapped. // or 0 if not mapped.
// Can only be used to look up user pages. // Can only be used to look up user pages.
uint64 uint64 walkaddr(pagetable_t pagetable, uint64 va) {
walkaddr(pagetable_t pagetable, uint64 va)
{
pte_t *pte; pte_t *pte;
uint64 pa; uint64 pa;
@ -128,9 +117,7 @@ walkaddr(pagetable_t pagetable, uint64 va)
// add a mapping to the kernel page table. // add a mapping to the kernel page table.
// only used when booting. // only used when booting.
// does not flush TLB or enable paging. // does not flush TLB or enable paging.
void void kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm) {
kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
{
if (mappages(kpgtbl, va, sz, pa, perm) != 0) if (mappages(kpgtbl, va, sz, pa, perm) != 0)
panic("kvmmap"); panic("kvmmap");
} }
@ -139,9 +126,8 @@ kvmmap(pagetable_t kpgtbl, uint64 va, uint64 pa, uint64 sz, int perm)
// physical addresses starting at pa. va and size might not // physical addresses starting at pa. va and size might not
// be page-aligned. Returns 0 on success, -1 if walk() couldn't // be page-aligned. Returns 0 on success, -1 if walk() couldn't
// allocate a needed page-table page. // allocate a needed page-table page.
int int mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa,
mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm) int perm) {
{
uint64 a, last; uint64 a, last;
pte_t *pte; pte_t *pte;
@ -167,9 +153,7 @@ mappages(pagetable_t pagetable, uint64 va, uint64 size, uint64 pa, int perm)
// Remove npages of mappings starting from va. va must be // Remove npages of mappings starting from va. va must be
// page-aligned. The mappings must exist. // page-aligned. The mappings must exist.
// Optionally free the physical memory. // Optionally free the physical memory.
void void uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free) {
uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
{
uint64 a; uint64 a;
pte_t *pte; pte_t *pte;
@ -193,9 +177,7 @@ uvmunmap(pagetable_t pagetable, uint64 va, uint64 npages, int do_free)
// create an empty user page table. // create an empty user page table.
// returns 0 if out of memory. // returns 0 if out of memory.
pagetable_t pagetable_t uvmcreate() {
uvmcreate()
{
pagetable_t pagetable; pagetable_t pagetable;
pagetable = (pagetable_t)kalloc(); pagetable = (pagetable_t)kalloc();
if (pagetable == 0) if (pagetable == 0)
@ -207,9 +189,7 @@ uvmcreate()
// Load the user initcode into address 0 of pagetable, // Load the user initcode into address 0 of pagetable,
// for the very first process. // for the very first process.
// sz must be less than a page. // sz must be less than a page.
void void uvmfirst(pagetable_t pagetable, uchar *src, uint sz) {
uvmfirst(pagetable_t pagetable, uchar *src, uint sz)
{
char *mem; char *mem;
if (sz >= PGSIZE) if (sz >= PGSIZE)
@ -222,9 +202,7 @@ uvmfirst(pagetable_t pagetable, uchar *src, uint sz)
// Allocate PTEs and physical memory to grow process from oldsz to // Allocate PTEs and physical memory to grow process from oldsz to
// newsz, which need not be page aligned. Returns new size or 0 on error. // newsz, which need not be page aligned. Returns new size or 0 on error.
uint64 uint64 uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm) {
uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
{
char *mem; char *mem;
uint64 a; uint64 a;
@ -239,7 +217,8 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
return 0; return 0;
} }
memset(mem, 0, PGSIZE); memset(mem, 0, PGSIZE);
if(mappages(pagetable, a, PGSIZE, (uint64)mem, PTE_R|PTE_U|xperm) != 0){ if (mappages(pagetable, a, PGSIZE, (uint64)mem,
PTE_R | PTE_U | xperm) != 0) {
kfree(mem); kfree(mem);
uvmdealloc(pagetable, a, oldsz); uvmdealloc(pagetable, a, oldsz);
return 0; return 0;
@ -252,9 +231,7 @@ uvmalloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz, int xperm)
// newsz. oldsz and newsz need not be page-aligned, nor does newsz // newsz. oldsz and newsz need not be page-aligned, nor does newsz
// need to be less than oldsz. oldsz can be larger than the actual // need to be less than oldsz. oldsz can be larger than the actual
// process size. Returns the new process size. // process size. Returns the new process size.
uint64 uint64 uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz) {
uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
{
if (newsz >= oldsz) if (newsz >= oldsz)
return oldsz; return oldsz;
@ -268,9 +245,7 @@ uvmdealloc(pagetable_t pagetable, uint64 oldsz, uint64 newsz)
// Recursively free page-table pages. // Recursively free page-table pages.
// All leaf mappings must already have been removed. // All leaf mappings must already have been removed.
void void freewalk(pagetable_t pagetable) {
freewalk(pagetable_t pagetable)
{
// there are 2^9 = 512 PTEs in a page table. // there are 2^9 = 512 PTEs in a page table.
for (int i = 0; i < 512; i++) { for (int i = 0; i < 512; i++) {
pte_t pte = pagetable[i]; pte_t pte = pagetable[i];
@ -288,9 +263,7 @@ freewalk(pagetable_t pagetable)
// Free user memory pages, // Free user memory pages,
// then free page-table pages. // then free page-table pages.
void void uvmfree(pagetable_t pagetable, uint64 sz) {
uvmfree(pagetable_t pagetable, uint64 sz)
{
if (sz > 0) if (sz > 0)
uvmunmap(pagetable, 0, PGROUNDUP(sz) / PGSIZE, 1); uvmunmap(pagetable, 0, PGROUNDUP(sz) / PGSIZE, 1);
freewalk(pagetable); freewalk(pagetable);
@ -302,9 +275,7 @@ uvmfree(pagetable_t pagetable, uint64 sz)
// physical memory. // physical memory.
// returns 0 on success, -1 on failure. // returns 0 on success, -1 on failure.
// frees any allocated pages on failure. // frees any allocated pages on failure.
int int uvmcopy(pagetable_t old, pagetable_t new, uint64 sz) {
uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
{
pte_t *pte; pte_t *pte;
uint64 pa, i; uint64 pa, i;
uint flags; uint flags;
@ -334,9 +305,7 @@ uvmcopy(pagetable_t old, pagetable_t new, uint64 sz)
// mark a PTE invalid for user access. // mark a PTE invalid for user access.
// used by exec for the user stack guard page. // used by exec for the user stack guard page.
void void uvmclear(pagetable_t pagetable, uint64 va) {
uvmclear(pagetable_t pagetable, uint64 va)
{
pte_t *pte; pte_t *pte;
pte = walk(pagetable, va, 0); pte = walk(pagetable, va, 0);
@ -348,9 +317,7 @@ uvmclear(pagetable_t pagetable, uint64 va)
// Copy from kernel to user. // Copy from kernel to user.
// Copy len bytes from src to virtual address dstva in a given page table. // Copy len bytes from src to virtual address dstva in a given page table.
// Return 0 on success, -1 on error. // Return 0 on success, -1 on error.
int int copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len) {
copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
{
uint64 n, va0, pa0; uint64 n, va0, pa0;
while (len > 0) { while (len > 0) {
@ -373,9 +340,7 @@ copyout(pagetable_t pagetable, uint64 dstva, char *src, uint64 len)
// Copy from user to kernel. // Copy from user to kernel.
// Copy len bytes to dst from virtual address srcva in a given page table. // Copy len bytes to dst from virtual address srcva in a given page table.
// Return 0 on success, -1 on error. // Return 0 on success, -1 on error.
int int copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len) {
copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
{
uint64 n, va0, pa0; uint64 n, va0, pa0;
while (len > 0) { while (len > 0) {
@ -399,9 +364,7 @@ copyin(pagetable_t pagetable, char *dst, uint64 srcva, uint64 len)
// Copy bytes to dst from virtual address srcva in a given page table, // Copy bytes to dst from virtual address srcva in a given page table,
// until a '\0', or max. // until a '\0', or max.
// Return 0 on success, -1 on error. // Return 0 on success, -1 on error.
int int copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max) {
copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)
{
uint64 n, va0, pa0; uint64 n, va0, pa0;
int got_null = 0; int got_null = 0;

View File

@ -12,7 +12,12 @@
#include "kernel/param.h" #include "kernel/param.h"
#ifndef static_assert #ifndef static_assert
#define static_assert(a, b) do { switch (0) case 0: case (a): ; } while (0) #define static_assert(a, b) \
do { \
switch (0) \
case 0: \
case (a):; \
} while (0)
#endif #endif
#define NINODES 200 #define NINODES 200
@ -32,7 +37,6 @@ char zeroes[BSIZE];
uint freeinode = 1; uint freeinode = 1;
uint freeblock; uint freeblock;
void balloc(int); void balloc(int);
void wsect(uint, void *); void wsect(uint, void *);
void winode(uint, struct dinode *); void winode(uint, struct dinode *);
@ -43,9 +47,7 @@ void iappend(uint inum, void *p, int n);
void die(const char *); void die(const char *);
// convert to riscv byte order // convert to riscv byte order
ushort ushort xshort(ushort x) {
xshort(ushort x)
{
ushort y; ushort y;
uchar *a = (uchar *)&y; uchar *a = (uchar *)&y;
a[0] = x; a[0] = x;
@ -53,9 +55,7 @@ xshort(ushort x)
return y; return y;
} }
uint uint xint(uint x) {
xint(uint x)
{
uint y; uint y;
uchar *a = (uchar *)&y; uchar *a = (uchar *)&y;
a[0] = x; a[0] = x;
@ -65,16 +65,13 @@ xint(uint x)
return y; return y;
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int i, cc, fd; int i, cc, fd;
uint rootino, inum, off; uint rootino, inum, off;
struct dirent de; struct dirent de;
char buf[BSIZE]; char buf[BSIZE];
struct dinode din; struct dinode din;
static_assert(sizeof(int) == 4, "Integers must be 4 bytes!"); static_assert(sizeof(int) == 4, "Integers must be 4 bytes!");
if (argc < 2) { if (argc < 2) {
@ -102,7 +99,8 @@ main(int argc, char *argv[])
sb.inodestart = xint(2 + nlog); sb.inodestart = xint(2 + nlog);
sb.bmapstart = xint(2 + nlog + ninodeblocks); sb.bmapstart = xint(2 + nlog + ninodeblocks);
printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap blocks %u) blocks %d total %d\n", printf("nmeta %d (boot, super, log blocks %u inode blocks %u, bitmap "
"blocks %u) blocks %d total %d\n",
nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE); nmeta, nlog, ninodeblocks, nbitmap, nblocks, FSSIZE);
freeblock = nmeta; // the first free block that we can allocate freeblock = nmeta; // the first free block that we can allocate
@ -172,18 +170,14 @@ main(int argc, char *argv[])
exit(0); exit(0);
} }
void void wsect(uint sec, void *buf) {
wsect(uint sec, void *buf)
{
if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE) if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
die("lseek"); die("lseek");
if (write(fsfd, buf, BSIZE) != BSIZE) if (write(fsfd, buf, BSIZE) != BSIZE)
die("write"); die("write");
} }
void void winode(uint inum, struct dinode *ip) {
winode(uint inum, struct dinode *ip)
{
char buf[BSIZE]; char buf[BSIZE];
uint bn; uint bn;
struct dinode *dip; struct dinode *dip;
@ -195,9 +189,7 @@ winode(uint inum, struct dinode *ip)
wsect(bn, buf); wsect(bn, buf);
} }
void void rinode(uint inum, struct dinode *ip) {
rinode(uint inum, struct dinode *ip)
{
char buf[BSIZE]; char buf[BSIZE];
uint bn; uint bn;
struct dinode *dip; struct dinode *dip;
@ -208,18 +200,14 @@ rinode(uint inum, struct dinode *ip)
*ip = *dip; *ip = *dip;
} }
void void rsect(uint sec, void *buf) {
rsect(uint sec, void *buf)
{
if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE) if (lseek(fsfd, sec * BSIZE, 0) != sec * BSIZE)
die("lseek"); die("lseek");
if (read(fsfd, buf, BSIZE) != BSIZE) if (read(fsfd, buf, BSIZE) != BSIZE)
die("read"); die("read");
} }
uint uint ialloc(ushort type) {
ialloc(ushort type)
{
uint inum = freeinode++; uint inum = freeinode++;
struct dinode din; struct dinode din;
@ -231,9 +219,7 @@ ialloc(ushort type)
return inum; return inum;
} }
void void balloc(int used) {
balloc(int used)
{
uchar buf[BSIZE]; uchar buf[BSIZE];
int i; int i;
@ -249,9 +235,7 @@ balloc(int used)
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
void void iappend(uint inum, void *xp, int n) {
iappend(uint inum, void *xp, int n)
{
char *p = (char *)xp; char *p = (char *)xp;
uint fbn, off, n1; uint fbn, off, n1;
struct dinode din; struct dinode din;
@ -293,9 +277,7 @@ iappend(uint inum, void *xp, int n)
winode(inum, &din); winode(inum, &din);
} }
void void die(const char *s) {
die(const char *s)
{
perror(s); perror(s);
exit(1); exit(1);
} }

View File

@ -4,9 +4,7 @@
char buf[512]; char buf[512];
void void cat(int fd) {
cat(int fd)
{
int n; int n;
while ((n = read(fd, buf, sizeof(buf))) > 0) { while ((n = read(fd, buf, sizeof(buf))) > 0) {
@ -21,9 +19,7 @@ cat(int fd)
} }
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int fd, i; int fd, i;
if (argc <= 1) { if (argc <= 1) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int i; int i;
for (i = 1; i < argc; i++) { for (i = 1; i < argc; i++) {

View File

@ -7,15 +7,9 @@
#define N 1000 #define N 1000
void void print(const char *s) { write(1, s, strlen(s)); }
print(const char *s)
{
write(1, s, strlen(s));
}
void void forktest(void) {
forktest(void)
{
int n, pid; int n, pid;
print("fork test\n"); print("fork test\n");
@ -48,9 +42,7 @@ forktest(void)
print("fork test OK\n"); print("fork test OK\n");
} }
int int main(void) {
main(void)
{
forktest(); forktest();
exit(0); exit(0);
} }

View File

@ -7,9 +7,7 @@
char buf[1024]; char buf[1024];
int match(char *, char *); int match(char *, char *);
void void grep(char *pattern, int fd) {
grep(char *pattern, int fd)
{
int n, m; int n, m;
char *p, *q; char *p, *q;
@ -33,9 +31,7 @@ grep(char *pattern, int fd)
} }
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int fd, i; int fd, i;
char *pattern; char *pattern;
@ -68,9 +64,7 @@ main(int argc, char *argv[])
int matchhere(char *, char *); int matchhere(char *, char *);
int matchstar(int, char *, char *); int matchstar(int, char *, char *);
int int match(char *re, char *text) {
match(char *re, char *text)
{
if (re[0] == '^') if (re[0] == '^')
return matchhere(re + 1, text); return matchhere(re + 1, text);
do { // must look at empty string do { // must look at empty string
@ -81,8 +75,7 @@ match(char *re, char *text)
} }
// matchhere: search for re at beginning of text // matchhere: search for re at beginning of text
int matchhere(char *re, char *text) int matchhere(char *re, char *text) {
{
if (re[0] == '\0') if (re[0] == '\0')
return 1; return 1;
if (re[1] == '*') if (re[1] == '*')
@ -95,12 +88,10 @@ int matchhere(char *re, char *text)
} }
// matchstar: search for c*re at beginning of text // matchstar: search for c*re at beginning of text
int matchstar(int c, char *re, char *text) int matchstar(int c, char *re, char *text) {
{
do { // a * matches zero or more instances do { // a * matches zero or more instances
if (matchhere(re, text)) if (matchhere(re, text))
return 1; return 1;
} while (*text != '\0' && (*text++ == c || c == '.')); } while (*text != '\0' && (*text++ == c || c == '.'));
return 0; return 0;
} }

View File

@ -13,9 +13,7 @@
#include "kernel/riscv.h" #include "kernel/riscv.h"
// from FreeBSD. // from FreeBSD.
int int do_rand(unsigned long *ctx) {
do_rand(unsigned long *ctx)
{
/* /*
* Compute x = (7^5 * x) mod (2^31 - 1) * Compute x = (7^5 * x) mod (2^31 - 1)
* without overflowing 31 bits: * without overflowing 31 bits:
@ -41,15 +39,9 @@ do_rand(unsigned long *ctx)
unsigned long rand_next = 1; unsigned long rand_next = 1;
int int rand(void) { return (do_rand(&rand_next)); }
rand(void)
{
return (do_rand(&rand_next));
}
void void go(int which_child) {
go(int which_child)
{
int fd = -1; int fd = -1;
static char buf[999]; static char buf[999];
char *break0 = sbrk(0); char *break0 = sbrk(0);
@ -286,16 +278,15 @@ go(int which_child)
wait(&st1); wait(&st1);
wait(&st2); wait(&st2);
if (st1 != 0 || st2 != 0 || strcmp(buf, "hi\n") != 0) { if (st1 != 0 || st2 != 0 || strcmp(buf, "hi\n") != 0) {
printf("grind: exec pipeline failed %d %d \"%s\"\n", st1, st2, buf); printf("grind: exec pipeline failed %d %d \"%s\"\n", st1, st2,
buf);
exit(1); exit(1);
} }
} }
} }
} }
void void iter() {
iter()
{
unlink("a"); unlink("a");
unlink("b"); unlink("b");
@ -333,9 +324,7 @@ iter()
exit(0); exit(0);
} }
int int main() {
main()
{
while (1) { while (1) {
int pid = fork(); int pid = fork();
if (pid == 0) { if (pid == 0) {

View File

@ -11,9 +11,7 @@
char *argv[] = {"sh", 0}; char *argv[] = {"sh", 0};
int int main(void) {
main(void)
{
int pid, wpid; int pid, wpid;
if (open("console", O_RDWR) < 0) { if (open("console", O_RDWR) < 0) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(int argc, char **argv) {
main(int argc, char **argv)
{
int i; int i;
if (argc < 2) { if (argc < 2) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
if (argc != 3) { if (argc != 3) {
fprintf(2, "Usage: ln old new\n"); fprintf(2, "Usage: ln old new\n");
exit(1); exit(1);

View File

@ -3,9 +3,7 @@
#include "user/user.h" #include "user/user.h"
#include "kernel/fs.h" #include "kernel/fs.h"
char* char *fmtname(char *path) {
fmtname(char *path)
{
static char buf[DIRSIZ + 1]; static char buf[DIRSIZ + 1];
char *p; char *p;
@ -22,9 +20,7 @@ fmtname(char *path)
return buf; return buf;
} }
void void ls(char *path) {
ls(char *path)
{
char buf[512], *p; char buf[512], *p;
int fd; int fd;
struct dirent de; struct dirent de;
@ -71,9 +67,7 @@ ls(char *path)
close(fd); close(fd);
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int i; int i;
if (argc < 2) { if (argc < 2) {

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int i; int i;
if (argc < 2) { if (argc < 2) {

View File

@ -6,15 +6,9 @@
static char digits[] = "0123456789ABCDEF"; static char digits[] = "0123456789ABCDEF";
static void static void putc(int fd, char c) { write(fd, &c, 1); }
putc(int fd, char c)
{
write(fd, &c, 1);
}
static void static void printint(int fd, int xx, int base, int sgn) {
printint(int fd, int xx, int base, int sgn)
{
char buf[16]; char buf[16];
int i, neg; int i, neg;
uint x; uint x;
@ -38,8 +32,7 @@ printint(int fd, int xx, int base, int sgn)
putc(fd, buf[i]); putc(fd, buf[i]);
} }
static void static void printptr(int fd, uint64 x) {
printptr(int fd, uint64 x) {
int i; int i;
putc(fd, '0'); putc(fd, '0');
putc(fd, 'x'); putc(fd, 'x');
@ -48,9 +41,7 @@ printptr(int fd, uint64 x) {
} }
// Print to the given fd. Only understands %d, %x, %p, %s. // Print to the given fd. Only understands %d, %x, %p, %s.
void void vprintf(int fd, const char *fmt, va_list ap) {
vprintf(int fd, const char *fmt, va_list ap)
{
char *s; char *s;
int c, i, state; int c, i, state;
@ -94,18 +85,14 @@ vprintf(int fd, const char *fmt, va_list ap)
} }
} }
void void fprintf(int fd, const char *fmt, ...) {
fprintf(int fd, const char *fmt, ...)
{
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
vprintf(fd, fmt, ap); vprintf(fd, fmt, ap);
} }
void void printf(const char *fmt, ...) {
printf(const char *fmt, ...)
{
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);

View File

@ -2,9 +2,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int i; int i;
if (argc < 2) { if (argc < 2) {

View File

@ -55,9 +55,7 @@ struct cmd *parsecmd(char*);
void runcmd(struct cmd *) __attribute__((noreturn)); void runcmd(struct cmd *) __attribute__((noreturn));
// Execute cmd. Never returns. // Execute cmd. Never returns.
void void runcmd(struct cmd *cmd) {
runcmd(struct cmd *cmd)
{
int p[2]; int p[2];
struct backcmd *bcmd; struct backcmd *bcmd;
struct execcmd *ecmd; struct execcmd *ecmd;
@ -131,9 +129,7 @@ runcmd(struct cmd *cmd)
exit(0); exit(0);
} }
int int getcmd(char *buf, int nbuf) {
getcmd(char *buf, int nbuf)
{
write(2, "$ ", 2); write(2, "$ ", 2);
memset(buf, 0, nbuf); memset(buf, 0, nbuf);
gets(buf, nbuf); gets(buf, nbuf);
@ -142,9 +138,7 @@ getcmd(char *buf, int nbuf)
return 0; return 0;
} }
int int main(void) {
main(void)
{
static char buf[100]; static char buf[100];
int fd; int fd;
@ -172,16 +166,12 @@ main(void)
exit(0); exit(0);
} }
void void panic(char *s) {
panic(char *s)
{
fprintf(2, "%s\n", s); fprintf(2, "%s\n", s);
exit(1); exit(1);
} }
int int fork1(void) {
fork1(void)
{
int pid; int pid;
pid = fork(); pid = fork();
@ -193,9 +183,7 @@ fork1(void)
// PAGEBREAK! // PAGEBREAK!
// Constructors // Constructors
struct cmd* struct cmd *execcmd(void) {
execcmd(void)
{
struct execcmd *cmd; struct execcmd *cmd;
cmd = malloc(sizeof(*cmd)); cmd = malloc(sizeof(*cmd));
@ -204,9 +192,8 @@ execcmd(void)
return (struct cmd *)cmd; return (struct cmd *)cmd;
} }
struct cmd* struct cmd *redircmd(struct cmd *subcmd, char *file, char *efile, int mode,
redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd) int fd) {
{
struct redircmd *cmd; struct redircmd *cmd;
cmd = malloc(sizeof(*cmd)); cmd = malloc(sizeof(*cmd));
@ -220,9 +207,7 @@ redircmd(struct cmd *subcmd, char *file, char *efile, int mode, int fd)
return (struct cmd *)cmd; return (struct cmd *)cmd;
} }
struct cmd* struct cmd *pipecmd(struct cmd *left, struct cmd *right) {
pipecmd(struct cmd *left, struct cmd *right)
{
struct pipecmd *cmd; struct pipecmd *cmd;
cmd = malloc(sizeof(*cmd)); cmd = malloc(sizeof(*cmd));
@ -233,9 +218,7 @@ pipecmd(struct cmd *left, struct cmd *right)
return (struct cmd *)cmd; return (struct cmd *)cmd;
} }
struct cmd* struct cmd *listcmd(struct cmd *left, struct cmd *right) {
listcmd(struct cmd *left, struct cmd *right)
{
struct listcmd *cmd; struct listcmd *cmd;
cmd = malloc(sizeof(*cmd)); cmd = malloc(sizeof(*cmd));
@ -246,9 +229,7 @@ listcmd(struct cmd *left, struct cmd *right)
return (struct cmd *)cmd; return (struct cmd *)cmd;
} }
struct cmd* struct cmd *backcmd(struct cmd *subcmd) {
backcmd(struct cmd *subcmd)
{
struct backcmd *cmd; struct backcmd *cmd;
cmd = malloc(sizeof(*cmd)); cmd = malloc(sizeof(*cmd));
@ -263,9 +244,7 @@ backcmd(struct cmd *subcmd)
char whitespace[] = " \t\r\n\v"; char whitespace[] = " \t\r\n\v";
char symbols[] = "<|>&;()"; char symbols[] = "<|>&;()";
int int gettoken(char **ps, char *es, char **q, char **eq) {
gettoken(char **ps, char *es, char **q, char **eq)
{
char *s; char *s;
int ret; int ret;
@ -308,9 +287,7 @@ gettoken(char **ps, char *es, char **q, char **eq)
return ret; return ret;
} }
int int peek(char **ps, char *es, char *toks) {
peek(char **ps, char *es, char *toks)
{
char *s; char *s;
s = *ps; s = *ps;
@ -325,9 +302,7 @@ struct cmd *parsepipe(char**, char*);
struct cmd *parseexec(char **, char *); struct cmd *parseexec(char **, char *);
struct cmd *nulterminate(struct cmd *); struct cmd *nulterminate(struct cmd *);
struct cmd* struct cmd *parsecmd(char *s) {
parsecmd(char *s)
{
char *es; char *es;
struct cmd *cmd; struct cmd *cmd;
@ -342,9 +317,7 @@ parsecmd(char *s)
return cmd; return cmd;
} }
struct cmd* struct cmd *parseline(char **ps, char *es) {
parseline(char **ps, char *es)
{
struct cmd *cmd; struct cmd *cmd;
cmd = parsepipe(ps, es); cmd = parsepipe(ps, es);
@ -359,9 +332,7 @@ parseline(char **ps, char *es)
return cmd; return cmd;
} }
struct cmd* struct cmd *parsepipe(char **ps, char *es) {
parsepipe(char **ps, char *es)
{
struct cmd *cmd; struct cmd *cmd;
cmd = parseexec(ps, es); cmd = parseexec(ps, es);
@ -372,9 +343,7 @@ parsepipe(char **ps, char *es)
return cmd; return cmd;
} }
struct cmd* struct cmd *parseredirs(struct cmd *cmd, char **ps, char *es) {
parseredirs(struct cmd *cmd, char **ps, char *es)
{
int tok; int tok;
char *q, *eq; char *q, *eq;
@ -397,9 +366,7 @@ parseredirs(struct cmd *cmd, char **ps, char *es)
return cmd; return cmd;
} }
struct cmd* struct cmd *parseblock(char **ps, char *es) {
parseblock(char **ps, char *es)
{
struct cmd *cmd; struct cmd *cmd;
if (!peek(ps, es, "(")) if (!peek(ps, es, "("))
@ -413,9 +380,7 @@ parseblock(char **ps, char *es)
return cmd; return cmd;
} }
struct cmd* struct cmd *parseexec(char **ps, char *es) {
parseexec(char **ps, char *es)
{
char *q, *eq; char *q, *eq;
int tok, argc; int tok, argc;
struct execcmd *cmd; struct execcmd *cmd;
@ -447,9 +412,7 @@ parseexec(char **ps, char *es)
} }
// NUL-terminate all the counted strings. // NUL-terminate all the counted strings.
struct cmd* struct cmd *nulterminate(struct cmd *cmd) {
nulterminate(struct cmd *cmd)
{
int i; int i;
struct backcmd *bcmd; struct backcmd *bcmd;
struct execcmd *ecmd; struct execcmd *ecmd;

View File

@ -13,9 +13,7 @@
#include "kernel/fs.h" #include "kernel/fs.h"
#include "kernel/fcntl.h" #include "kernel/fcntl.h"
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int fd, i; int fd, i;
char path[] = "stressfs0"; char path[] = "stressfs0";
char data[512]; char data[512];

View File

@ -6,17 +6,13 @@
// //
// wrapper so that it's OK if main() does not call exit(). // wrapper so that it's OK if main() does not call exit().
// //
void void _main() {
_main()
{
extern int main(); extern int main();
main(); main();
exit(0); exit(0);
} }
char* char *strcpy(char *s, const char *t) {
strcpy(char *s, const char *t)
{
char *os; char *os;
os = s; os = s;
@ -25,17 +21,13 @@ strcpy(char *s, const char *t)
return os; return os;
} }
int int strcmp(const char *p, const char *q) {
strcmp(const char *p, const char *q)
{
while (*p && *p == *q) while (*p && *p == *q)
p++, q++; p++, q++;
return (uchar)*p - (uchar)*q; return (uchar)*p - (uchar)*q;
} }
uint uint strlen(const char *s) {
strlen(const char *s)
{
int n; int n;
for (n = 0; s[n]; n++) for (n = 0; s[n]; n++)
@ -43,9 +35,7 @@ strlen(const char *s)
return n; return n;
} }
void* void *memset(void *dst, int c, uint n) {
memset(void *dst, int c, uint n)
{
char *cdst = (char *)dst; char *cdst = (char *)dst;
int i; int i;
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
@ -54,18 +44,14 @@ memset(void *dst, int c, uint n)
return dst; return dst;
} }
char* char *strchr(const char *s, char c) {
strchr(const char *s, char c)
{
for (; *s; s++) for (; *s; s++)
if (*s == c) if (*s == c)
return (char *)s; return (char *)s;
return 0; return 0;
} }
char* char *gets(char *buf, int max) {
gets(char *buf, int max)
{
int i, cc; int i, cc;
char c; char c;
@ -81,9 +67,7 @@ gets(char *buf, int max)
return buf; return buf;
} }
int int stat(const char *n, struct stat *st) {
stat(const char *n, struct stat *st)
{
int fd; int fd;
int r; int r;
@ -95,9 +79,7 @@ stat(const char *n, struct stat *st)
return r; return r;
} }
int int atoi(const char *s) {
atoi(const char *s)
{
int n; int n;
n = 0; n = 0;
@ -106,9 +88,7 @@ atoi(const char *s)
return n; return n;
} }
void* void *memmove(void *vdst, const void *vsrc, int n) {
memmove(void *vdst, const void *vsrc, int n)
{
char *dst; char *dst;
const char *src; const char *src;
@ -126,9 +106,7 @@ memmove(void *vdst, const void *vsrc, int n)
return vdst; return vdst;
} }
int int memcmp(const void *s1, const void *s2, uint n) {
memcmp(const void *s1, const void *s2, uint n)
{
const char *p1 = s1, *p2 = s2; const char *p1 = s1, *p2 = s2;
while (n-- > 0) { while (n-- > 0) {
if (*p1 != *p2) { if (*p1 != *p2) {
@ -140,8 +118,6 @@ memcmp(const void *s1, const void *s2, uint n)
return 0; return 0;
} }
void * void *memcpy(void *dst, const void *src, uint n) {
memcpy(void *dst, const void *src, uint n)
{
return memmove(dst, src, n); return memmove(dst, src, n);
} }

View File

@ -21,9 +21,7 @@ typedef union header Header;
static Header base; static Header base;
static Header *freep; static Header *freep;
void void free(void *ap) {
free(void *ap)
{
Header *bp, *p; Header *bp, *p;
bp = (Header *)ap - 1; bp = (Header *)ap - 1;
@ -43,9 +41,7 @@ free(void *ap)
freep = p; freep = p;
} }
static Header* static Header *morecore(uint nu) {
morecore(uint nu)
{
char *p; char *p;
Header *hp; Header *hp;
@ -60,9 +56,7 @@ morecore(uint nu)
return freep; return freep;
} }
void* void *malloc(uint nbytes) {
malloc(uint nbytes)
{
Header *p, *prevp; Header *p, *prevp;
uint nunits; uint nunits;

View File

@ -29,9 +29,7 @@ char buf[BUFSZ];
// what if you pass ridiculous pointers to system calls // what if you pass ridiculous pointers to system calls
// that read user memory with copyin? // that read user memory with copyin?
void void copyin(char *s) {
copyin(char *s)
{
uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff}; uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff};
for (int ai = 0; ai < 2; ai++) { for (int ai = 0; ai < 2; ai++) {
@ -73,9 +71,7 @@ copyin(char *s)
// what if you pass ridiculous pointers to system calls // what if you pass ridiculous pointers to system calls
// that write user memory with copyout? // that write user memory with copyout?
void void copyout(char *s) {
copyout(char *s)
{
uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff}; uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff};
for (int ai = 0; ai < 2; ai++) { for (int ai = 0; ai < 2; ai++) {
@ -114,9 +110,7 @@ copyout(char *s)
} }
// what if you pass ridiculous string pointers to system calls? // what if you pass ridiculous string pointers to system calls?
void void copyinstr1(char *s) {
copyinstr1(char *s)
{
uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff}; uint64 addrs[] = {0x80000000LL, 0xffffffffffffffff};
for (int ai = 0; ai < 2; ai++) { for (int ai = 0; ai < 2; ai++) {
@ -133,9 +127,7 @@ copyinstr1(char *s)
// what if a string system call argument is exactly the size // what if a string system call argument is exactly the size
// of the kernel buffer it is copied into, so that the null // of the kernel buffer it is copied into, so that the null
// would fall just beyond the end of the kernel buffer? // would fall just beyond the end of the kernel buffer?
void void copyinstr2(char *s) {
copyinstr2(char *s)
{
char b[MAXPATH + 1]; char b[MAXPATH + 1];
for (int i = 0; i < MAXPATH; i++) for (int i = 0; i < MAXPATH; i++)
@ -195,9 +187,7 @@ copyinstr2(char *s)
} }
// what if a string argument crosses over the end of last user page? // what if a string argument crosses over the end of last user page?
void void copyinstr3(char *s) {
copyinstr3(char *s)
{
sbrk(8192); sbrk(8192);
uint64 top = (uint64)sbrk(0); uint64 top = (uint64)sbrk(0);
if ((top % PGSIZE) != 0) { if ((top % PGSIZE) != 0) {
@ -240,9 +230,7 @@ copyinstr3(char *s)
// See if the kernel refuses to read/write user memory that the // See if the kernel refuses to read/write user memory that the
// application doesn't have anymore, because it returned it. // application doesn't have anymore, because it returned it.
void void rwsbrk() {
rwsbrk()
{
int fd, n; int fd, n;
uint64 a = (uint64)sbrk(8192); uint64 a = (uint64)sbrk(8192);
@ -286,9 +274,7 @@ rwsbrk()
} }
// test O_TRUNC. // test O_TRUNC.
void void truncate1(char *s) {
truncate1(char *s)
{
char buf[32]; char buf[32];
unlink("truncfile"); unlink("truncfile");
@ -345,9 +331,7 @@ truncate1(char *s)
// this causes a write at an offset beyond the end of the file. // this causes a write at an offset beyond the end of the file.
// such writes fail on xv6 (unlike POSIX) but at least // such writes fail on xv6 (unlike POSIX) but at least
// they don't crash. // they don't crash.
void void truncate2(char *s) {
truncate2(char *s)
{
unlink("truncfile"); unlink("truncfile");
int fd1 = open("truncfile", O_CREATE | O_TRUNC | O_WRONLY); int fd1 = open("truncfile", O_CREATE | O_TRUNC | O_WRONLY);
@ -366,9 +350,7 @@ truncate2(char *s)
close(fd2); close(fd2);
} }
void void truncate3(char *s) {
truncate3(char *s)
{
int pid, xstatus; int pid, xstatus;
close(open("truncfile", O_CREATE | O_TRUNC | O_WRONLY)); close(open("truncfile", O_CREATE | O_TRUNC | O_WRONLY));
@ -419,11 +401,8 @@ truncate3(char *s)
exit(xstatus); exit(xstatus);
} }
// does chdir() call iput(p->cwd) in a transaction? // does chdir() call iput(p->cwd) in a transaction?
void void iputtest(char *s) {
iputtest(char *s)
{
if (mkdir("iputdir") < 0) { if (mkdir("iputdir") < 0) {
printf("%s: mkdir failed\n", s); printf("%s: mkdir failed\n", s);
exit(1); exit(1);
@ -443,9 +422,7 @@ iputtest(char *s)
} }
// does exit() call iput(p->cwd) in a transaction? // does exit() call iput(p->cwd) in a transaction?
void void exitiputtest(char *s) {
exitiputtest(char *s)
{
int pid, xstatus; int pid, xstatus;
pid = fork(); pid = fork();
@ -483,9 +460,7 @@ exitiputtest(char *s)
// for(i = 0; i < 10000; i++) // for(i = 0; i < 10000; i++)
// yield(); // yield();
// } // }
void void openiputtest(char *s) {
openiputtest(char *s)
{
int pid, xstatus; int pid, xstatus;
if (mkdir("oidir") < 0) { if (mkdir("oidir") < 0) {
@ -516,9 +491,7 @@ openiputtest(char *s)
// simple file system tests // simple file system tests
void void opentest(char *s) {
opentest(char *s)
{
int fd; int fd;
fd = open("echo", 0); fd = open("echo", 0);
@ -534,9 +507,7 @@ opentest(char *s)
} }
} }
void void writetest(char *s) {
writetest(char *s)
{
int fd; int fd;
int i; int i;
enum { N = 100, SZ = 10 }; enum { N = 100, SZ = 10 };
@ -575,9 +546,7 @@ writetest(char *s)
} }
} }
void void writebig(char *s) {
writebig(char *s)
{
int i, fd, n; int i, fd, n;
fd = open("big", O_CREATE | O_RDWR); fd = open("big", O_CREATE | O_RDWR);
@ -616,8 +585,8 @@ writebig(char *s)
exit(1); exit(1);
} }
if (((int *)buf)[0] != n) { if (((int *)buf)[0] != n) {
printf("%s: read content of block %d is %d\n", s, printf("%s: read content of block %d is %d\n", s, n,
n, ((int*)buf)[0]); ((int *)buf)[0]);
exit(1); exit(1);
} }
n++; n++;
@ -630,9 +599,7 @@ writebig(char *s)
} }
// many creates, followed by unlink test // many creates, followed by unlink test
void void createtest(char *s) {
createtest(char *s)
{
int i, fd; int i, fd;
enum { N = 52 }; enum { N = 52 };
@ -652,8 +619,7 @@ createtest(char *s)
} }
} }
void dirtest(char *s) void dirtest(char *s) {
{
if (mkdir("dir0") < 0) { if (mkdir("dir0") < 0) {
printf("%s: mkdir failed\n", s); printf("%s: mkdir failed\n", s);
exit(1); exit(1);
@ -675,9 +641,7 @@ void dirtest(char *s)
} }
} }
void void exectest(char *s) {
exectest(char *s)
{
int fd, xstatus, pid; int fd, xstatus, pid;
char *echoargv[] = {"echo", "OK", 0}; char *echoargv[] = {"echo", "OK", 0};
char buf[3]; char buf[3];
@ -727,14 +691,11 @@ exectest(char *s)
printf("%s: wrong output\n", s); printf("%s: wrong output\n", s);
exit(1); exit(1);
} }
} }
// simple fork and pipe read/write // simple fork and pipe read/write
void void pipe1(char *s) {
pipe1(char *s)
{
int fds[2], pid, xstatus; int fds[2], pid, xstatus;
int seq, i, n, cc, total; int seq, i, n, cc, total;
enum { N = 5, SZ = 1033 }; enum { N = 5, SZ = 1033 };
@ -785,11 +746,8 @@ pipe1(char *s)
} }
} }
// test if child is killed (status = -1) // test if child is killed (status = -1)
void void killstatus(char *s) {
killstatus(char *s)
{
int xst; int xst;
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
@ -816,9 +774,7 @@ killstatus(char *s)
} }
// meant to be run w/ at most two CPUs // meant to be run w/ at most two CPUs
void void preempt(char *s) {
preempt(char *s)
{
int pid1, pid2, pid3; int pid1, pid2, pid3;
int pfds[2]; int pfds[2];
@ -872,9 +828,7 @@ preempt(char *s)
} }
// try to find any races between exit and wait // try to find any races between exit and wait
void void exitwait(char *s) {
exitwait(char *s)
{
int i, pid; int i, pid;
for (i = 0; i < 100; i++) { for (i = 0; i < 100; i++) {
@ -902,9 +856,7 @@ exitwait(char *s)
// try to find races in the reparenting // try to find races in the reparenting
// code that handles a parent exiting // code that handles a parent exiting
// when it still has live children. // when it still has live children.
void void reparent(char *s) {
reparent(char *s)
{
int master_pid = getpid(); int master_pid = getpid();
for (int i = 0; i < 200; i++) { for (int i = 0; i < 200; i++) {
int pid = fork(); int pid = fork();
@ -930,9 +882,7 @@ reparent(char *s)
} }
// what if two children exit() at the same time? // what if two children exit() at the same time?
void void twochildren(char *s) {
twochildren(char *s)
{
for (int i = 0; i < 1000; i++) { for (int i = 0; i < 1000; i++) {
int pid1 = fork(); int pid1 = fork();
if (pid1 < 0) { if (pid1 < 0) {
@ -958,9 +908,7 @@ twochildren(char *s)
} }
// concurrent forks to try to expose locking bugs. // concurrent forks to try to expose locking bugs.
void void forkfork(char *s) {
forkfork(char *s)
{
enum { N = 2 }; enum { N = 2 };
for (int i = 0; i < N; i++) { for (int i = 0; i < N; i++) {
@ -994,9 +942,7 @@ forkfork(char *s)
} }
} }
void void forkforkfork(char *s) {
forkforkfork(char *s)
{
unlink("stopforking"); unlink("stopforking");
int pid = fork(); int pid = fork();
@ -1029,9 +975,7 @@ forkforkfork(char *s)
// deadlocks against init's wait()? also used to trigger a "panic: // deadlocks against init's wait()? also used to trigger a "panic:
// release" due to exit() releasing a different p->parent->lock than // release" due to exit() releasing a different p->parent->lock than
// it acquired. // it acquired.
void void reparent2(char *s) {
reparent2(char *s)
{
for (int i = 0; i < 800; i++) { for (int i = 0; i < 800; i++) {
int pid1 = fork(); int pid1 = fork();
if (pid1 < 0) { if (pid1 < 0) {
@ -1050,9 +994,7 @@ reparent2(char *s)
} }
// allocate all mem, free it, and allocate again // allocate all mem, free it, and allocate again
void void mem(char *s) {
mem(char *s)
{
void *m1, *m2; void *m1, *m2;
int pid; int pid;
@ -1090,9 +1032,7 @@ mem(char *s)
// two processes write to the same file descriptor // two processes write to the same file descriptor
// is the offset shared? does inode locking work? // is the offset shared? does inode locking work?
void void sharedfd(char *s) {
sharedfd(char *s)
{
int fd, pid, i, n, nc, np; int fd, pid, i, n, nc, np;
enum { N = 1000, SZ = 10 }; enum { N = 1000, SZ = 10 };
char buf[SZ]; char buf[SZ];
@ -1147,9 +1087,7 @@ sharedfd(char *s)
// four processes write different files at the same // four processes write different files at the same
// time, to test block allocation. // time, to test block allocation.
void void fourfiles(char *s) {
fourfiles(char *s)
{
int fd, pid, i, j, n, total, pi; int fd, pid, i, j, n, total, pi;
char *names[] = {"f0", "f1", "f2", "f3"}; char *names[] = {"f0", "f1", "f2", "f3"};
char *fname; char *fname;
@ -1213,9 +1151,7 @@ fourfiles(char *s)
} }
// four processes create and delete different files in same directory // four processes create and delete different files in same directory
void void createdelete(char *s) {
createdelete(char *s)
{
enum { N = 20, NCHILD = 4 }; enum { N = 20, NCHILD = 4 };
int pid, i, fd, pi; int pid, i, fd, pi;
char name[32]; char name[32];
@ -1285,9 +1221,7 @@ createdelete(char *s)
} }
// can I unlink a file and still read it? // can I unlink a file and still read it?
void void unlinkread(char *s) {
unlinkread(char *s)
{
enum { SZ = 5 }; enum { SZ = 5 };
int fd, fd1; int fd, fd1;
@ -1329,9 +1263,7 @@ unlinkread(char *s)
unlink("unlinkread"); unlink("unlinkread");
} }
void void linktest(char *s) {
linktest(char *s)
{
enum { SZ = 5 }; enum { SZ = 5 };
int fd; int fd;
@ -1389,9 +1321,7 @@ linktest(char *s)
} }
// test concurrent create/link/unlink of the same file // test concurrent create/link/unlink of the same file
void void concreate(char *s) {
concreate(char *s)
{
enum { N = 40 }; enum { N = 40 };
char file[3]; char file[3];
int i, pid, n, fd; int i, pid, n, fd;
@ -1463,8 +1393,7 @@ concreate(char *s)
printf("%s: fork failed\n", s); printf("%s: fork failed\n", s);
exit(1); exit(1);
} }
if(((i % 3) == 0 && pid == 0) || if (((i % 3) == 0 && pid == 0) || ((i % 3) == 1 && pid != 0)) {
((i % 3) == 1 && pid != 0)){
close(open(file, 0)); close(open(file, 0));
close(open(file, 0)); close(open(file, 0));
close(open(file, 0)); close(open(file, 0));
@ -1488,9 +1417,7 @@ concreate(char *s)
// another concurrent link/unlink/create test, // another concurrent link/unlink/create test,
// to look for deadlocks. // to look for deadlocks.
void void linkunlink(char *s) {
linkunlink(char *s)
{
int pid, i; int pid, i;
unlink("x"); unlink("x");
@ -1518,10 +1445,7 @@ linkunlink(char *s)
exit(0); exit(0);
} }
void subdir(char *s) {
void
subdir(char *s)
{
int fd, cc; int fd, cc;
unlink("ff"); unlink("ff");
@ -1699,9 +1623,7 @@ subdir(char *s)
} }
// test writes that are larger than the log. // test writes that are larger than the log.
void void bigwrite(char *s) {
bigwrite(char *s)
{
int fd, sz; int fd, sz;
unlink("bigwrite"); unlink("bigwrite");
@ -1724,10 +1646,7 @@ bigwrite(char *s)
} }
} }
void bigfile(char *s) {
void
bigfile(char *s)
{
enum { N = 20, SZ = 600 }; enum { N = 20, SZ = 600 };
int fd, i, total, cc; int fd, i, total, cc;
@ -1778,9 +1697,7 @@ bigfile(char *s)
unlink("bigfile.dat"); unlink("bigfile.dat");
} }
void void fourteen(char *s) {
fourteen(char *s)
{
int fd; int fd;
// DIRSIZ is 14. // DIRSIZ is 14.
@ -1795,13 +1712,16 @@ fourteen(char *s)
} }
fd = open("123456789012345/123456789012345/123456789012345", O_CREATE); fd = open("123456789012345/123456789012345/123456789012345", O_CREATE);
if (fd < 0) { if (fd < 0) {
printf("%s: create 123456789012345/123456789012345/123456789012345 failed\n", s); printf("%s: create 123456789012345/123456789012345/123456789012345 "
"failed\n",
s);
exit(1); exit(1);
} }
close(fd); close(fd);
fd = open("12345678901234/12345678901234/12345678901234", 0); fd = open("12345678901234/12345678901234/12345678901234", 0);
if (fd < 0) { if (fd < 0) {
printf("%s: open 12345678901234/12345678901234/12345678901234 failed\n", s); printf("%s: open 12345678901234/12345678901234/12345678901234 failed\n",
s);
exit(1); exit(1);
} }
close(fd); close(fd);
@ -1824,9 +1744,7 @@ fourteen(char *s)
unlink("12345678901234"); unlink("12345678901234");
} }
void void rmdot(char *s) {
rmdot(char *s)
{
if (mkdir("dots") != 0) { if (mkdir("dots") != 0) {
printf("%s: mkdir dots failed\n", s); printf("%s: mkdir dots failed\n", s);
exit(1); exit(1);
@ -1861,9 +1779,7 @@ rmdot(char *s)
} }
} }
void void dirfile(char *s) {
dirfile(char *s)
{
int fd; int fd;
fd = open("dirfile", O_CREATE); fd = open("dirfile", O_CREATE);
@ -1918,9 +1834,7 @@ dirfile(char *s)
// test that iput() is called at the end of _namei(). // test that iput() is called at the end of _namei().
// also tests empty file names. // also tests empty file names.
void void iref(char *s) {
iref(char *s)
{
int i, fd; int i, fd;
for (i = 0; i < NINODE + 1; i++) { for (i = 0; i < NINODE + 1; i++) {
@ -1956,9 +1870,7 @@ iref(char *s)
// test that fork fails gracefully // test that fork fails gracefully
// the forktest binary also does this, but it runs out of proc entries first. // the forktest binary also does this, but it runs out of proc entries first.
// inside the bigger usertests binary, we run out of memory first. // inside the bigger usertests binary, we run out of memory first.
void void forktest(char *s) {
forktest(char *s)
{
enum { N = 1000 }; enum { N = 1000 };
int n, pid; int n, pid;
@ -1993,9 +1905,7 @@ forktest(char *s)
} }
} }
void void sbrkbasic(char *s) {
sbrkbasic(char *s)
{
enum { TOOMUCH = 1024 * 1024 * 1024 }; enum { TOOMUCH = 1024 * 1024 * 1024 };
int i, pid, xstatus; int i, pid, xstatus;
char *c, *a, *b; char *c, *a, *b;
@ -2057,9 +1967,7 @@ sbrkbasic(char *s)
exit(xstatus); exit(xstatus);
} }
void void sbrkmuch(char *s) {
sbrkmuch(char *s)
{
enum { BIG = 100 * 1024 * 1024 }; enum { BIG = 100 * 1024 * 1024 };
char *c, *oldbrk, *a, *lastaddr, *p; char *c, *oldbrk, *a, *lastaddr, *p;
uint64 amt; uint64 amt;
@ -2071,7 +1979,9 @@ sbrkmuch(char *s)
amt = BIG - (uint64)a; amt = BIG - (uint64)a;
p = sbrk(amt); p = sbrk(amt);
if (p != a) { if (p != a) {
printf("%s: sbrk test failed to grow big address space; enough phys mem?\n", s); printf("%s: sbrk test failed to grow big address space; enough phys "
"mem?\n",
s);
exit(1); exit(1);
} }
@ -2092,7 +2002,8 @@ sbrkmuch(char *s)
} }
c = sbrk(0); c = sbrk(0);
if (c != a - PGSIZE) { if (c != a - PGSIZE) {
printf("%s: sbrk deallocation produced wrong address, a %x c %x\n", s, a, c); printf("%s: sbrk deallocation produced wrong address, a %x c %x\n", s,
a, c);
exit(1); exit(1);
} }
@ -2118,9 +2029,7 @@ sbrkmuch(char *s)
} }
// can we read the kernel's memory? // can we read the kernel's memory?
void void kernmem(char *s) {
kernmem(char *s)
{
char *a; char *a;
int pid; int pid;
@ -2142,9 +2051,7 @@ kernmem(char *s)
} }
// user code should not be able to write to addresses above MAXVA. // user code should not be able to write to addresses above MAXVA.
void void MAXVAplus(char *s) {
MAXVAplus(char *s)
{
volatile uint64 a = MAXVA; volatile uint64 a = MAXVA;
for (; a != 0; a <<= 1) { for (; a != 0; a <<= 1) {
int pid; int pid;
@ -2167,9 +2074,7 @@ MAXVAplus(char *s)
// if we run the system out of memory, does it clean up the last // if we run the system out of memory, does it clean up the last
// failed allocation? // failed allocation?
void void sbrkfail(char *s) {
sbrkfail(char *s)
{
enum { BIG = 100 * 1024 * 1024 }; enum { BIG = 100 * 1024 * 1024 };
int i, xstatus; int i, xstatus;
int fds[2]; int fds[2];
@ -2188,7 +2093,8 @@ sbrkfail(char *s)
sbrk(BIG - (uint64)sbrk(0)); sbrk(BIG - (uint64)sbrk(0));
write(fds[1], "x", 1); write(fds[1], "x", 1);
// sit around until killed // sit around until killed
for(;;) sleep(1000); for (;;)
sleep(1000);
} }
if (pids[i] != -1) if (pids[i] != -1)
read(fds[0], &scratch, 1); read(fds[0], &scratch, 1);
@ -2234,11 +2140,8 @@ sbrkfail(char *s)
exit(1); exit(1);
} }
// test reads/writes from/to allocated memory // test reads/writes from/to allocated memory
void void sbrkarg(char *s) {
sbrkarg(char *s)
{
char *a; char *a;
int fd, n; int fd, n;
@ -2263,9 +2166,7 @@ sbrkarg(char *s)
} }
} }
void void validatetest(char *s) {
validatetest(char *s)
{
int hi; int hi;
uint64 p; uint64 p;
@ -2281,9 +2182,7 @@ validatetest(char *s)
// does uninitialized data start out zero? // does uninitialized data start out zero?
char uninit[10000]; char uninit[10000];
void void bsstest(char *s) {
bsstest(char *s)
{
int i; int i;
for (i = 0; i < sizeof(uninit); i++) { for (i = 0; i < sizeof(uninit); i++) {
@ -2297,9 +2196,7 @@ bsstest(char *s)
// does exec return an error if the arguments // does exec return an error if the arguments
// are larger than a page? or does it write // are larger than a page? or does it write
// below the stack and wreck the instructions/data? // below the stack and wreck the instructions/data?
void void bigargtest(char *s) {
bigargtest(char *s)
{
int pid, fd, xstatus; int pid, fd, xstatus;
unlink("bigarg-ok"); unlink("bigarg-ok");
@ -2308,7 +2205,10 @@ bigargtest(char *s)
static char *args[MAXARG]; static char *args[MAXARG];
int i; int i;
for (i = 0; i < MAXARG - 1; i++) for (i = 0; i < MAXARG - 1; i++)
args[i] = "bigargs test: failed\n "; args[i] = "bigargs test: failed\n "
" "
" "
" ";
args[MAXARG - 1] = 0; args[MAXARG - 1] = 0;
exec("echo", args); exec("echo", args);
fd = open("bigarg-ok", O_CREATE); fd = open("bigarg-ok", O_CREATE);
@ -2332,9 +2232,7 @@ bigargtest(char *s)
// what happens when the file system runs out of blocks? // what happens when the file system runs out of blocks?
// answer: balloc panics, so this test is not useful. // answer: balloc panics, so this test is not useful.
void void fsfull() {
fsfull()
{
int nfiles; int nfiles;
int fsblocks = 0; int fsblocks = 0;
@ -2383,8 +2281,7 @@ fsfull()
printf("fsfull test finished\n"); printf("fsfull test finished\n");
} }
void argptest(char *s) void argptest(char *s) {
{
int fd; int fd;
fd = open("init", O_RDONLY); fd = open("init", O_RDONLY);
if (fd < 0) { if (fd < 0) {
@ -2397,9 +2294,7 @@ void argptest(char *s)
// check that there's an invalid page beneath // check that there's an invalid page beneath
// the user stack, to catch stack overflow. // the user stack, to catch stack overflow.
void void stacktest(char *s) {
stacktest(char *s)
{
int pid; int pid;
int xstatus; int xstatus;
@ -2422,9 +2317,7 @@ stacktest(char *s)
} }
// check that writes to text segment fault // check that writes to text segment fault
void void textwrite(char *s) {
textwrite(char *s)
{
int pid; int pid;
int xstatus; int xstatus;
@ -2448,9 +2341,7 @@ textwrite(char *s)
// the virtual page address to uint, which (with certain wild system // the virtual page address to uint, which (with certain wild system
// call arguments) resulted in a kernel page faults. // call arguments) resulted in a kernel page faults.
void *big = (void *)0xeaeb0b5b00002f5e; void *big = (void *)0xeaeb0b5b00002f5e;
void void pgbug(char *s) {
pgbug(char *s)
{
char *argv[1]; char *argv[1];
argv[0] = 0; argv[0] = 0;
exec(big, argv); exec(big, argv);
@ -2462,9 +2353,7 @@ pgbug(char *s)
// regression test. does the kernel panic if a process sbrk()s its // regression test. does the kernel panic if a process sbrk()s its
// size to be less than a page, or zero, or reduces the break by an // size to be less than a page, or zero, or reduces the break by an
// amount too small to cause a page to be freed? // amount too small to cause a page to be freed?
void void sbrkbugs(char *s) {
sbrkbugs(char *s)
{
int pid = fork(); int pid = fork();
if (pid < 0) { if (pid < 0) {
printf("fork failed\n"); printf("fork failed\n");
@ -2520,9 +2409,7 @@ sbrkbugs(char *s)
// if process size was somewhat more than a page boundary, and then // if process size was somewhat more than a page boundary, and then
// shrunk to be somewhat less than that page boundary, can the kernel // shrunk to be somewhat less than that page boundary, can the kernel
// still copyin() from addresses in the last page? // still copyin() from addresses in the last page?
void void sbrklast(char *s) {
sbrklast(char *s)
{
uint64 top = (uint64)sbrk(0); uint64 top = (uint64)sbrk(0);
if ((top % 4096) != 0) if ((top % 4096) != 0)
sbrk(4096 - (top % 4096)); sbrk(4096 - (top % 4096));
@ -2543,24 +2430,17 @@ sbrklast(char *s)
exit(1); exit(1);
} }
// does sbrk handle signed int32 wrap-around with // does sbrk handle signed int32 wrap-around with
// negative arguments? // negative arguments?
void void sbrk8000(char *s) {
sbrk8000(char *s)
{
sbrk(0x80000004); sbrk(0x80000004);
volatile char *top = sbrk(0); volatile char *top = sbrk(0);
*(top - 1) = *(top - 1) + 1; *(top - 1) = *(top - 1) + 1;
} }
// regression test. test whether exec() leaks memory if one of the // regression test. test whether exec() leaks memory if one of the
// arguments is invalid. the test passes if the kernel doesn't panic. // arguments is invalid. the test passes if the kernel doesn't panic.
void void badarg(char *s) {
badarg(char *s)
{
for (int i = 0; i < 50000; i++) { for (int i = 0; i < 50000; i++) {
char *argv[2]; char *argv[2];
argv[0] = (char *)0xffffffff; argv[0] = (char *)0xffffffff;
@ -2644,9 +2524,7 @@ struct test {
// //
// directory that uses indirect blocks // directory that uses indirect blocks
void void bigdir(char *s) {
bigdir(char *s)
{
enum { N = 500 }; enum { N = 500 };
int i, fd; int i, fd;
char name[10]; char name[10];
@ -2686,9 +2564,7 @@ bigdir(char *s)
// concurrent writes to try to provoke deadlock in the virtio disk // concurrent writes to try to provoke deadlock in the virtio disk
// driver. // driver.
void void manywrites(char *s) {
manywrites(char *s)
{
int nchildren = 4; int nchildren = 4;
int howmany = 30; // increase to look for deadlock int howmany = 30; // increase to look for deadlock
@ -2743,9 +2619,7 @@ manywrites(char *s)
// file is deleted? if the kernel has this bug, it will panic: balloc: // file is deleted? if the kernel has this bug, it will panic: balloc:
// out of blocks. assumed_free may need to be raised to be more than // out of blocks. assumed_free may need to be raised to be more than
// the number of free blocks. this test takes a long time. // the number of free blocks. this test takes a long time.
void void badwrite(char *s) {
badwrite(char *s)
{
int assumed_free = 600; int assumed_free = 600;
unlink("junk"); unlink("junk");
@ -2778,9 +2652,7 @@ badwrite(char *s)
// test the exec() code that cleans up if it runs out // test the exec() code that cleans up if it runs out
// of memory. it's really a test that such a condition // of memory. it's really a test that such a condition
// doesn't cause a panic. // doesn't cause a panic.
void void execout(char *s) {
execout(char *s)
{
for (int avail = 0; avail < 15; avail++) { for (int avail = 0; avail < 15; avail++) {
int pid = fork(); int pid = fork();
if (pid < 0) { if (pid < 0) {
@ -2813,9 +2685,7 @@ execout(char *s)
} }
// can the kernel tolerate running out of disk space? // can the kernel tolerate running out of disk space?
void void diskfull(char *s) {
diskfull(char *s)
{
int fi; int fi;
int done = 0; int done = 0;
@ -2893,9 +2763,7 @@ diskfull(char *s)
} }
} }
void void outofinodes(char *s) {
outofinodes(char *s)
{
int nzz = 32 * 32; int nzz = 32 * 32;
for (int i = 0; i < nzz; i++) { for (int i = 0; i < nzz; i++) {
char name[32]; char name[32];
@ -2941,8 +2809,7 @@ struct test slowtests[] = {
// run each test in its own process. run returns 1 if child's exit() // run each test in its own process. run returns 1 if child's exit()
// indicates success. // indicates success.
int int run(void f(char *), char *s) {
run(void f(char *), char *s) {
int pid; int pid;
int xstatus; int xstatus;
@ -2964,8 +2831,7 @@ run(void f(char *), char *s) {
} }
} }
int int runtests(struct test *tests, char *justone) {
runtests(struct test *tests, char *justone) {
for (struct test *t = tests; t->s != 0; t++) { for (struct test *t = tests; t->s != 0; t++) {
if ((justone == 0) || strcmp(t->s, justone) == 0) { if ((justone == 0) || strcmp(t->s, justone) == 0) {
if (!run(t->f, t->s)) { if (!run(t->f, t->s)) {
@ -2977,16 +2843,13 @@ runtests(struct test *tests, char *justone) {
return 0; return 0;
} }
// //
// use sbrk() to count how many free physical memory pages there are. // use sbrk() to count how many free physical memory pages there are.
// touches the pages to force allocation. // touches the pages to force allocation.
// because out of memory with lazy allocation results in the process // because out of memory with lazy allocation results in the process
// taking a fault and being killed, fork and report back. // taking a fault and being killed, fork and report back.
// //
int int countfree() {
countfree()
{
int fds[2]; int fds[2];
if (pipe(fds) < 0) { if (pipe(fds) < 0) {
@ -3044,8 +2907,7 @@ countfree()
return n; return n;
} }
int int drivetests(int quick, int continuous, char *justone) {
drivetests(int quick, int continuous, char *justone) {
do { do {
printf("usertests starting\n"); printf("usertests starting\n");
int free0 = countfree(); int free0 = countfree();
@ -3065,7 +2927,8 @@ drivetests(int quick, int continuous, char *justone) {
} }
} }
if ((free1 = countfree()) < free0) { if ((free1 = countfree()) < free0) {
printf("FAILED -- lost some free pages %d (out of %d)\n", free1, free0); printf("FAILED -- lost some free pages %d (out of %d)\n", free1,
free0);
if (continuous != 2) { if (continuous != 2) {
return 1; return 1;
} }
@ -3074,9 +2937,7 @@ drivetests(int quick, int continuous, char *justone) {
return 0; return 0;
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int continuous = 0; int continuous = 0;
int quick = 0; int quick = 0;
char *justone = 0; char *justone = 0;

View File

@ -4,9 +4,7 @@
char buf[512]; char buf[512];
void void wc(int fd, char *name) {
wc(int fd, char *name)
{
int i, n; int i, n;
int l, w, c, inword; int l, w, c, inword;
@ -32,9 +30,7 @@ wc(int fd, char *name)
printf("%d %d %d %s\n", l, w, c, name); printf("%d %d %d %s\n", l, w, c, name);
} }
int int main(int argc, char *argv[]) {
main(int argc, char *argv[])
{
int fd, i; int fd, i;
if (argc <= 1) { if (argc <= 1) {

View File

@ -5,9 +5,7 @@
#include "kernel/stat.h" #include "kernel/stat.h"
#include "user/user.h" #include "user/user.h"
int int main(void) {
main(void)
{
if (fork() > 0) if (fork() > 0)
sleep(5); // Let child exit before parent. sleep(5); // Let child exit before parent.
exit(0); exit(0);