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? | ||||
|   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 | ||||
|  |  | |||
							
								
								
									
										18
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										18
									
								
								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"); | ||||
|  |  | |||
							
								
								
									
										1
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								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
 | ||||
|  |  | |||
							
								
								
									
										15
									
								
								spinlock.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								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); | ||||
|  |  | |||
							
								
								
									
										4
									
								
								trap.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								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; | ||||
|  |  | |||
|  | @ -93,8 +93,8 @@ preempt() | |||
| main() | ||||
| { | ||||
|   puts("usertests starting\n"); | ||||
|   //pipe1();
 | ||||
|   preempt(); | ||||
|   pipe1(); | ||||
|   //preempt();
 | ||||
| 
 | ||||
|   while(1) | ||||
|     ; | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue