Mercurial > hg > Members > menikon > CbC_xv6
view src/impl/file_impl_pipe.cbc @ 198:6e28bd30e8a7
fix
author | menikon <e165723@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 22 Jan 2020 20:28:26 +0900 |
parents | 000e247dc51d |
children | 14aa35b56347 |
line wrap: on
line source
#include "../../context.h" #interface "file.h" // ---- // typedef struct pipe<Impl, Isa> impl file { // #define PIPESIZE 512 // union Data* file; // 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 // // int ref; // reference count // char readable; // char writable; // unsigned int off; // // // interface field // int n; // char* addr; // // // private code gear // __code piperead1(Impl* pipe, char* addr, int n, __code next(...)); // __code piperead2(Impl* pipe, char* addr, int n, __code next(...)); // __code cbc_pipeclose(Impl* pipe, Isa* file, __code next(...)); // __code cbc_pipeclose2(Impl* pipe, Isa* file, Isa* ff, __code next(...)); // __code cbc_pipeclose3(Impl* pipe, Isa* file, Isa* ff, __code next(...)); // __code cbc_pipeclose4(Impl* pipe, int writable, __code next(...)); // __code cbc_pipe_close_writeopen(Impl* pipe, __code next(...)); // __code cbc_pipe_close_readopen(Impl* pipe, __code next(...)); // } pipe; // ---- file* createpipe(struct Context* cbc_context) { struct file* file = new file(); struct pipe* pipe = new pipe(); file->file = (union Data*)pipe; pipe->file = (union Data*)file; pipe->lock = 0; pipe->spinlock = 0; pipe->data = 0; pipe->nread = 0; pipe->nwrite = 0; pipe->readopen = 0; pipe->writeopen = 0; pipe->ref = 0; pipe->readable = 0; pipe->writable = 0; pipe->off = 0; pipe->int = 0; pipe->n = 0; pipe->addr = NULL; file->st = NULL; file->addr = NULL; file->n = 0; file->fd = 0; pipe->piperead1 = C_piperead1pipe; pipe->piperead2 = C_piperead2pipe; pipe->cbc_pipeclose = C_cbc_pipeclosepipe; pipe->cbc_pipeclose2 = C_cbc_pipeclose2pipe; pipe->cbc_pipeclose3 = C_cbc_pipeclose3pipe; pipe->cbc_pipeclose4 = C_cbc_pipeclose4pipe; pipe->cbc_pipe_close_writeopen = C_cbc_pipe_close_writeopenpipe; pipe->cbc_pipe_close_readopen = C_cbc_pipe_close_readopenpipe; file->read = C_readpipe; file->write = C_writepipe; file->close = C_closepipe; return file; } __code statpipe(struct pipe* file, struct stat* st, __code next(...)) { //:skip 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(...)){ //:skip 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(...)){ //:skip 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 pipeclose(struct pipe* file,int fd,__code next(...)) { proc->ofile[fd] = 0; goto file->cbc_pipeclose(file->file, next); } __code cbc_pipeclose(struct pipe* pipe, struct file* file, __code next(...)) { struct file ff; acquire(*ftable.loc) if (f->ref < 1) { goto cbc_context->kernel_error->panic("file close"); } goto pipe->cbc_pipeclose2(f,ff,next); } __code cbc_pipeclose2(struct pipe* pipe,struct file* file, struct file* ff,__code next(...)) { if (--f->ref > 0) { release(&ftable.lock); goto cbc_context->return(); } goto pipe->cbc_pipeclose3(f,ff,next); } __code cbc_pipeclose3(struct pipe* pipe,struct file* file, struct file* ff,__code next(...)) { *ff = *f; f->ref = 0; f->type = FD_NONE; relsease(&ftable.lock); struct pipe* p = ff.pipe; int writable = ff.writable; goto pipe->cbc_pipeclose4(p,writable,next); } __code cbc_pipeclose4(struct pipe* pipe, int writable, __code next(...)) { acquire(&pipe->lock); if (writable) { goto pipe->cbc_pipe_close_writeopen(next); } goto pipe->cbc_pipe_close_readopen(next); } __code cbc_pipe_close_writeopen(struct pipe* pipe, __code next(...)) { pipe->writeopen = 0; goto cbc_wakeup(&pipe->nread,pipe,cbc_pipe_release,next); } __code cbc_pipe_close_readopen(struct pipe* pipe, __code next(...)) { pipe->readopen = 0; goto cbc_context->wakeup(&pipe->nwrite,pipe,cbc_pipe_release,next); }