diff options
Diffstat (limited to 'proc.c')
-rw-r--r-- | proc.c | 44 |
1 files changed, 27 insertions, 17 deletions
@@ -104,37 +104,47 @@ swtch() { struct proc *np; struct proc *op = curproc[cpu()]; - + unsigned sp; + int i; + + // force push of callee-saved registers + asm volatile("nop" : : : "%edi", "%esi", "%ebx"); + + // save calling process's stack pointers + op->ebp = read_ebp(); + op->esp = read_esp(); + + // don't execute on calling process's stack + sp = (unsigned) cpus[cpu()].mpstack + MPSTACK - 32; + asm volatile("movl %0, %%esp" : : "g" (sp)); + asm volatile("movl %0, %%ebp" : : "g" (sp)); + + // gcc might store op on the stack + np = curproc[cpu()]; + np = np + 1; + while(1){ - np = op + 1; - while(np != op){ + for(i = 0; i < NPROC; i++){ + if(np >= &proc[NPROC]) + np = &proc[0]; if(np->state == RUNNABLE) break; np++; - if(np == &proc[NPROC]) - np = &proc[0]; } - if(np->state == RUNNABLE) + if(i < NPROC) break; - // cprintf("swtch: nothing to run\n"); + // cprintf("swtch %d: nothing to run %d %d\n", + // cpu(), proc[1].state, proc[2].state); release_spinlock(&kernel_lock); acquire_spinlock(&kernel_lock); + np = &proc[0]; } - // XXX this may be too late, should probably save on the way - // in, in case some other CPU decided to run curproc - // before we got here. in fact setting state=WAITING and - // setting these variables had better be atomic w.r.t. other CPUs. - op->ebp = read_ebp(); - op->esp = read_esp(); - - cprintf("cpu %d swtch %x -> %x\n", cpu(), op, np); + cprintf("cpu %d swtch %x -> %x\n", cpu(), curproc[cpu()], np); curproc[cpu()] = np; np->state = RUNNING; - // XXX callee-saved registers? - // h/w sets busy bit in TSS descriptor sometimes, and faults // if it's set in LTR. so clear tss descriptor busy bit. np->gdt[SEG_TSS].sd_type = STS_T32A; |