Mercurial > hg > CbC > CbC_xv6
view src/impl/ConsoleIO.cbc @ 351:1fb6c09db515
add cbc_consoleread2
author | anatofuz <anatofuz@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 02 Mar 2020 18:16:50 +0900 |
parents | 0e72eb96b6b1 |
children | 582f538160d8 |
line wrap: on
line source
#include "../context.h" #interface "IO.h" // ---- // typedef struct ConsoleIO <Type, Isa> impl IO { // __code consoleread(Type* IO, struct inode* ip, char* dst, int n, __code next(...)); // __code consoleread1(Type* IO, int n, int target, char* dst, struct inode* ip, __code next(...)); // __code consoleread2(Type* IO, struct inode* ip, __code next(...)); // __code next(....); // } ConsoleIO; // ---- IO* createConsoleIO(struct Context* cbc_context) { struct IO* io = new IO(); struct ConsoleIO* console_io = new ConsoleIO(); io->io = (union Data*)console_io; console_io->IO = NULL; console_io->ip = NULL; console_io->dst = NULL; console_io->n = 0; console_io->target = 0; console_io->consoleread = C_consoleread; console_io->consoleread1 = C_consoleread1; console_io->consoleread2 = C_consoleread2; io->read = C_readConsoleIO; io->write = C_writeConsoleIO; io->close = C_closeConsoleIO; return io; } __code readConsoleIO(struct ConsoleIO* io, struct file* file, char* addr, int n, __code next(...)) { struct inode* ip = file->ip; // args should be assigned to the impl structure goto io->consoleread(__code next(...)); } __code consoleread(struct ConsoleIO* IO, struct inode* ip, char* dst, int n, __code next(...)) { uint target; iunlock(ip); target = n; acquire(&input.lock); if (n > 0) { goto IO->consoleread2(IO, n, ip, target, dst, ip, next); } goto IO->consoleread1(IO, n, target, dst, ip, next); } __code consoleread1(struct ConsoleIO* IO, int n, int target, char* dst, struct inode* ip, __code next(...)) { int 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 == 1) { if (n > 0) { goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2); } } release(&input.lock); ilock(ip); goto next(target - n); } __code consoleread2(struct ConsoleIO* IO, struct inode* ip, __code next(...)) { if (input.r == input.w) { // input is global variable if (proc->killed) { release(&input.lock); ilock(ip); goto next(-1); } goto cbc_sleep(&input.r, &input.lock, cbc_consoleread2); } goto IO->consoleread1(); } __code writeConsoleIO(struct ConsoleIO* io, struct file* file, char* addr, int n, __code next(...)) { goto next(...); } __code closeConsoleIO(struct ConsoleIO* io, struct file* file, int fd, __code next(...)) { goto next(...); }