diff options
| -rw-r--r-- | Notes | 23 | ||||
| -rw-r--r-- | proc.c | 18 | ||||
| -rw-r--r-- | proc.h | 1 | ||||
| -rw-r--r-- | spinlock.c | 15 | ||||
| -rw-r--r-- | trap.c | 4 | ||||
| -rw-r--r-- | usertests.c | 4 | 
6 files changed, 34 insertions, 31 deletions
@@ -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 @@ -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"); @@ -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 @@ -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); @@ -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)      ;  | 
