Start of an experiment to remove the use of gs for cpu local variables.
This commit is contained in:
		
							parent
							
								
									59cdd6c63b
								
							
						
					
					
						commit
						abf847a083
					
				
					 17 changed files with 145 additions and 123 deletions
				
			
		|  | @ -111,7 +111,7 @@ panic(char *s) | |||
| 
 | ||||
|   cli(); | ||||
|   cons.locking = 0; | ||||
|   cprintf("cpu with apicid %d: panic: ", cpu->apicid); | ||||
|   cprintf("cpu %d: panic: ", cpuid()); | ||||
|   cprintf(s); | ||||
|   cprintf("\n"); | ||||
|   getcallerpcs(&s, pcs); | ||||
|  | @ -242,7 +242,7 @@ consoleread(struct inode *ip, char *dst, int n) | |||
|   acquire(&cons.lock); | ||||
|   while(n > 0){ | ||||
|     while(input.r == input.w){ | ||||
|       if(proc->killed){ | ||||
|       if(myproc()->killed){ | ||||
|         release(&cons.lock); | ||||
|         ilock(ip); | ||||
|         return -1; | ||||
|  |  | |||
							
								
								
									
										4
									
								
								defs.h
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								defs.h
									
										
									
									
									
								
							|  | @ -74,7 +74,7 @@ void            kbdintr(void); | |||
| 
 | ||||
| // lapic.c
 | ||||
| void            cmostime(struct rtcdate *r); | ||||
| int             cpunum(void); | ||||
| int             lapiccpunum(void); | ||||
| extern volatile uint*    lapic; | ||||
| void            lapiceoi(void); | ||||
| void            lapicinit(void); | ||||
|  | @ -103,6 +103,7 @@ int             pipewrite(struct pipe*, char*, int); | |||
| 
 | ||||
| //PAGEBREAK: 16
 | ||||
| // proc.c
 | ||||
| int             cpuid(void); | ||||
| void            exit(void); | ||||
| int             fork(void); | ||||
| int             growproc(int); | ||||
|  | @ -111,6 +112,7 @@ void            pinit(void); | |||
| void            procdump(void); | ||||
| void            scheduler(void) __attribute__((noreturn)); | ||||
| void            sched(void); | ||||
| void            setproc(struct proc*); | ||||
| void            sleep(void*, struct spinlock*); | ||||
| void            userinit(void); | ||||
| int             wait(void); | ||||
|  |  | |||
							
								
								
									
										15
									
								
								exec.c
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								exec.c
									
										
									
									
									
								
							|  | @ -22,6 +22,7 @@ exec(char *path, char **argv) | |||
| 
 | ||||
|   if((ip = namei(path)) == 0){ | ||||
|     end_op(); | ||||
|     cprintf("exec: fail\n"); | ||||
|     return -1; | ||||
|   } | ||||
|   ilock(ip); | ||||
|  | @ -89,15 +90,15 @@ exec(char *path, char **argv) | |||
|   for(last=s=path; *s; s++) | ||||
|     if(*s == '/') | ||||
|       last = s+1; | ||||
|   safestrcpy(proc->name, last, sizeof(proc->name)); | ||||
|   safestrcpy(myproc()->name, last, sizeof(myproc()->name)); | ||||
| 
 | ||||
|   // Commit to the user image.
 | ||||
|   oldpgdir = proc->pgdir; | ||||
|   proc->pgdir = pgdir; | ||||
|   proc->sz = sz; | ||||
|   proc->tf->eip = elf.entry;  // main
 | ||||
|   proc->tf->esp = sp; | ||||
|   switchuvm(proc); | ||||
|   oldpgdir = myproc()->pgdir; | ||||
|   myproc()->pgdir = pgdir; | ||||
|   myproc()->sz = sz; | ||||
|   myproc()->tf->eip = elf.entry;  // main
 | ||||
|   myproc()->tf->esp = sp; | ||||
|   switchuvm(myproc()); | ||||
|   freevm(oldpgdir); | ||||
|   return 0; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										4
									
								
								fs.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								fs.c
									
										
									
									
									
								
							|  | @ -169,7 +169,7 @@ iinit(int dev) | |||
|   for(i = 0; i < NINODE; i++) { | ||||
|     initsleeplock(&icache.inode[i].lock, "inode"); | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|   readsb(dev, &sb); | ||||
|   cprintf("sb: size %d nblocks %d ninodes %d nlog %d logstart %d\
 | ||||
|  inodestart %d bmap start %d\n", sb.size, sb.nblocks, | ||||
|  | @ -615,7 +615,7 @@ namex(char *path, int nameiparent, char *name) | |||
|   if(*path == '/') | ||||
|     ip = iget(ROOTDEV, ROOTINO); | ||||
|   else | ||||
|     ip = idup(proc->cwd); | ||||
|     ip = idup(myproc()->cwd); | ||||
| 
 | ||||
|   while((path = skipelem(path, name)) != 0){ | ||||
|     ilock(ip); | ||||
|  |  | |||
							
								
								
									
										3
									
								
								ide.c
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								ide.c
									
										
									
									
									
								
							|  | @ -108,9 +108,9 @@ ideintr(void) | |||
| 
 | ||||
|   // First queued buffer is the active request.
 | ||||
|   acquire(&idelock); | ||||
| 
 | ||||
|   if((b = idequeue) == 0){ | ||||
|     release(&idelock); | ||||
|     // cprintf("spurious IDE interrupt\n");
 | ||||
|     return; | ||||
|   } | ||||
|   idequeue = b->qnext; | ||||
|  | @ -164,5 +164,6 @@ iderw(struct buf *b) | |||
|     sleep(b, &idelock); | ||||
|   } | ||||
| 
 | ||||
| 
 | ||||
|   release(&idelock); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										6
									
								
								lapic.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								lapic.c
									
										
									
									
									
								
							|  | @ -99,11 +99,11 @@ lapicinit(void) | |||
| } | ||||
| 
 | ||||
| int | ||||
| cpunum(void) | ||||
| lapiccpunum(void) | ||||
| { | ||||
|   int apicid, i; | ||||
|    | ||||
|   // Cannot call cpu when interrupts are enabled:
 | ||||
|   // Cannot call cpunum when interrupts are enabled:
 | ||||
|   // result not guaranteed to last long enough to be used!
 | ||||
|   // Would prefer to panic but even printing is chancy here:
 | ||||
|   // almost everything, including cprintf and panic, calls cpu,
 | ||||
|  | @ -111,7 +111,7 @@ cpunum(void) | |||
|   if(readeflags()&FL_IF){ | ||||
|     static int n; | ||||
|     if(n++ == 0) | ||||
|       cprintf("cpu called from %x with interrupts enabled\n", | ||||
|       cprintf("cpunum called from %x with interrupts enabled\n", | ||||
|         __builtin_return_address(0)); | ||||
|   } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										9
									
								
								main.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								main.c
									
										
									
									
									
								
							|  | @ -22,7 +22,6 @@ main(void) | |||
|   mpinit();        // detect other processors
 | ||||
|   lapicinit();     // interrupt controller
 | ||||
|   seginit();       // segment descriptors
 | ||||
|   cprintf("\ncpu%d: starting xv6\n\n", cpunum()); | ||||
|   picinit();       // another interrupt controller
 | ||||
|   ioapicinit();    // another interrupt controller
 | ||||
|   consoleinit();   // console hardware
 | ||||
|  | @ -31,7 +30,7 @@ main(void) | |||
|   tvinit();        // trap vectors
 | ||||
|   binit();         // buffer cache
 | ||||
|   fileinit();      // file table
 | ||||
|   ideinit();       // disk
 | ||||
|   ideinit();       // disk 
 | ||||
|   if(!ismp) | ||||
|     timerinit();   // uniprocessor timer
 | ||||
|   startothers();   // start other processors
 | ||||
|  | @ -54,9 +53,9 @@ mpenter(void) | |||
| static void | ||||
| mpmain(void) | ||||
| { | ||||
|   cprintf("cpu%d: starting\n", cpunum()); | ||||
|   cprintf("cpu%d: starting %d\n", cpuid(), lapiccpunum()); | ||||
|   idtinit();       // load idt register
 | ||||
|   xchg(&cpu->started, 1); // tell startothers() we're up
 | ||||
|   xchg(&(mycpu()->started), 1); // tell startothers() we're up
 | ||||
|   scheduler();     // start running processes
 | ||||
| } | ||||
| 
 | ||||
|  | @ -78,7 +77,7 @@ startothers(void) | |||
|   memmove(code, _binary_entryother_start, (uint)_binary_entryother_size); | ||||
| 
 | ||||
|   for(c = cpus; c < cpus+ncpu; c++){ | ||||
|     if(c == cpus+cpunum())  // We've started already.
 | ||||
|     if(c == mycpu())  // We've started already.
 | ||||
|       continue; | ||||
| 
 | ||||
|     // Tell entryother.S what stack to use, where to enter, and what
 | ||||
|  |  | |||
							
								
								
									
										4
									
								
								pipe.c
									
										
									
									
									
								
							
							
						
						
									
										4
									
								
								pipe.c
									
										
									
									
									
								
							|  | @ -83,7 +83,7 @@ pipewrite(struct pipe *p, char *addr, int n) | |||
|   acquire(&p->lock); | ||||
|   for(i = 0; i < n; i++){ | ||||
|     while(p->nwrite == p->nread + PIPESIZE){  //DOC: pipewrite-full
 | ||||
|       if(p->readopen == 0 || proc->killed){ | ||||
|       if(p->readopen == 0 || myproc()->killed){ | ||||
|         release(&p->lock); | ||||
|         return -1; | ||||
|       } | ||||
|  | @ -104,7 +104,7 @@ piperead(struct pipe *p, char *addr, int n) | |||
| 
 | ||||
|   acquire(&p->lock); | ||||
|   while(p->nread == p->nwrite && p->writeopen){  //DOC: pipe-empty
 | ||||
|     if(proc->killed){ | ||||
|     if(myproc()->killed){ | ||||
|       release(&p->lock); | ||||
|       return -1; | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										89
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										89
									
								
								proc.c
									
										
									
									
									
								
							|  | @ -26,6 +26,16 @@ pinit(void) | |||
|   initlock(&ptable.lock, "ptable"); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| cpuid() { | ||||
|   return mycpu()-cpus; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| setproc(struct proc* p) { | ||||
|   mycpu()->proc = p; | ||||
| } | ||||
| 
 | ||||
| //PAGEBREAK: 32
 | ||||
| // Look in the process table for an UNUSED proc.
 | ||||
| // If found, change state to EMBRYO and initialize
 | ||||
|  | @ -121,16 +131,16 @@ growproc(int n) | |||
| { | ||||
|   uint sz; | ||||
| 
 | ||||
|   sz = proc->sz; | ||||
|   sz = myproc()->sz; | ||||
|   if(n > 0){ | ||||
|     if((sz = allocuvm(proc->pgdir, sz, sz + n)) == 0) | ||||
|     if((sz = allocuvm(myproc()->pgdir, sz, sz + n)) == 0) | ||||
|       return -1; | ||||
|   } else if(n < 0){ | ||||
|     if((sz = deallocuvm(proc->pgdir, sz, sz + n)) == 0) | ||||
|     if((sz = deallocuvm(myproc()->pgdir, sz, sz + n)) == 0) | ||||
|       return -1; | ||||
|   } | ||||
|   proc->sz = sz; | ||||
|   switchuvm(proc); | ||||
|   myproc()->sz = sz; | ||||
|   switchuvm(myproc()); | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -148,26 +158,26 @@ fork(void) | |||
|     return -1; | ||||
|   } | ||||
| 
 | ||||
|   // Copy process state from p.
 | ||||
|   if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ | ||||
|   // Copy process state from proc.
 | ||||
|   if((np->pgdir = copyuvm(myproc()->pgdir, myproc()->sz)) == 0){ | ||||
|     kfree(np->kstack); | ||||
|     np->kstack = 0; | ||||
|     np->state = UNUSED; | ||||
|     return -1; | ||||
|   } | ||||
|   np->sz = proc->sz; | ||||
|   np->parent = proc; | ||||
|   *np->tf = *proc->tf; | ||||
|   np->sz = myproc()->sz; | ||||
|   np->parent = myproc(); | ||||
|   *np->tf = *myproc()->tf; | ||||
| 
 | ||||
|   // Clear %eax so that fork returns 0 in the child.
 | ||||
|   np->tf->eax = 0; | ||||
| 
 | ||||
|   for(i = 0; i < NOFILE; i++) | ||||
|     if(proc->ofile[i]) | ||||
|       np->ofile[i] = filedup(proc->ofile[i]); | ||||
|   np->cwd = idup(proc->cwd); | ||||
|     if(myproc()->ofile[i]) | ||||
|       np->ofile[i] = filedup(myproc()->ofile[i]); | ||||
|   np->cwd = idup(myproc()->cwd); | ||||
| 
 | ||||
|   safestrcpy(np->name, proc->name, sizeof(proc->name)); | ||||
|   safestrcpy(np->name, myproc()->name, sizeof(myproc()->name)); | ||||
| 
 | ||||
|   pid = np->pid; | ||||
| 
 | ||||
|  | @ -189,30 +199,30 @@ exit(void) | |||
|   struct proc *p; | ||||
|   int fd; | ||||
| 
 | ||||
|   if(proc == initproc) | ||||
|   if(myproc() == initproc) | ||||
|     panic("init exiting"); | ||||
| 
 | ||||
|   // Close all open files.
 | ||||
|   for(fd = 0; fd < NOFILE; fd++){ | ||||
|     if(proc->ofile[fd]){ | ||||
|       fileclose(proc->ofile[fd]); | ||||
|       proc->ofile[fd] = 0; | ||||
|     if(myproc()->ofile[fd]){ | ||||
|       fileclose(myproc()->ofile[fd]); | ||||
|       myproc()->ofile[fd] = 0; | ||||
|     } | ||||
|   } | ||||
| 
 | ||||
|   begin_op(); | ||||
|   iput(proc->cwd); | ||||
|   iput(myproc()->cwd); | ||||
|   end_op(); | ||||
|   proc->cwd = 0; | ||||
|   myproc()->cwd = 0; | ||||
| 
 | ||||
|   acquire(&ptable.lock); | ||||
| 
 | ||||
|   // Parent might be sleeping in wait().
 | ||||
|   wakeup1(proc->parent); | ||||
|   wakeup1(myproc()->parent); | ||||
| 
 | ||||
|   // Pass abandoned children to init.
 | ||||
|   for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ | ||||
|     if(p->parent == proc){ | ||||
|     if(p->parent == myproc()){ | ||||
|       p->parent = initproc; | ||||
|       if(p->state == ZOMBIE) | ||||
|         wakeup1(initproc); | ||||
|  | @ -220,7 +230,7 @@ exit(void) | |||
|   } | ||||
| 
 | ||||
|   // Jump into the scheduler, never to return.
 | ||||
|   proc->state = ZOMBIE; | ||||
|   myproc()->state = ZOMBIE; | ||||
|   sched(); | ||||
|   panic("zombie exit"); | ||||
| } | ||||
|  | @ -238,7 +248,7 @@ wait(void) | |||
|     // Scan through table looking for exited children.
 | ||||
|     havekids = 0; | ||||
|     for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ | ||||
|       if(p->parent != proc) | ||||
|       if(p->parent != myproc()) | ||||
|         continue; | ||||
|       havekids = 1; | ||||
|       if(p->state == ZOMBIE){ | ||||
|  | @ -258,13 +268,13 @@ wait(void) | |||
|     } | ||||
| 
 | ||||
|     // No point waiting if we don't have any children.
 | ||||
|     if(!havekids || proc->killed){ | ||||
|     if(!havekids || myproc()->killed){ | ||||
|       release(&ptable.lock); | ||||
|       return -1; | ||||
|     } | ||||
| 
 | ||||
|     // Wait for children to exit.  (See wakeup1 call in proc_exit.)
 | ||||
|     sleep(proc, &ptable.lock);  //DOC: wait-sleep
 | ||||
|     sleep(myproc(), &ptable.lock);  //DOC: wait-sleep
 | ||||
|   } | ||||
| } | ||||
| 
 | ||||
|  | @ -294,15 +304,15 @@ 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.
 | ||||
|       proc = p; | ||||
|       setproc(p); | ||||
|       switchuvm(p); | ||||
|       p->state = RUNNING; | ||||
|       swtch(&cpu->scheduler, p->context); | ||||
|       swtch(&(mycpu()->scheduler), p->context); | ||||
|       switchkvm(); | ||||
| 
 | ||||
|       // Process is done running for now.
 | ||||
|       // It should have changed its p->state before coming back.
 | ||||
|       proc = 0; | ||||
|       setproc(0); | ||||
|     } | ||||
|     release(&ptable.lock); | ||||
| 
 | ||||
|  | @ -323,15 +333,15 @@ sched(void) | |||
| 
 | ||||
|   if(!holding(&ptable.lock)) | ||||
|     panic("sched ptable.lock"); | ||||
|   if(cpu->ncli != 1) | ||||
|   if(mycpu()->ncli != 1) | ||||
|     panic("sched locks"); | ||||
|   if(proc->state == RUNNING) | ||||
|   if(myproc()->state == RUNNING) | ||||
|     panic("sched running"); | ||||
|   if(readeflags()&FL_IF) | ||||
|     panic("sched interruptible"); | ||||
|   intena = cpu->intena; | ||||
|   swtch(&proc->context, cpu->scheduler); | ||||
|   cpu->intena = intena; | ||||
|   intena = mycpu()->intena; | ||||
|   swtch(&myproc()->context, mycpu()->scheduler); | ||||
|   mycpu()->intena = intena; | ||||
| } | ||||
| 
 | ||||
| // Give up the CPU for one scheduling round.
 | ||||
|  | @ -339,7 +349,7 @@ void | |||
| yield(void) | ||||
| { | ||||
|   acquire(&ptable.lock);  //DOC: yieldlock
 | ||||
|   proc->state = RUNNABLE; | ||||
|   myproc()->state = RUNNABLE; | ||||
|   sched(); | ||||
|   release(&ptable.lock); | ||||
| } | ||||
|  | @ -370,7 +380,7 @@ forkret(void) | |||
| void | ||||
| sleep(void *chan, struct spinlock *lk) | ||||
| { | ||||
|   if(proc == 0) | ||||
|   if(myproc() == 0) | ||||
|     panic("sleep"); | ||||
| 
 | ||||
|   if(lk == 0) | ||||
|  | @ -386,14 +396,13 @@ sleep(void *chan, struct spinlock *lk) | |||
|     acquire(&ptable.lock);  //DOC: sleeplock1
 | ||||
|     release(lk); | ||||
|   } | ||||
| 
 | ||||
|   // Go to sleep.
 | ||||
|   proc->chan = chan; | ||||
|   proc->state = SLEEPING; | ||||
|   myproc()->chan = chan; | ||||
|   myproc()->state = SLEEPING; | ||||
|   sched(); | ||||
| 
 | ||||
|   // Tidy up.
 | ||||
|   proc->chan = 0; | ||||
|   myproc()->chan = 0; | ||||
| 
 | ||||
|   // Reacquire original lock.
 | ||||
|   if(lk != &ptable.lock){  //DOC: sleeplock2
 | ||||
|  |  | |||
							
								
								
									
										27
									
								
								proc.h
									
										
									
									
									
								
							
							
						
						
									
										27
									
								
								proc.h
									
										
									
									
									
								
							|  | @ -7,25 +7,36 @@ struct cpu { | |||
|   volatile uint started;       // Has the CPU started?
 | ||||
|   int ncli;                    // Depth of pushcli nesting.
 | ||||
|   int intena;                  // Were interrupts enabled before pushcli?
 | ||||
| 
 | ||||
|   // Cpu-local storage variables; see below
 | ||||
|   struct cpu *cpu; | ||||
|   struct proc *proc;           // The currently-running process.
 | ||||
|   // Per-CPU variables, holding pointers to the current cpu and to the current
 | ||||
|   // process (see cpu() and proc() in proc.c)
 | ||||
|   struct cpu *cpu;             // On cpu 0, cpu = &cpus[0]; on cpu 1, cpu=&cpus[1], etc.
 | ||||
|   struct proc *proc;           // The currently-running process on this cpu
 | ||||
| }; | ||||
| 
 | ||||
| extern struct cpu cpus[NCPU]; | ||||
| extern int ncpu; | ||||
| 
 | ||||
| // Per-CPU variables, holding pointers to the
 | ||||
| // current cpu and to the current process.
 | ||||
| // The asm suffix tells gcc to use "%gs:0" to refer to cpu
 | ||||
| // and "%gs:4" to refer to proc.  seginit sets up the
 | ||||
| // %gs segment register so that %gs refers to the memory
 | ||||
| // holding those two variables in the local cpu's struct cpu.
 | ||||
| // This is similar to how thread-local variables are implemented
 | ||||
| // in thread libraries such as Linux pthreads.
 | ||||
| extern struct cpu *cpu asm("%gs:0");       // &cpus[cpunum()]
 | ||||
| extern struct proc *proc asm("%gs:4");     // cpus[cpunum()].proc
 | ||||
| 
 | ||||
| static inline struct cpu* | ||||
| mycpu(void) { | ||||
|   struct cpu *cpu; | ||||
|   asm("movl %%gs:0, %0" : "=r"(cpu)); | ||||
|   return cpu; | ||||
| } | ||||
| 
 | ||||
| static inline struct proc* | ||||
| myproc(void) { | ||||
|   struct proc *proc; | ||||
|   asm("movl %%gs:4, %0" : "=r"(proc)); | ||||
|   return proc; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //PAGEBREAK: 17
 | ||||
| // Saved registers for kernel context switches.
 | ||||
|  |  | |||
|  | @ -27,7 +27,7 @@ acquiresleep(struct sleeplock *lk) | |||
|     sleep(lk, &lk->lk); | ||||
|   } | ||||
|   lk->locked = 1; | ||||
|   lk->pid = proc->pid; | ||||
|   lk->pid = myproc()->pid; | ||||
|   release(&lk->lk); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								spinlock.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								spinlock.c
									
										
									
									
									
								
							|  | @ -38,7 +38,7 @@ acquire(struct spinlock *lk) | |||
|   __sync_synchronize(); | ||||
| 
 | ||||
|   // Record info about lock acquisition for debugging.
 | ||||
|   lk->cpu = cpu; | ||||
|   lk->cpu = mycpu(); | ||||
|   getcallerpcs(&lk, lk->pcs); | ||||
| } | ||||
| 
 | ||||
|  | @ -89,7 +89,7 @@ getcallerpcs(void *v, uint pcs[]) | |||
| int | ||||
| holding(struct spinlock *lock) | ||||
| { | ||||
|   return lock->locked && lock->cpu == cpu; | ||||
|   return lock->locked && lock->cpu == mycpu(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -104,9 +104,9 @@ pushcli(void) | |||
| 
 | ||||
|   eflags = readeflags(); | ||||
|   cli(); | ||||
|   if(cpu->ncli == 0) | ||||
|     cpu->intena = eflags & FL_IF; | ||||
|   cpu->ncli += 1; | ||||
|   if(mycpu()->ncli == 0) | ||||
|     mycpu()->intena = eflags & FL_IF; | ||||
|   mycpu()->ncli += 1; | ||||
| } | ||||
| 
 | ||||
| void | ||||
|  | @ -114,9 +114,9 @@ popcli(void) | |||
| { | ||||
|   if(readeflags()&FL_IF) | ||||
|     panic("popcli - interruptible"); | ||||
|   if(--cpu->ncli < 0) | ||||
|   if(--mycpu()->ncli < 0) | ||||
|     panic("popcli"); | ||||
|   if(cpu->ncli == 0 && cpu->intena) | ||||
|   if(mycpu()->ncli == 0 && mycpu()->intena) | ||||
|     sti(); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										21
									
								
								syscall.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								syscall.c
									
										
									
									
									
								
							|  | @ -17,7 +17,7 @@ | |||
| int | ||||
| fetchint(uint addr, int *ip) | ||||
| { | ||||
|   if(addr >= proc->sz || addr+4 > proc->sz) | ||||
|   if(addr >= myproc()->sz || addr+4 > myproc()->sz) | ||||
|     return -1; | ||||
|   *ip = *(int*)(addr); | ||||
|   return 0; | ||||
|  | @ -31,13 +31,14 @@ fetchstr(uint addr, char **pp) | |||
| { | ||||
|   char *s, *ep; | ||||
| 
 | ||||
|   if(addr >= proc->sz) | ||||
|   if(addr >= myproc()->sz) | ||||
|     return -1; | ||||
|   *pp = (char*)addr; | ||||
|   ep = (char*)proc->sz; | ||||
|   for(s = *pp; s < ep; s++) | ||||
|   ep = (char*)myproc()->sz; | ||||
|   for(s = *pp; s < ep; s++){ | ||||
|     if(*s == 0) | ||||
|       return s - *pp; | ||||
|   } | ||||
|   return -1; | ||||
| } | ||||
| 
 | ||||
|  | @ -45,7 +46,7 @@ fetchstr(uint addr, char **pp) | |||
| int | ||||
| argint(int n, int *ip) | ||||
| { | ||||
|   return fetchint(proc->tf->esp + 4 + 4*n, ip); | ||||
|   return fetchint((myproc()->tf->esp) + 4 + 4*n, ip); | ||||
| } | ||||
| 
 | ||||
| // Fetch the nth word-sized system call argument as a pointer
 | ||||
|  | @ -58,7 +59,7 @@ argptr(int n, char **pp, int size) | |||
| 
 | ||||
|   if(argint(n, &i) < 0) | ||||
|     return -1; | ||||
|   if(size < 0 || (uint)i >= proc->sz || (uint)i+size > proc->sz) | ||||
|   if(size < 0 || (uint)i >= myproc()->sz || (uint)i+size > myproc()->sz) | ||||
|     return -1; | ||||
|   *pp = (char*)i; | ||||
|   return 0; | ||||
|  | @ -128,12 +129,12 @@ syscall(void) | |||
| { | ||||
|   int num; | ||||
| 
 | ||||
|   num = proc->tf->eax; | ||||
|   num = myproc()->tf->eax; | ||||
|   if(num > 0 && num < NELEM(syscalls) && syscalls[num]) { | ||||
|     proc->tf->eax = syscalls[num](); | ||||
|     myproc()->tf->eax = syscalls[num](); | ||||
|   } else { | ||||
|     cprintf("%d %s: unknown sys call %d\n", | ||||
|             proc->pid, proc->name, num); | ||||
|     proc->tf->eax = -1; | ||||
|             myproc()->pid, myproc()->name, num); | ||||
|     myproc()->tf->eax = -1; | ||||
|   } | ||||
| } | ||||
|  |  | |||
							
								
								
									
										14
									
								
								sysfile.c
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								sysfile.c
									
										
									
									
									
								
							|  | @ -26,7 +26,7 @@ argfd(int n, int *pfd, struct file **pf) | |||
| 
 | ||||
|   if(argint(n, &fd) < 0) | ||||
|     return -1; | ||||
|   if(fd < 0 || fd >= NOFILE || (f=proc->ofile[fd]) == 0) | ||||
|   if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0) | ||||
|     return -1; | ||||
|   if(pfd) | ||||
|     *pfd = fd; | ||||
|  | @ -43,8 +43,8 @@ fdalloc(struct file *f) | |||
|   int fd; | ||||
| 
 | ||||
|   for(fd = 0; fd < NOFILE; fd++){ | ||||
|     if(proc->ofile[fd] == 0){ | ||||
|       proc->ofile[fd] = f; | ||||
|     if(myproc()->ofile[fd] == 0){ | ||||
|       myproc()->ofile[fd] = f; | ||||
|       return fd; | ||||
|     } | ||||
|   } | ||||
|  | @ -97,7 +97,7 @@ sys_close(void) | |||
| 
 | ||||
|   if(argfd(0, &fd, &f) < 0) | ||||
|     return -1; | ||||
|   proc->ofile[fd] = 0; | ||||
|   myproc()->ofile[fd] = 0; | ||||
|   fileclose(f); | ||||
|   return 0; | ||||
| } | ||||
|  | @ -386,9 +386,9 @@ sys_chdir(void) | |||
|     return -1; | ||||
|   } | ||||
|   iunlock(ip); | ||||
|   iput(proc->cwd); | ||||
|   iput(myproc()->cwd); | ||||
|   end_op(); | ||||
|   proc->cwd = ip; | ||||
|   myproc()->cwd = ip; | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -432,7 +432,7 @@ sys_pipe(void) | |||
|   fd0 = -1; | ||||
|   if((fd0 = fdalloc(rf)) < 0 || (fd1 = fdalloc(wf)) < 0){ | ||||
|     if(fd0 >= 0) | ||||
|       proc->ofile[fd0] = 0; | ||||
|       myproc()->ofile[fd0] = 0; | ||||
|     fileclose(rf); | ||||
|     fileclose(wf); | ||||
|     return -1; | ||||
|  |  | |||
|  | @ -39,7 +39,7 @@ sys_kill(void) | |||
| int | ||||
| sys_getpid(void) | ||||
| { | ||||
|   return proc->pid; | ||||
|   return myproc()->pid; | ||||
| } | ||||
| 
 | ||||
| int | ||||
|  | @ -50,7 +50,7 @@ sys_sbrk(void) | |||
| 
 | ||||
|   if(argint(0, &n) < 0) | ||||
|     return -1; | ||||
|   addr = proc->sz; | ||||
|   addr = myproc()->sz; | ||||
|   if(growproc(n) < 0) | ||||
|     return -1; | ||||
|   return addr; | ||||
|  | @ -67,7 +67,7 @@ sys_sleep(void) | |||
|   acquire(&tickslock); | ||||
|   ticks0 = ticks; | ||||
|   while(ticks - ticks0 < n){ | ||||
|     if(proc->killed){ | ||||
|     if(myproc()->killed){ | ||||
|       release(&tickslock); | ||||
|       return -1; | ||||
|     } | ||||
|  |  | |||
							
								
								
									
										24
									
								
								trap.c
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								trap.c
									
										
									
									
									
								
							|  | @ -37,18 +37,18 @@ void | |||
| trap(struct trapframe *tf) | ||||
| { | ||||
|   if(tf->trapno == T_SYSCALL){ | ||||
|     if(proc->killed) | ||||
|     if(myproc()->killed) | ||||
|       exit(); | ||||
|     proc->tf = tf; | ||||
|     myproc()->tf = tf; | ||||
|     syscall(); | ||||
|     if(proc->killed) | ||||
|     if(myproc()->killed) | ||||
|       exit(); | ||||
|     return; | ||||
|   } | ||||
| 
 | ||||
|   switch(tf->trapno){ | ||||
|   case T_IRQ0 + IRQ_TIMER: | ||||
|     if(cpunum() == 0){ | ||||
|     if(cpuid() == 0){ | ||||
|       acquire(&tickslock); | ||||
|       ticks++; | ||||
|       wakeup(&ticks); | ||||
|  | @ -74,38 +74,38 @@ trap(struct trapframe *tf) | |||
|   case T_IRQ0 + 7: | ||||
|   case T_IRQ0 + IRQ_SPURIOUS: | ||||
|     cprintf("cpu%d: spurious interrupt at %x:%x\n", | ||||
|             cpunum(), tf->cs, tf->eip); | ||||
|             cpuid(), tf->cs, tf->eip); | ||||
|     lapiceoi(); | ||||
|     break; | ||||
| 
 | ||||
|   //PAGEBREAK: 13
 | ||||
|   default: | ||||
|     if(proc == 0 || (tf->cs&3) == 0){ | ||||
|     if(myproc() == 0 || (tf->cs&3) == 0){ | ||||
|       // In kernel, it must be our mistake.
 | ||||
|       cprintf("unexpected trap %d from cpu %d eip %x (cr2=0x%x)\n", | ||||
|               tf->trapno, cpunum(), tf->eip, rcr2()); | ||||
|               tf->trapno, cpuid(), tf->eip, rcr2()); | ||||
|       panic("trap"); | ||||
|     } | ||||
|     // In user space, assume process misbehaved.
 | ||||
|     cprintf("pid %d %s: trap %d err %d on cpu %d " | ||||
|             "eip 0x%x addr 0x%x--kill proc\n", | ||||
|             proc->pid, proc->name, tf->trapno, tf->err, cpunum(), tf->eip, | ||||
|             myproc()->pid, myproc()->name, tf->trapno, tf->err, cpuid(), tf->eip, | ||||
|             rcr2()); | ||||
|     proc->killed = 1; | ||||
|     myproc()->killed = 1; | ||||
|   } | ||||
| 
 | ||||
|   // Force process exit if it has been killed and is in user space.
 | ||||
|   // (If it is still executing in the kernel, let it keep running
 | ||||
|   // until it gets to the regular system call return.)
 | ||||
|   if(proc && proc->killed && (tf->cs&3) == DPL_USER) | ||||
|   if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER) | ||||
|     exit(); | ||||
| 
 | ||||
|   // Force process to give up CPU on clock tick.
 | ||||
|   // If interrupts were on while locks held, would need to check nlock.
 | ||||
|   if(proc && proc->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) | ||||
|   if(myproc() && myproc()->state == RUNNING && tf->trapno == T_IRQ0+IRQ_TIMER) | ||||
|     yield(); | ||||
| 
 | ||||
|   // Check if the process has been killed since we yielded
 | ||||
|   if(proc && proc->killed && (tf->cs&3) == DPL_USER) | ||||
|   if(myproc() && myproc()->killed && (tf->cs&3) == DPL_USER) | ||||
|     exit(); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										22
									
								
								vm.c
									
										
									
									
									
								
							
							
						
						
									
										22
									
								
								vm.c
									
										
									
									
									
								
							|  | @ -21,21 +21,19 @@ seginit(void) | |||
|   // Cannot share a CODE descriptor for both kernel and user
 | ||||
|   // because it would have to have DPL_USR, but the CPU forbids
 | ||||
|   // an interrupt from CPL=0 to DPL=3.
 | ||||
|   c = &cpus[cpunum()]; | ||||
|   c = &cpus[lapiccpunum()]; | ||||
|   c->gdt[SEG_KCODE] = SEG(STA_X|STA_R, 0, 0xffffffff, 0); | ||||
|   c->gdt[SEG_KDATA] = SEG(STA_W, 0, 0xffffffff, 0); | ||||
|   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; | ||||
|   // Map cpu and proc -- these are private per cpu.
 | ||||
|   c->gdt[SEG_KCPU] = SEG(STA_W, &c->cpu, 8, 0); | ||||
| 
 | ||||
|   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.
 | ||||
|   cpu = c; | ||||
|   proc = 0; | ||||
|   // setcpu(c);
 | ||||
|   setproc(0); | ||||
| } | ||||
| 
 | ||||
| // Return the address of the PTE in page table pgdir
 | ||||
|  | @ -171,13 +169,13 @@ switchuvm(struct proc *p) | |||
|     panic("switchuvm: no pgdir"); | ||||
| 
 | ||||
|   pushcli(); | ||||
|   cpu->gdt[SEG_TSS] = SEG16(STS_T32A, &cpu->ts, sizeof(cpu->ts)-1, 0); | ||||
|   cpu->gdt[SEG_TSS].s = 0; | ||||
|   cpu->ts.ss0 = SEG_KDATA << 3; | ||||
|   cpu->ts.esp0 = (uint)p->kstack + KSTACKSIZE; | ||||
|   mycpu()->gdt[SEG_TSS] = SEG16(STS_T32A, &mycpu()->ts, sizeof(mycpu()->ts)-1, 0); | ||||
|   mycpu()->gdt[SEG_TSS].s = 0; | ||||
|   mycpu()->ts.ss0 = SEG_KDATA << 3; | ||||
|   mycpu()->ts.esp0 = (uint)p->kstack + KSTACKSIZE; | ||||
|   // setting IOPL=0 in eflags *and* iomb beyond the tss segment limit
 | ||||
|   // forbids I/O instructions (e.g., inb and outb) from user space
 | ||||
|   cpu->ts.iomb = (ushort) 0xFFFF; | ||||
|   mycpu()->ts.iomb = (ushort) 0xFFFF; | ||||
|   ltr(SEG_TSS << 3); | ||||
|   lcr3(V2P(p->pgdir));  // switch to process's address space
 | ||||
|   popcli(); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Frans Kaashoek
						Frans Kaashoek