view src/impl/file_impl_pipe.cbc @ 177:d4e068b15f30

tweak
author anatofuz
date Fri, 17 Jan 2020 15:09:01 +0900
parents da4c83ae7ada
children 2842d9e65751
line wrap: on
line source

#include "../context.h"
#interface "file.h"

// ----
// typedef struct pipe<Impl, Isa> impl file {
//     #define PIPESIZE 512
//     struct spinlock lock;
//     char data[PIPESIZE];
//     uint nread;     // number of bytes read
//     uint nwrite;    // number of bytes written
//     int readopen;   // read fd is still open
//     int writeopen;  // write fd is still open
// } pipe;
// ----

file* createpipe(struct Context* cbc_context) {
    struct file* file  = new file();
    struct pipe* pipe = new pipe();
    file->file = (union Data*)pipe;
    pipe->lock = 0;
    pipe->spinlock  = 0;
    pipe->data  = 0;
    pipe->nread  = 0;
    pipe->nwrite  = 0;
    pipe->readopen  = 0;
    pipe->writeopen  = 0;
    file->off = 0;
    file->st = NULL;
    file->addr = NULL;
    file->n  = 0;
    file->stat = C_statpipe;
    file->read = C_readpipe;
    file->write = C_writepipe;
    file->close = C_closepipe;
    return file;
}
__code statpipe(struct pipe* file, struct stat* st, __code next(...)) {

    goto next(...);
}

__code readpipe(struct pipe* file, char* addr, int n, __code next(...)) {
    acquire(&p->lock);
    goto cbc_piperead1(file,addr,n,next);
}

__code piperead1(struct pipe* p, char* addr, int n, __code next(...)) {
    if (p->nread == p->nwrite && p->writeopen){
        goto cbc_piperead2(p,addr,n,next);
    }
    n = 0;
    goto cbc_piperead3(p,addr,n,next);
}

__code piperead2(struct pipe* p, char* addr, int n, __code next(...)) {
    if(proc->killed){
        release(&p->lock);
        goto cbc_context->error();
    }
    goto cbc_sleep(p,&p->nread, &p->lock, next,cbc_piperead1);
}

__code cbc_sleep(struct pipe* p, unit* nread, struct spinlock* lock, __code next(...), __code pread(...)){
    if(proc == 0) {
        goto cbc_context->panic("sleep");
    }

    if(lk == 0) {
        goto cbc_context->panic("sleep without lk");
    }

    if(lk != &ptable.lock){  //DOC: sleeplock0
        acquire(&ptable.lock);  //DOC: sleeplock1
        release(lk);
    }
    goto cbc_sched(cbc_sleep1);
}

__code cbc_sched_stub(struct pipe* p, unit* nread, struct spinlock* lock, __code next(...), __code pread(...)){
    proc->chan = chan;
    proc->state = SLEEPING;
    proc->lk = lk;
    proc->cbc_next = next1;
}

__code writepipe(struct pipe* file, char* addr, int n, __code next(...)) {

    goto next(...);
}

__code closepipe(struct pipe* file,int fd,__code next(...)) {
    proc->ofile[fd] = 0;
    goto cbc_fileclose(f,next);
}


__code cbc_fileclose(struct file* file, __code next(...)) {
    struct file ff;
    acquire(*ftable.loc)

    if (f->ref < 1) {
        goto cbc_context->kernel_error->panic("file close");
    }
    goto cbc_fileclose2(f,ff,next);
}

__code cbc_fileclose2(struct file* file, struct file* ff,__code next(...)) {
    if (--f->ref > 0) {
        release(&ftable.lock);
        goto cbc_context->return();
    }
    goto cbc_fileclose3(f,ff,next);
}

__code cbc_fileclose3(struct file* file, struct file* ff,__code next(...)) {
    *ff = *f;
    f->ref = 0;
    f->type = FD_NONE;
    relsease(&ftable.lock);
    
    goto cbc_pipe_close(ff.pipe,ff.writable,next);
}

__code cbc_pipe_close(struct pipe* p, int writable, __code next(...)) {
    acquire(&p->lock);
    if (writable) {
        goto cbc_pipe_close_writeopen(p,next);
    }
    goto cbc_pipe_close_readopen(p,next);
}


__code cbc_pipe_close_writeopen(struct pipe* p, __code next(...)) {
    p->writeopen = 0;
    goto cbc_wakeup(&p->nread,p,cbc_pipe_release,next);
}

__code cbc_pipe_close_readopen(struct pipe* p, __code next(...)) {
    p->writeopen = 0;
    goto cbc_->wakeup(&p->nwrite,p,cbc_pipe_release,next);
}