diff --git a/Notes b/Notes index 8fab37d..b5f4035 100644 --- a/Notes +++ b/Notes @@ -114,26 +114,15 @@ wakeup needs proc_table_lock so we need recursive locks? 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 public variables of table elements 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 -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... -ide_init doesn't work now? -and IOAPIC: read from unsupported address - when running pre-empt user test - so maybe something wrong with clock interrupts - no! if one cpu holds lock w/ curproc0=, - then another cpu can take it, it looks like - a recursive acquire() + +nasty hack to allow locks before first process, + and to allow them in interrupts when curproc may be zero + +race between release and sleep in sys_wait() +race between sys_exit waking up parent and setting state=ZOMBIE diff --git a/proc.c b/proc.c index 53469a1..0e35540 100644 --- a/proc.c +++ b/proc.c @@ -181,7 +181,9 @@ swtch(int newstate) { struct proc *p = curproc[cpu()]; 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() if(setjmp(&p->jmpbuf) == 0) longjmp(&cpus[cpu()].jmpbuf); @@ -203,9 +205,11 @@ wakeup(void *chan) struct proc *p; acquire(&proc_table_lock); - for(p = proc; p < &proc[NPROC]; p++) - if(p->state == WAITING && p->chan == chan) + for(p = proc; p < &proc[NPROC]; p++){ + if(p->state == WAITING && p->chan == chan){ p->state = RUNNABLE; + } + } release(&proc_table_lock); } @@ -225,7 +229,7 @@ proc_exit() struct proc *cp = curproc[cpu()]; 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++){ if(cp->fds[fd]){ @@ -246,7 +250,7 @@ proc_exit() if(p->ppid == cp->pid) p->pid = 1; - acquire(&proc_table_lock); + release(&proc_table_lock); // switch into scheduler swtch(ZOMBIE); @@ -265,10 +269,8 @@ cli(void) void sti(void) { - if(cpus[cpu()].clis < 1){ - cprintf("cpu %d clis %d\n", cpu(), cpus[cpu()].clis); + if(cpus[cpu()].clis < 1) panic("sti"); - } cpus[cpu()].clis -= 1; if(cpus[cpu()].clis < 1) __asm __volatile("sti"); diff --git a/proc.h b/proc.h index 4c5807b..e13df41 100644 --- a/proc.h +++ b/proc.h @@ -45,6 +45,7 @@ struct proc{ int ppid; void *chan; // sleep int killed; + int locks; // # of locks currently held struct fd *fds[NOFILE]; struct Taskstate ts; // only to give cpu address of kernel stack diff --git a/spinlock.c b/spinlock.c index bd6bff5..507e74b 100644 --- a/spinlock.c +++ b/spinlock.c @@ -17,10 +17,11 @@ int getcallerpc(void *v) { void acquire(struct spinlock * lock) { + struct proc *cp = curproc[cpu()]; unsigned who; - if(curproc[cpu()]) - who = (unsigned) curproc[cpu()]; + if(cp) + who = (unsigned) cp; else who = cpu() + 1; @@ -38,16 +39,20 @@ acquire(struct spinlock * lock) lock->who = who; } + if(cp) + cp->locks += 1; + if(DEBUG) cprintf("cpu%d: acquired at %x\n", cpu(), getcallerpc(&lock)); } void release(struct spinlock * lock) { + struct proc *cp = curproc[cpu()]; unsigned who; - if(curproc[cpu()]) - who = (unsigned) curproc[cpu()]; + if(cp) + who = (unsigned) cp; else who = cpu() + 1; @@ -57,6 +62,8 @@ release(struct spinlock * lock) panic("release"); lock->count -= 1; + if(cp) + cp->locks -= 1; if(lock->count < 1){ lock->who = 0; cmpxchg(1, 0, &lock->locked); diff --git a/trap.c b/trap.c index 862225b..6f5409b 100644 --- a/trap.c +++ b/trap.c @@ -62,6 +62,9 @@ trap(struct Trapframe *tf) struct proc *cp = curproc[cpu()]; lapic_timerintr(); if(cp){ + if(cpus[cpu()].clis != 0) + panic("trap clis > 0"); + cpus[cpu()].clis += 1; sti(); if(cp->killed) proc_exit(); @@ -69,6 +72,7 @@ trap(struct Trapframe *tf) } return; } + if(v == (IRQ_OFFSET + IRQ_IDE)){ ide_intr(); return; diff --git a/usertests.c b/usertests.c index fa1b210..2f688ca 100644 --- a/usertests.c +++ b/usertests.c @@ -93,8 +93,8 @@ preempt() main() { puts("usertests starting\n"); - //pipe1(); - preempt(); + pipe1(); + //preempt(); while(1) ;