Read curproc from cpu structure, but be careful because after a schedule event
myproc() points to a different thread. myproc(); sched(); myproc(); // this proc maybe different than the one before sched Thus, in a function that operates on one thread better to retrieve the current process once at the start of the function.
This commit is contained in:
		
							parent
							
								
									abf847a083
								
							
						
					
					
						commit
						fbb4c09444
					
				
					 7 changed files with 97 additions and 62 deletions
				
			
		
							
								
								
									
										1
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								defs.h
									
										
									
									
									
								
							|  | @ -108,6 +108,7 @@ void            exit(void); | |||
| int             fork(void); | ||||
| int             growproc(int); | ||||
| int             kill(int); | ||||
| struct proc*    myproc(); | ||||
| void            pinit(void); | ||||
| void            procdump(void); | ||||
| void            scheduler(void) __attribute__((noreturn)); | ||||
|  |  | |||
							
								
								
									
										15
									
								
								exec.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								exec.c
									
										
									
									
									
								
							|  | @ -17,6 +17,7 @@ exec(char *path, char **argv) | |||
|   struct inode *ip; | ||||
|   struct proghdr ph; | ||||
|   pde_t *pgdir, *oldpgdir; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   begin_op(); | ||||
| 
 | ||||
|  | @ -90,15 +91,15 @@ exec(char *path, char **argv) | |||
|   for(last=s=path; *s; s++) | ||||
|     if(*s == '/') | ||||
|       last = s+1; | ||||
|   safestrcpy(myproc()->name, last, sizeof(myproc()->name)); | ||||
|   safestrcpy(curproc->name, last, sizeof(curproc->name)); | ||||
| 
 | ||||
|   // Commit to the user image.
 | ||||
|   oldpgdir = myproc()->pgdir; | ||||
|   myproc()->pgdir = pgdir; | ||||
|   myproc()->sz = sz; | ||||
|   myproc()->tf->eip = elf.entry;  // main
 | ||||
|   myproc()->tf->esp = sp; | ||||
|   switchuvm(myproc()); | ||||
|   oldpgdir = curproc->pgdir; | ||||
|   curproc->pgdir = pgdir; | ||||
|   curproc->sz = sz; | ||||
|   curproc->tf->eip = elf.entry;  // main
 | ||||
|   curproc->tf->esp = sp; | ||||
|   switchuvm(curproc); | ||||
|   freevm(oldpgdir); | ||||
|   return 0; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										101
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										101
									
								
								proc.c
									
										
									
									
									
								
							|  | @ -26,14 +26,23 @@ pinit(void) | |||
|   initlock(&ptable.lock, "ptable"); | ||||
| } | ||||
| 
 | ||||
| // XXX get rid off?
 | ||||
| int | ||||
| cpuid() { | ||||
|   return mycpu()-cpus; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| setproc(struct proc* p) { | ||||
|   mycpu()->proc = p; | ||||
| // Disable interrupts so that we are not rescheduled
 | ||||
| // while reading proc from the cpu structure
 | ||||
| struct proc* | ||||
| myproc(void) { | ||||
|   struct cpu *c; | ||||
|   struct proc *p; | ||||
|   pushcli(); | ||||
|   c = mycpu(); | ||||
|   p = c->proc; | ||||
|   popcli(); | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
| //PAGEBREAK: 32
 | ||||
|  | @ -130,17 +139,18 @@ int | |||
| growproc(int n) | ||||
| { | ||||
|   uint sz; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   sz = myproc()->sz; | ||||
|   sz = curproc->sz; | ||||
|   if(n > 0){ | ||||
|     if((sz = allocuvm(myproc()->pgdir, sz, sz + n)) == 0) | ||||
|     if((sz = allocuvm(curproc->pgdir, sz, sz + n)) == 0) | ||||
|       return -1; | ||||
|   } else if(n < 0){ | ||||
|     if((sz = deallocuvm(myproc()->pgdir, sz, sz + n)) == 0) | ||||
|     if((sz = deallocuvm(curproc->pgdir, sz, sz + n)) == 0) | ||||
|       return -1; | ||||
|   } | ||||
|   myproc()->sz = sz; | ||||
|   switchuvm(myproc()); | ||||
|   curproc->sz = sz; | ||||
|   switchuvm(curproc); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -152,6 +162,7 @@ fork(void) | |||
| { | ||||
|   int i, pid; | ||||
|   struct proc *np; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   // Allocate process.
 | ||||
|   if((np = allocproc()) == 0){ | ||||
|  | @ -159,25 +170,25 @@ fork(void) | |||
|   } | ||||
| 
 | ||||
|   // Copy process state from proc.
 | ||||
|   if((np->pgdir = copyuvm(myproc()->pgdir, myproc()->sz)) == 0){ | ||||
|   if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){ | ||||
|     kfree(np->kstack); | ||||
|     np->kstack = 0; | ||||
|     np->state = UNUSED; | ||||
|     return -1; | ||||
|   } | ||||
|   np->sz = myproc()->sz; | ||||
|   np->parent = myproc(); | ||||
|   *np->tf = *myproc()->tf; | ||||
|   np->sz = curproc->sz; | ||||
|   np->parent = curproc; | ||||
|   *np->tf = *curproc->tf; | ||||
| 
 | ||||
|   // Clear %eax so that fork returns 0 in the child.
 | ||||
|   np->tf->eax = 0; | ||||
| 
 | ||||
|   for(i = 0; i < NOFILE; i++) | ||||
|     if(myproc()->ofile[i]) | ||||
|       np->ofile[i] = filedup(myproc()->ofile[i]); | ||||
|   np->cwd = idup(myproc()->cwd); | ||||
|     if(curproc->ofile[i]) | ||||
|       np->ofile[i] = filedup(curproc->ofile[i]); | ||||
|   np->cwd = idup(curproc->cwd); | ||||
| 
 | ||||
|   safestrcpy(np->name, myproc()->name, sizeof(myproc()->name)); | ||||
|   safestrcpy(np->name, curproc->name, sizeof(curproc->name)); | ||||
| 
 | ||||
|   pid = np->pid; | ||||
| 
 | ||||
|  | @ -196,33 +207,34 @@ fork(void) | |||
| void | ||||
| exit(void) | ||||
| { | ||||
|   struct proc *curproc = myproc(); | ||||
|   struct proc *p; | ||||
|   int fd; | ||||
| 
 | ||||
|   if(myproc() == initproc) | ||||
|   if(curproc == initproc) | ||||
|     panic("init exiting"); | ||||
| 
 | ||||
|   // Close all open files.
 | ||||
|   for(fd = 0; fd < NOFILE; fd++){ | ||||
|     if(myproc()->ofile[fd]){ | ||||
|       fileclose(myproc()->ofile[fd]); | ||||
|       myproc()->ofile[fd] = 0; | ||||
|     if(curproc->ofile[fd]){ | ||||
|       fileclose(curproc->ofile[fd]); | ||||
|       curproc->ofile[fd] = 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   begin_op(); | ||||
|   iput(myproc()->cwd); | ||||
|   iput(curproc->cwd); | ||||
|   end_op(); | ||||
|   myproc()->cwd = 0; | ||||
|   curproc->cwd = 0; | ||||
| 
 | ||||
|   acquire(&ptable.lock); | ||||
| 
 | ||||
|   // Parent might be sleeping in wait().
 | ||||
|   wakeup1(myproc()->parent); | ||||
|   wakeup1(curproc->parent); | ||||
| 
 | ||||
|   // Pass abandoned children to init.
 | ||||
|   for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ | ||||
|     if(p->parent == myproc()){ | ||||
|     if(p->parent == curproc){ | ||||
|       p->parent = initproc; | ||||
|       if(p->state == ZOMBIE) | ||||
|         wakeup1(initproc); | ||||
|  | @ -230,7 +242,7 @@ exit(void) | |||
|   } | ||||
| 
 | ||||
|   // Jump into the scheduler, never to return.
 | ||||
|   myproc()->state = ZOMBIE; | ||||
|   curproc->state = ZOMBIE; | ||||
|   sched(); | ||||
|   panic("zombie exit"); | ||||
| } | ||||
|  | @ -242,13 +254,14 @@ wait(void) | |||
| { | ||||
|   struct proc *p; | ||||
|   int havekids, pid; | ||||
| 
 | ||||
|   struct proc *curproc = myproc(); | ||||
|    | ||||
|   acquire(&ptable.lock); | ||||
|   for(;;){ | ||||
|     // Scan through table looking for exited children.
 | ||||
|     havekids = 0; | ||||
|     for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ | ||||
|       if(p->parent != myproc()) | ||||
|       if(p->parent != curproc) | ||||
|         continue; | ||||
|       havekids = 1; | ||||
|       if(p->state == ZOMBIE){ | ||||
|  | @ -268,13 +281,13 @@ wait(void) | |||
|     } | ||||
| 
 | ||||
|     // No point waiting if we don't have any children.
 | ||||
|     if(!havekids || myproc()->killed){ | ||||
|     if(!havekids || curproc->killed){ | ||||
|       release(&ptable.lock); | ||||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
|     // Wait for children to exit.  (See wakeup1 call in proc_exit.)
 | ||||
|     sleep(myproc(), &ptable.lock);  //DOC: wait-sleep
 | ||||
|     sleep(curproc, &ptable.lock);  //DOC: wait-sleep
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -290,6 +303,7 @@ void | |||
| scheduler(void) | ||||
| { | ||||
|   struct proc *p; | ||||
|   struct cpu *c = mycpu(); | ||||
| 
 | ||||
|   for(;;){ | ||||
|     // Enable interrupts on this processor.
 | ||||
|  | @ -304,15 +318,18 @@ scheduler(void) | |||
|       // Switch to chosen process.  It is the process's job
 | ||||
|       // to release ptable.lock and then reacquire it
 | ||||
|       // before jumping back to us.
 | ||||
|       setproc(p); | ||||
|       c->proc = p; | ||||
|       switchuvm(p); | ||||
|       p->state = RUNNING; | ||||
|       swtch(&(mycpu()->scheduler), p->context); | ||||
|       p->cpu = c; | ||||
|       // cprintf("%d: switch to %d\n", c-cpus, p->pid);
 | ||||
|       swtch(&(p->cpu->scheduler), p->context); | ||||
|       switchkvm(); | ||||
| 
 | ||||
|       // Process is done running for now.
 | ||||
|       // It should have changed its p->state before coming back.
 | ||||
|       setproc(0); | ||||
|       c->proc = 0; | ||||
|       p->cpu = 0; | ||||
|     } | ||||
|     release(&ptable.lock); | ||||
| 
 | ||||
|  | @ -330,17 +347,20 @@ void | |||
| sched(void) | ||||
| { | ||||
|   int intena; | ||||
|   struct proc *p = myproc(); | ||||
| 
 | ||||
|   if(!holding(&ptable.lock)) | ||||
|     panic("sched ptable.lock"); | ||||
|   if(mycpu()->ncli != 1) | ||||
|     panic("sched locks"); | ||||
|   if(myproc()->state == RUNNING) | ||||
|   if(p->state == RUNNING) | ||||
|     panic("sched running"); | ||||
|   if(readeflags()&FL_IF) | ||||
|     panic("sched interruptible"); | ||||
|   intena = mycpu()->intena; | ||||
|   swtch(&myproc()->context, mycpu()->scheduler); | ||||
|   // cprintf("%d: before swtch %d %x\n", p->cpu-cpus, p->pid, * (int *) 0x1d);
 | ||||
|   swtch(&p->context, p->cpu->scheduler); | ||||
|   // cprintf("%d/%d: after swtch %d %x\n", cpuid(), p->cpu-cpus, p->pid, * (int *) 0x1d);
 | ||||
|   mycpu()->intena = intena; | ||||
| } | ||||
| 
 | ||||
|  | @ -380,7 +400,9 @@ forkret(void) | |||
| void | ||||
| sleep(void *chan, struct spinlock *lk) | ||||
| { | ||||
|   if(myproc() == 0) | ||||
|   struct proc *p = myproc(); | ||||
|    | ||||
|   if(p == 0) | ||||
|     panic("sleep"); | ||||
| 
 | ||||
|   if(lk == 0) | ||||
|  | @ -397,12 +419,15 @@ sleep(void *chan, struct spinlock *lk) | |||
|     release(lk); | ||||
|   } | ||||
|   // Go to sleep.
 | ||||
|   myproc()->chan = chan; | ||||
|   myproc()->state = SLEEPING; | ||||
|   p->chan = chan; | ||||
|   p->state = SLEEPING; | ||||
| 
 | ||||
|   // cprintf("sleep %d\n", p->pid);
 | ||||
|    | ||||
|   sched(); | ||||
| 
 | ||||
|   // Tidy up.
 | ||||
|   myproc()->chan = 0; | ||||
|   p->chan = 0; | ||||
| 
 | ||||
|   // Reacquire original lock.
 | ||||
|   if(lk != &ptable.lock){  //DOC: sleeplock2
 | ||||
|  |  | |||
							
								
								
									
										3
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								proc.h
									
										
									
									
									
								
							|  | @ -30,12 +30,14 @@ mycpu(void) { | |||
|   return cpu; | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| static inline struct proc* | ||||
| myproc(void) { | ||||
|   struct proc *proc; | ||||
|   asm("movl %%gs:4, %0" : "=r"(proc)); | ||||
|   return proc; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| //PAGEBREAK: 17
 | ||||
|  | @ -74,6 +76,7 @@ struct proc { | |||
|   struct file *ofile[NOFILE];  // Open files
 | ||||
|   struct inode *cwd;           // Current directory
 | ||||
|   char name[16];               // Process name (debugging)
 | ||||
|   struct cpu *cpu;             // If running, which cpu.
 | ||||
| }; | ||||
| 
 | ||||
| // Process memory is laid out contiguously, low addresses first:
 | ||||
|  |  | |||
							
								
								
									
										23
									
								
								syscall.c
									
										
									
									
									
								
							
							
						
						
									
										23
									
								
								syscall.c
									
										
									
									
									
								
							|  | @ -17,7 +17,9 @@ | |||
| int | ||||
| fetchint(uint addr, int *ip) | ||||
| { | ||||
|   if(addr >= myproc()->sz || addr+4 > myproc()->sz) | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   if(addr >= curproc->sz || addr+4 > curproc->sz) | ||||
|     return -1; | ||||
|   *ip = *(int*)(addr); | ||||
|   return 0; | ||||
|  | @ -30,11 +32,12 @@ int | |||
| fetchstr(uint addr, char **pp) | ||||
| { | ||||
|   char *s, *ep; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   if(addr >= myproc()->sz) | ||||
|   if(addr >= curproc->sz) | ||||
|     return -1; | ||||
|   *pp = (char*)addr; | ||||
|   ep = (char*)myproc()->sz; | ||||
|   ep = (char*)curproc->sz; | ||||
|   for(s = *pp; s < ep; s++){ | ||||
|     if(*s == 0) | ||||
|       return s - *pp; | ||||
|  | @ -56,10 +59,11 @@ int | |||
| argptr(int n, char **pp, int size) | ||||
| { | ||||
|   int i; | ||||
| 
 | ||||
|   struct proc *curproc = myproc(); | ||||
|   | ||||
|   if(argint(n, &i) < 0) | ||||
|     return -1; | ||||
|   if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz) | ||||
|   if(size < 0 || (uint)i >= curproc->sz || (uint)i+size > curproc->sz) | ||||
|     return -1; | ||||
|   *pp = (char*)i; | ||||
|   return 0; | ||||
|  | @ -128,13 +132,14 @@ void | |||
| syscall(void) | ||||
| { | ||||
|   int num; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   num = myproc()->tf->eax; | ||||
|   num = curproc->tf->eax; | ||||
|   if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { | ||||
|     myproc()->tf->eax = syscalls[num](); | ||||
|     curproc->tf->eax = syscalls[num](); | ||||
|   } else { | ||||
|     cprintf("%d %s: unknown sys call %d\n", | ||||
|             myproc()->pid, myproc()->name, num); | ||||
|     myproc()->tf->eax = -1; | ||||
|             curproc->pid, curproc->name, num); | ||||
|     curproc->tf->eax = -1; | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										12
									
								
								sysfile.c
									
										
									
									
									
								
							
							
						
						
									
										12
									
								
								sysfile.c
									
										
									
									
									
								
							|  | @ -41,10 +41,11 @@ static int | |||
| fdalloc(struct file *f) | ||||
| { | ||||
|   int fd; | ||||
|   struct proc *curproc = myproc(); | ||||
| 
 | ||||
|   for(fd = 0; fd < NOFILE; fd++){ | ||||
|     if(myproc()->ofile[fd] == 0){ | ||||
|       myproc()->ofile[fd] = f; | ||||
|     if(curproc->ofile[fd] == 0){ | ||||
|       curproc->ofile[fd] = f; | ||||
|       return fd; | ||||
|     } | ||||
|   } | ||||
|  | @ -373,7 +374,8 @@ sys_chdir(void) | |||
| { | ||||
|   char *path; | ||||
|   struct inode *ip; | ||||
| 
 | ||||
|   struct proc *curproc = myproc(); | ||||
|    | ||||
|   begin_op(); | ||||
|   if(argstr(0, &path) < 0 || (ip = namei(path)) == 0){ | ||||
|     end_op(); | ||||
|  | @ -386,9 +388,9 @@ sys_chdir(void) | |||
|     return -1; | ||||
|   } | ||||
|   iunlock(ip); | ||||
|   iput(myproc()->cwd); | ||||
|   iput(curproc->cwd); | ||||
|   end_op(); | ||||
|   myproc()->cwd = ip; | ||||
|   curproc->cwd = ip; | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										4
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								vm.c
									
										
									
									
									
								
							|  | @ -27,13 +27,11 @@ seginit(void) | |||
|   c->gdt[SEG_UCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, DPL_USER); | ||||
|   c->gdt[SEG_UDATA] = SEG(STA_W, 0, 0xffffffff, DPL_USER); | ||||
|   c->cpu = c; | ||||
|   c->proc = 0; | ||||
|   // Map cpu and proc -- these are private per cpu.
 | ||||
|   c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 4, 0); | ||||
|   lgdt(c->gdt, sizeof(c->gdt)); | ||||
|   loadgs(SEG_KCPU << 3); | ||||
|   // Initialize cpu-local storage.
 | ||||
|   // setcpu(c);
 | ||||
|   setproc(0); | ||||
| } | ||||
| 
 | ||||
| // Return the address of the PTE in page table pgdir
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Frans Kaashoek
						Frans Kaashoek