passes both usertests
exit had acquire where I meant release swtch now checks that you hold no locks
This commit is contained in:
parent
8148b6ee53
commit
6eb6f10c56
6 changed files with 34 additions and 31 deletions
23
Notes
23
Notes
|
@ -114,26 +114,15 @@ wakeup needs proc_table_lock
|
||||||
so we need recursive locks?
|
so we need recursive locks?
|
||||||
or you must hold the lock to call wakeup?
|
or you must hold the lock to call wakeup?
|
||||||
|
|
||||||
if locks contain proc *, they can't be used at interrupt time
|
|
||||||
only proc_table_lock will be used at interrupt time?
|
|
||||||
maybe it doesn't matter if we use curproc?
|
|
||||||
|
|
||||||
in general, the table locks protect both free-ness and
|
in general, the table locks protect both free-ness and
|
||||||
public variables of table elements
|
public variables of table elements
|
||||||
in many cases you can use table elements w/o a lock
|
in many cases you can use table elements w/o a lock
|
||||||
e.g. if you are the process, or you are using an fd
|
e.g. if you are the process, or you are using an fd
|
||||||
|
|
||||||
why can't i get a lock in console code?
|
|
||||||
always triple fault
|
|
||||||
because release turns on interrupts!
|
|
||||||
a bad idea very early in main()
|
|
||||||
but mp_init() calls cprintf
|
|
||||||
|
|
||||||
lock code shouldn't call cprintf...
|
lock code shouldn't call cprintf...
|
||||||
ide_init doesn't work now?
|
|
||||||
and IOAPIC: read from unsupported address
|
nasty hack to allow locks before first process,
|
||||||
when running pre-empt user test
|
and to allow them in interrupts when curproc may be zero
|
||||||
so maybe something wrong with clock interrupts
|
|
||||||
no! if one cpu holds lock w/ curproc0=,
|
race between release and sleep in sys_wait()
|
||||||
then another cpu can take it, it looks like
|
race between sys_exit waking up parent and setting state=ZOMBIE
|
||||||
a recursive acquire()
|
|
||||||
|
|
18
proc.c
18
proc.c
|
@ -181,7 +181,9 @@ swtch(int newstate)
|
||||||
{
|
{
|
||||||
struct proc *p = curproc[cpu()];
|
struct proc *p = curproc[cpu()];
|
||||||
if(p == 0)
|
if(p == 0)
|
||||||
panic("swtch");
|
panic("swtch no proc");
|
||||||
|
if(p->locks != 0)
|
||||||
|
panic("swtch w/ locks");
|
||||||
p->newstate = newstate; // basically an argument to scheduler()
|
p->newstate = newstate; // basically an argument to scheduler()
|
||||||
if(setjmp(&p->jmpbuf) == 0)
|
if(setjmp(&p->jmpbuf) == 0)
|
||||||
longjmp(&cpus[cpu()].jmpbuf);
|
longjmp(&cpus[cpu()].jmpbuf);
|
||||||
|
@ -203,9 +205,11 @@ wakeup(void *chan)
|
||||||
struct proc *p;
|
struct proc *p;
|
||||||
|
|
||||||
acquire(&proc_table_lock);
|
acquire(&proc_table_lock);
|
||||||
for(p = proc; p < &proc[NPROC]; p++)
|
for(p = proc; p < &proc[NPROC]; p++){
|
||||||
if(p->state == WAITING && p->chan == chan)
|
if(p->state == WAITING && p->chan == chan){
|
||||||
p->state = RUNNABLE;
|
p->state = RUNNABLE;
|
||||||
|
}
|
||||||
|
}
|
||||||
release(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +229,7 @@ proc_exit()
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
cprintf("exit %x\n", cp);
|
cprintf("exit %x pid %d ppid %d\n", cp, cp->pid, cp->ppid);
|
||||||
|
|
||||||
for(fd = 0; fd < NOFILE; fd++){
|
for(fd = 0; fd < NOFILE; fd++){
|
||||||
if(cp->fds[fd]){
|
if(cp->fds[fd]){
|
||||||
|
@ -246,7 +250,7 @@ proc_exit()
|
||||||
if(p->ppid == cp->pid)
|
if(p->ppid == cp->pid)
|
||||||
p->pid = 1;
|
p->pid = 1;
|
||||||
|
|
||||||
acquire(&proc_table_lock);
|
release(&proc_table_lock);
|
||||||
|
|
||||||
// switch into scheduler
|
// switch into scheduler
|
||||||
swtch(ZOMBIE);
|
swtch(ZOMBIE);
|
||||||
|
@ -265,10 +269,8 @@ cli(void)
|
||||||
void
|
void
|
||||||
sti(void)
|
sti(void)
|
||||||
{
|
{
|
||||||
if(cpus[cpu()].clis < 1){
|
if(cpus[cpu()].clis < 1)
|
||||||
cprintf("cpu %d clis %d\n", cpu(), cpus[cpu()].clis);
|
|
||||||
panic("sti");
|
panic("sti");
|
||||||
}
|
|
||||||
cpus[cpu()].clis -= 1;
|
cpus[cpu()].clis -= 1;
|
||||||
if(cpus[cpu()].clis < 1)
|
if(cpus[cpu()].clis < 1)
|
||||||
__asm __volatile("sti");
|
__asm __volatile("sti");
|
||||||
|
|
1
proc.h
1
proc.h
|
@ -45,6 +45,7 @@ struct proc{
|
||||||
int ppid;
|
int ppid;
|
||||||
void *chan; // sleep
|
void *chan; // sleep
|
||||||
int killed;
|
int killed;
|
||||||
|
int locks; // # of locks currently held
|
||||||
struct fd *fds[NOFILE];
|
struct fd *fds[NOFILE];
|
||||||
|
|
||||||
struct Taskstate ts; // only to give cpu address of kernel stack
|
struct Taskstate ts; // only to give cpu address of kernel stack
|
||||||
|
|
15
spinlock.c
15
spinlock.c
|
@ -17,10 +17,11 @@ int getcallerpc(void *v) {
|
||||||
void
|
void
|
||||||
acquire(struct spinlock * lock)
|
acquire(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
|
struct proc *cp = curproc[cpu()];
|
||||||
unsigned who;
|
unsigned who;
|
||||||
|
|
||||||
if(curproc[cpu()])
|
if(cp)
|
||||||
who = (unsigned) curproc[cpu()];
|
who = (unsigned) cp;
|
||||||
else
|
else
|
||||||
who = cpu() + 1;
|
who = cpu() + 1;
|
||||||
|
|
||||||
|
@ -38,16 +39,20 @@ acquire(struct spinlock * lock)
|
||||||
lock->who = who;
|
lock->who = who;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cp)
|
||||||
|
cp->locks += 1;
|
||||||
|
|
||||||
if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
|
if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
release(struct spinlock * lock)
|
release(struct spinlock * lock)
|
||||||
{
|
{
|
||||||
|
struct proc *cp = curproc[cpu()];
|
||||||
unsigned who;
|
unsigned who;
|
||||||
|
|
||||||
if(curproc[cpu()])
|
if(cp)
|
||||||
who = (unsigned) curproc[cpu()];
|
who = (unsigned) cp;
|
||||||
else
|
else
|
||||||
who = cpu() + 1;
|
who = cpu() + 1;
|
||||||
|
|
||||||
|
@ -57,6 +62,8 @@ release(struct spinlock * lock)
|
||||||
panic("release");
|
panic("release");
|
||||||
|
|
||||||
lock->count -= 1;
|
lock->count -= 1;
|
||||||
|
if(cp)
|
||||||
|
cp->locks -= 1;
|
||||||
if(lock->count < 1){
|
if(lock->count < 1){
|
||||||
lock->who = 0;
|
lock->who = 0;
|
||||||
cmpxchg(1, 0, &lock->locked);
|
cmpxchg(1, 0, &lock->locked);
|
||||||
|
|
4
trap.c
4
trap.c
|
@ -62,6 +62,9 @@ trap(struct Trapframe *tf)
|
||||||
struct proc *cp = curproc[cpu()];
|
struct proc *cp = curproc[cpu()];
|
||||||
lapic_timerintr();
|
lapic_timerintr();
|
||||||
if(cp){
|
if(cp){
|
||||||
|
if(cpus[cpu()].clis != 0)
|
||||||
|
panic("trap clis > 0");
|
||||||
|
cpus[cpu()].clis += 1;
|
||||||
sti();
|
sti();
|
||||||
if(cp->killed)
|
if(cp->killed)
|
||||||
proc_exit();
|
proc_exit();
|
||||||
|
@ -69,6 +72,7 @@ trap(struct Trapframe *tf)
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(v == (IRQ_OFFSET + IRQ_IDE)){
|
if(v == (IRQ_OFFSET + IRQ_IDE)){
|
||||||
ide_intr();
|
ide_intr();
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -93,8 +93,8 @@ preempt()
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
puts("usertests starting\n");
|
puts("usertests starting\n");
|
||||||
//pipe1();
|
pipe1();
|
||||||
preempt();
|
//preempt();
|
||||||
|
|
||||||
while(1)
|
while(1)
|
||||||
;
|
;
|
||||||
|
|
Loading…
Reference in a new issue