提交 6eb6f10c 创建 作者: rtm's avatar rtm

passes both usertests

exit had acquire where I meant release swtch now checks that you hold no locks
上级 8148b6ee
...@@ -114,26 +114,15 @@ wakeup needs proc_table_lock ...@@ -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()
...@@ -181,7 +181,9 @@ swtch(int newstate) ...@@ -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) ...@@ -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() ...@@ -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() ...@@ -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) ...@@ -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");
......
...@@ -45,6 +45,7 @@ struct proc{ ...@@ -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
......
...@@ -17,10 +17,11 @@ int getcallerpc(void *v) { ...@@ -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) ...@@ -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) ...@@ -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);
......
...@@ -62,6 +62,9 @@ trap(struct Trapframe *tf) ...@@ -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) ...@@ -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() ...@@ -93,8 +93,8 @@ preempt()
main() main()
{ {
puts("usertests starting\n"); puts("usertests starting\n");
//pipe1(); pipe1();
preempt(); //preempt();
while(1) while(1)
; ;
......
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论