pi for pipe, rather than p, to avoid confusion with proc's p->lock

This commit is contained in:
Robert Morris 2019-07-20 17:07:20 -04:00
parent 3333665ab6
commit 06e49a58dc
2 changed files with 51 additions and 58 deletions

View file

@ -22,33 +22,33 @@ struct pipe {
int
pipealloc(struct file **f0, struct file **f1)
{
struct pipe *p;
struct pipe *pi;
p = 0;
pi = 0;
*f0 = *f1 = 0;
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
goto bad;
if((p = (struct pipe*)kalloc()) == 0)
if((pi = (struct pipe*)kalloc()) == 0)
goto bad;
p->readopen = 1;
p->writeopen = 1;
p->nwrite = 0;
p->nread = 0;
initlock(&p->lock, "pipe");
pi->readopen = 1;
pi->writeopen = 1;
pi->nwrite = 0;
pi->nread = 0;
initlock(&pi->lock, "pipe");
(*f0)->type = FD_PIPE;
(*f0)->readable = 1;
(*f0)->writable = 0;
(*f0)->pipe = p;
(*f0)->pipe = pi;
(*f1)->type = FD_PIPE;
(*f1)->readable = 0;
(*f1)->writable = 1;
(*f1)->pipe = p;
(*f1)->pipe = pi;
return 0;
//PAGEBREAK: 20
bad:
if(p)
kfree((char*)p);
if(pi)
kfree((char*)pi);
if(*f0)
fileclose(*f0);
if(*f1)
@ -57,73 +57,73 @@ pipealloc(struct file **f0, struct file **f1)
}
void
pipeclose(struct pipe *p, int writable)
pipeclose(struct pipe *pi, int writable)
{
acquire(&p->lock);
acquire(&pi->lock);
if(writable){
p->writeopen = 0;
wakeup(&p->nread);
pi->writeopen = 0;
wakeup(&pi->nread);
} else {
p->readopen = 0;
wakeup(&p->nwrite);
pi->readopen = 0;
wakeup(&pi->nwrite);
}
if(p->readopen == 0 && p->writeopen == 0){
release(&p->lock);
kfree((char*)p);
if(pi->readopen == 0 && pi->writeopen == 0){
release(&pi->lock);
kfree((char*)pi);
} else
release(&p->lock);
release(&pi->lock);
}
//PAGEBREAK: 40
int
pipewrite(struct pipe *p, uint64 addr, int n)
pipewrite(struct pipe *pi, uint64 addr, int n)
{
int i;
char ch;
struct proc *pr = myproc();
acquire(&p->lock);
acquire(&pi->lock);
for(i = 0; i < n; i++){
while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full
if(p->readopen == 0 || myproc()->killed){
release(&p->lock);
while(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
if(pi->readopen == 0 || myproc()->killed){
release(&pi->lock);
return -1;
}
wakeup(&p->nread);
sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep
wakeup(&pi->nread);
sleep(&pi->nwrite, &pi->lock); //DOC: pipewrite-sleep
}
if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
break;
p->data[p->nwrite++ % PIPESIZE] = ch;
pi->data[pi->nwrite++ % PIPESIZE] = ch;
}
wakeup(&p->nread); //DOC: pipewrite-wakeup1
release(&p->lock);
wakeup(&pi->nread); //DOC: pipewrite-wakeup1
release(&pi->lock);
return n;
}
int
piperead(struct pipe *p, uint64 addr, int n)
piperead(struct pipe *pi, uint64 addr, int n)
{
int i;
struct proc *pr = myproc();
char ch;
acquire(&p->lock);
while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty
acquire(&pi->lock);
while(pi->nread == pi->nwrite && pi->writeopen){ //DOC: pipe-empty
if(myproc()->killed){
release(&p->lock);
release(&pi->lock);
return -1;
}
sleep(&p->nread, &p->lock); //DOC: piperead-sleep
sleep(&pi->nread, &pi->lock); //DOC: piperead-sleep
}
for(i = 0; i < n; i++){ //DOC: piperead-copy
if(p->nread == p->nwrite)
if(pi->nread == pi->nwrite)
break;
ch = p->data[p->nread++ % PIPESIZE];
ch = pi->data[pi->nread++ % PIPESIZE];
if(copyout(pr->pagetable, addr + i, &ch, 1) == -1)
break;
}
wakeup(&p->nwrite); //DOC: piperead-wakeup
release(&p->lock);
wakeup(&pi->nwrite); //DOC: piperead-wakeup
release(&pi->lock);
return i;
}

View file

@ -510,12 +510,6 @@ sleep(void *chan, struct spinlock *lk)
{
struct proc *p = myproc();
if(p == 0)
panic("sleep");
if(lk == 0)
panic("sleep without lk");
// Must acquire p->lock in order to
// change p->state and then call sched.
// Once we hold p->lock, we can be
@ -543,17 +537,6 @@ sleep(void *chan, struct spinlock *lk)
}
}
//PAGEBREAK!
// Wake up p if it is sleeping in wait(); used by exit().
// Caller must hold p->lock.
static void
wakeup1(struct proc *p)
{
if(p->chan == p && p->state == SLEEPING) {
p->state = RUNNABLE;
}
}
// Wake up all processes sleeping on chan.
// Must be called without any p->lock.
void
@ -570,6 +553,16 @@ wakeup(void *chan)
}
}
// Wake up p if it is sleeping in wait(); used by exit().
// Caller must hold p->lock.
static void
wakeup1(struct proc *p)
{
if(p->chan == p && p->state == SLEEPING) {
p->state = RUNNABLE;
}
}
// Kill the process with the given pid.
// The victim won't exit until it tries to return
// to user space (see usertrap() in trap.c).