From 8b4e2a08febc8b957b44732dbc7da831479a0005 Mon Sep 17 00:00:00 2001 From: rtm Date: Sat, 1 Jul 2006 21:26:01 +0000 Subject: swtch saves callee-saved registers swtch idles on per-CPU stack, not on calling process's stack fix pipe bugs usertest.c tests pipes, fork, exit, close --- proc.c | 44 +++++++++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 17 deletions(-) (limited to 'proc.c') diff --git a/proc.c b/proc.c index 97e84e3..8ad6a23 100644 --- a/proc.c +++ b/proc.c @@ -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; -- cgit v1.2.3