changeset 24:36bd61f5c847

rewrite sys_read cbc
author mir3636
date Thu, 17 Jan 2019 19:11:19 +0900
parents ee58360d0e99
children a5ccbc210ff8
files src/console.c src/file.c src/fs.c src/makefile-armgccbc src/proc.c src/syscall.c src/sysfile.c
diffstat 7 files changed, 200 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/console.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/console.c	Thu Jan 17 19:11:19 2019 +0900
@@ -215,6 +215,72 @@
     release(&input.lock);
 }
 
+__code cbc_consoleread (struct inode *ip, char *dst, int n, __code(*next)(int ret))
+{
+    uint target;
+    int c;
+
+    iunlock(ip);
+
+    target = n;
+    acquire(&input.lock);
+
+    while (n > 0) {
+        while (input.r == input.w) {
+            if (proc->killed) {
+                release(&input.lock);
+                ilock(ip);
+                goto next(-1);
+            }
+
+            proc->cbc_arg.cbc_console_arg.n = n;
+	    proc->cbc_arg.cbc_console_arg.dst = dst;
+	    proc->cbc_arg.cbc_console_arg.ip = ip;
+	    proc->cbc_arg.cbc_console_arg.next = next;
+            goto cbc_sleep(&input.r, &input.lock, cbc_consoleread1);
+        }
+}
+
+__code cbc_consoleread1 (__code(*next)(int ret))
+{
+    int cont = 1;
+    proc->cbc_arg.cbc_console_arg.n = n;
+    proc->cbc_arg.cbc_console_arg.dst = dst;
+    proc->cbc_arg.cbc_console_arg.ip = ip;
+    
+    c = input.buf[input.r++ % INPUT_BUF];
+
+        if (c == C('D')) {  // EOF
+            if (n < target) {
+                // Save ^D for next time, to make sure
+                // caller gets a 0-byte result.
+                input.r--;  
+            }
+            cont = 0;
+       }
+
+        *dst++ = c;
+        --n;
+
+        if (c == '\n') {
+            cont = 0;
+        }
+    
+
+    if (cont){
+        proc->cbc_arg.cbc_console_arg.n = n;
+        proc->cbc_arg.cbc_console_arg.dst = dst;
+        proc->cbc_arg.cbc_console_arg.ip = ip;
+	proc->cbc_arg.cbc_console_arg.next = next;
+        goto cbc_sleep(&input.r, &input.lock, cbc_consoleread1);
+    }
+    
+    release(&input.lock);
+    ilock(ip);
+
+    goto next(target - n);
+}
+
 int consoleread (struct inode *ip, char *dst, int n)
 {
     uint target;
@@ -288,6 +354,8 @@
 
     devsw[CONSOLE].write = consolewrite;
     devsw[CONSOLE].read = consoleread;
+    cbc_devsw[CONSOLE].write = cbc_consolewrite;
+    cbc_devsw[CONSOLE].read = cbc_consoleread;
 
     cons.locking = 1;
 }
--- a/src/file.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/file.c	Thu Jan 17 19:11:19 2019 +0900
@@ -98,6 +98,35 @@
     return -1;
 }
 
+__code cbc_fileread1 (int r, struct file *f, char *addr, int n, __code (*next)(int ret))
+{
+    if (r > 0)
+        f->off += r;
+    iunlock(f->ip);
+    goto next(r);
+}
+
+__code cbc_fileread (struct file *f, char *addr, int n, __code (*next)(int ret))
+{
+    int r;
+
+    if (f->readable == 0) {
+        goto next(-1);
+    }
+
+    if (f->type == FD_PIPE) {
+        goto cbc_piperead(f->pipe, addr, n, next);
+    }
+
+    if (f->type == FD_INODE) {
+        ilock(f->ip);
+
+        goto cbc_readi(f->ip, addr, f->off, n);
+    }
+
+    goto cbc_panic("fileread");
+}
+
 // Read from file f.
 int fileread (struct file *f, char *addr, int n)
 {
--- a/src/fs.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/fs.c	Thu Jan 17 19:11:19 2019 +0900
@@ -453,6 +453,37 @@
     st->size = ip->size;
 }
 
+__code cbc_readi (struct inode *ip, char *dst, uint off, uint n, __code (*next)(int ret))
+{
+    uint tot, m;
+    struct buf *bp;
+
+    if (ip->type == T_DEV) {
+        if (ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read) {
+            goto next(-1);
+        }
+
+        goto cbc_devsw[ip->major].read(ip, dst, n);
+    }
+
+    if (off > ip->size || off + n < off) {
+        goto next(-1);
+    }
+
+    if (off + n > ip->size) {
+        n = ip->size - off;
+    }
+
+    for (tot = 0; tot < n; tot += m, off += m, dst += m) {
+        bp = bread(ip->dev, bmap(ip, off / BSIZE));
+        m = min(n - tot, BSIZE - off%BSIZE);
+        memmove(dst, bp->data + off % BSIZE, m);
+        brelse(bp);
+    }
+
+    goto next(n);
+}
+
 //PAGEBREAK!
 // Read data from inode.
 int readi (struct inode *ip, char *dst, uint off, uint n)
--- a/src/makefile-armgccbc	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/makefile-armgccbc	Thu Jan 17 19:11:19 2019 +0900
@@ -3,11 +3,15 @@
 
 include makefile.inc
 
-CC = /usr/local/arm-cbc/bin/arm-none-eabi-gcc -B/usr/local/arm-cbc/bin/arm-none-eabi-
-AS = arm-linux-gnu-gcc
-LD = arm-linux-gnu-ld
-OBJCOPY = arm-linux-gnu-objcopy
-OBJDUMP = arm-linux-gnu-objdump
+CC = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-gcc -B/mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-
+#AS = arm-linux-gnu-gcc
+AS = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-gcc
+#LD = arm-linux-gnu-ld
+LD = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-ld
+#OBJCOPY = arm-linux-gnu-objcopy
+OBJCOPY = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-objcopy
+#OBJDUMP = arm-linux-gnu-objdump
+OBJDUMP = /mnt/dalmore-home/one/src/armgcc/cross/bin/arm-none-eabi-objdump
 CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -Wall -I. -g -O0
 
 ASFLAGS = 
--- a/src/proc.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/proc.c	Thu Jan 17 19:11:19 2019 +0900
@@ -411,6 +411,43 @@
     // Return to "caller", actually trapret (see allocproc).
 }
 
+__code cbc_sleep1()
+{
+    struct spinlock *lk = proc->lk;
+    // Tidy up.
+    proc->chan = 0;
+
+    // Reacquire original lock.
+    if(lk != &ptable.lock){  //DOC: sleeplock2
+        release(&ptable.lock);
+        acquire(lk);
+    }
+    goto proc->cbc_next();
+}
+
+__code cbc_sleep(void *chan, struct spinlock *lk, __code(*next1)())
+{
+    //show_callstk("sleep");
+
+    if(proc == 0) {
+        panic("sleep");
+    }
+
+    if(lk == 0) {
+        panic("sleep without lk");
+    }
+
+    if(lk != &ptable.lock){  //DOC: sleeplock0
+        acquire(&ptable.lock);  //DOC: sleeplock1
+        release(lk);
+    }
+    proc->chan = chan;
+    proc->state = SLEEPING;
+    proc->cbc_next = next1;
+
+    goto cbc_sched(cbc_sleep1);
+}
+
 // Atomically release lock and sleep on chan.
 // Reacquires lock when awakened.
 void sleep(void *chan, struct spinlock *lk)
--- a/src/syscall.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/syscall.c	Thu Jan 17 19:11:19 2019 +0900
@@ -139,6 +139,15 @@
         [SYS_close]   =sys_close,
 };
 
+static __code (*cbccodes[])(void) = {
+	[SYS_cbc_read]	= cbc_read, 
+};
+
+__code cbc_ret(int ret){
+    proc->tf->r0 = ret;
+    goto cbc_trap_return();
+}
+
 void syscall(void)
 {
     int num;
@@ -148,6 +157,12 @@
 
     //cprintf ("syscall(%d) from %s(%d)\n", num, proc->name, proc->pid);
 
+    if((num > 0) && (num > NELEM(syscalls)) && cbccodes[num]) {
+	
+    	goto (cbccodes[num])(cbc_ret);
+    }
+
+
     if((num > 0) && (num <= NELEM(syscalls)) && syscalls[num]) {
         ret = syscalls[num]();
 
--- a/src/sysfile.c	Mon Dec 17 16:55:22 2018 +0900
+++ b/src/sysfile.c	Thu Jan 17 19:11:19 2019 +0900
@@ -74,6 +74,17 @@
     return fd;
 }
 
+__code cbc_read(__code (*next)(int ret)){
+    struct file *f;
+    int n;
+    char *p;
+
+    if(argfd(0, 0, &f) < 0 || argint(2, &n) < 0 || argptr(1, &p, n) < 0) {
+        goto next(-1);
+    }
+    goto cbc_fileread(f, p, n, next);
+}
+
 int sys_read(void)
 {
     struct file *f;