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(...);
}