pi for pipe, rather than p, to avoid confusion with proc's p->lock
This commit is contained in:
parent
3333665ab6
commit
06e49a58dc
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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).
|
||||
|
|
Loading…
Reference in a new issue