# HG changeset patch # User mir3636 # Date 1547719879 -32400 # Node ID 36bd61f5c847bc418daf86db1a53f352a5c8c92a # Parent ee58360d0e9937a20fa6ed80cdd77831d580aa15 rewrite sys_read cbc diff -r ee58360d0e99 -r 36bd61f5c847 src/console.c --- 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; } diff -r ee58360d0e99 -r 36bd61f5c847 src/file.c --- 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) { diff -r ee58360d0e99 -r 36bd61f5c847 src/fs.c --- 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) diff -r ee58360d0e99 -r 36bd61f5c847 src/makefile-armgccbc --- 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 = diff -r ee58360d0e99 -r 36bd61f5c847 src/proc.c --- 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) diff -r ee58360d0e99 -r 36bd61f5c847 src/syscall.c --- 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](); diff -r ee58360d0e99 -r 36bd61f5c847 src/sysfile.c --- 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;