pi for pipe, rather than p, to avoid confusion with proc's p->lock
This commit is contained in:
parent
3333665ab6
commit
06e49a58dc
2 changed files with 51 additions and 58 deletions
|
@ -22,33 +22,33 @@ struct pipe {
|
||||||
int
|
int
|
||||||
pipealloc(struct file **f0, struct file **f1)
|
pipealloc(struct file **f0, struct file **f1)
|
||||||
{
|
{
|
||||||
struct pipe *p;
|
struct pipe *pi;
|
||||||
|
|
||||||
p = 0;
|
pi = 0;
|
||||||
*f0 = *f1 = 0;
|
*f0 = *f1 = 0;
|
||||||
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
|
if((*f0 = filealloc()) == 0 || (*f1 = filealloc()) == 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
if((p = (struct pipe*)kalloc()) == 0)
|
if((pi = (struct pipe*)kalloc()) == 0)
|
||||||
goto bad;
|
goto bad;
|
||||||
p->readopen = 1;
|
pi->readopen = 1;
|
||||||
p->writeopen = 1;
|
pi->writeopen = 1;
|
||||||
p->nwrite = 0;
|
pi->nwrite = 0;
|
||||||
p->nread = 0;
|
pi->nread = 0;
|
||||||
initlock(&p->lock, "pipe");
|
initlock(&pi->lock, "pipe");
|
||||||
(*f0)->type = FD_PIPE;
|
(*f0)->type = FD_PIPE;
|
||||||
(*f0)->readable = 1;
|
(*f0)->readable = 1;
|
||||||
(*f0)->writable = 0;
|
(*f0)->writable = 0;
|
||||||
(*f0)->pipe = p;
|
(*f0)->pipe = pi;
|
||||||
(*f1)->type = FD_PIPE;
|
(*f1)->type = FD_PIPE;
|
||||||
(*f1)->readable = 0;
|
(*f1)->readable = 0;
|
||||||
(*f1)->writable = 1;
|
(*f1)->writable = 1;
|
||||||
(*f1)->pipe = p;
|
(*f1)->pipe = pi;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
//PAGEBREAK: 20
|
//PAGEBREAK: 20
|
||||||
bad:
|
bad:
|
||||||
if(p)
|
if(pi)
|
||||||
kfree((char*)p);
|
kfree((char*)pi);
|
||||||
if(*f0)
|
if(*f0)
|
||||||
fileclose(*f0);
|
fileclose(*f0);
|
||||||
if(*f1)
|
if(*f1)
|
||||||
|
@ -57,73 +57,73 @@ pipealloc(struct file **f0, struct file **f1)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
pipeclose(struct pipe *p, int writable)
|
pipeclose(struct pipe *pi, int writable)
|
||||||
{
|
{
|
||||||
acquire(&p->lock);
|
acquire(&pi->lock);
|
||||||
if(writable){
|
if(writable){
|
||||||
p->writeopen = 0;
|
pi->writeopen = 0;
|
||||||
wakeup(&p->nread);
|
wakeup(&pi->nread);
|
||||||
} else {
|
} else {
|
||||||
p->readopen = 0;
|
pi->readopen = 0;
|
||||||
wakeup(&p->nwrite);
|
wakeup(&pi->nwrite);
|
||||||
}
|
}
|
||||||
if(p->readopen == 0 && p->writeopen == 0){
|
if(pi->readopen == 0 && pi->writeopen == 0){
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
kfree((char*)p);
|
kfree((char*)pi);
|
||||||
} else
|
} else
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
//PAGEBREAK: 40
|
//PAGEBREAK: 40
|
||||||
int
|
int
|
||||||
pipewrite(struct pipe *p, uint64 addr, int n)
|
pipewrite(struct pipe *pi, uint64 addr, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char ch;
|
char ch;
|
||||||
struct proc *pr = myproc();
|
struct proc *pr = myproc();
|
||||||
|
|
||||||
acquire(&p->lock);
|
acquire(&pi->lock);
|
||||||
for(i = 0; i < n; i++){
|
for(i = 0; i < n; i++){
|
||||||
while(p->nwrite == p->nread + PIPESIZE){ //DOC: pipewrite-full
|
while(pi->nwrite == pi->nread + PIPESIZE){ //DOC: pipewrite-full
|
||||||
if(p->readopen == 0 || myproc()->killed){
|
if(pi->readopen == 0 || myproc()->killed){
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
wakeup(&p->nread);
|
wakeup(&pi->nread);
|
||||||
sleep(&p->nwrite, &p->lock); //DOC: pipewrite-sleep
|
sleep(&pi->nwrite, &pi->lock); //DOC: pipewrite-sleep
|
||||||
}
|
}
|
||||||
if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
|
if(copyin(pr->pagetable, &ch, addr + i, 1) == -1)
|
||||||
break;
|
break;
|
||||||
p->data[p->nwrite++ % PIPESIZE] = ch;
|
pi->data[pi->nwrite++ % PIPESIZE] = ch;
|
||||||
}
|
}
|
||||||
wakeup(&p->nread); //DOC: pipewrite-wakeup1
|
wakeup(&pi->nread); //DOC: pipewrite-wakeup1
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
piperead(struct pipe *p, uint64 addr, int n)
|
piperead(struct pipe *pi, uint64 addr, int n)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct proc *pr = myproc();
|
struct proc *pr = myproc();
|
||||||
char ch;
|
char ch;
|
||||||
|
|
||||||
acquire(&p->lock);
|
acquire(&pi->lock);
|
||||||
while(p->nread == p->nwrite && p->writeopen){ //DOC: pipe-empty
|
while(pi->nread == pi->nwrite && pi->writeopen){ //DOC: pipe-empty
|
||||||
if(myproc()->killed){
|
if(myproc()->killed){
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
return -1;
|
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
|
for(i = 0; i < n; i++){ //DOC: piperead-copy
|
||||||
if(p->nread == p->nwrite)
|
if(pi->nread == pi->nwrite)
|
||||||
break;
|
break;
|
||||||
ch = p->data[p->nread++ % PIPESIZE];
|
ch = pi->data[pi->nread++ % PIPESIZE];
|
||||||
if(copyout(pr->pagetable, addr + i, &ch, 1) == -1)
|
if(copyout(pr->pagetable, addr + i, &ch, 1) == -1)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
wakeup(&p->nwrite); //DOC: piperead-wakeup
|
wakeup(&pi->nwrite); //DOC: piperead-wakeup
|
||||||
release(&p->lock);
|
release(&pi->lock);
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,12 +510,6 @@ sleep(void *chan, struct spinlock *lk)
|
||||||
{
|
{
|
||||||
struct proc *p = myproc();
|
struct proc *p = myproc();
|
||||||
|
|
||||||
if(p == 0)
|
|
||||||
panic("sleep");
|
|
||||||
|
|
||||||
if(lk == 0)
|
|
||||||
panic("sleep without lk");
|
|
||||||
|
|
||||||
// Must acquire p->lock in order to
|
// Must acquire p->lock in order to
|
||||||
// change p->state and then call sched.
|
// change p->state and then call sched.
|
||||||
// Once we hold p->lock, we can be
|
// 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.
|
// Wake up all processes sleeping on chan.
|
||||||
// Must be called without any p->lock.
|
// Must be called without any p->lock.
|
||||||
void
|
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.
|
// Kill the process with the given pid.
|
||||||
// The victim won't exit until it tries to return
|
// The victim won't exit until it tries to return
|
||||||
// to user space (see usertrap() in trap.c).
|
// to user space (see usertrap() in trap.c).
|
||||||
|
|
Loading…
Reference in a new issue