void flushmmu(void) { int s; s = splhi(); up->newtlb = 1; mmuswitch(up); splx(s); }
void flushmmu(void) { int x; x = splhi(); up->newtlb = 1; mmuswitch(up); splx(x); }
void mmuflush(void) { Proc *up = externup(); Mpl pl; pl = splhi(); up->newtlb = 1; mmuswitch(up); splx(pl); }
/* * If changing this routine, look also at sleep(). It * contains a copy of the guts of sched(). */ void sched(void) { Proc *p; if(m->ilockdepth) panic("cpu%d: ilockdepth %d, last lock %#p at %#p, sched called from %#p", m->machno, m->ilockdepth, up != nil ? up->lastilock: nil, (up != nil && up->lastilock != nil) ? up->lastilock->pc: 0, getcallerpc(&p+2)); if(up != nil) { /* * Delay the sched until the process gives up the locks * it is holding. This avoids dumb lock loops. * Don't delay if the process is Moribund. * It called sched to die. * But do sched eventually. This avoids a missing unlock * from hanging the entire kernel. * But don't reschedule procs holding palloc or procalloc. * Those are far too important to be holding while asleep. * * This test is not exact. There can still be a few instructions * in the middle of taslock when a process holds a lock * but Lock.p has not yet been initialized. */ if(up->nlocks) if(up->state != Moribund) if(up->delaysched < 20 || palloc.Lock.p == up || procalloc.Lock.p == up){ up->delaysched++; delayedscheds++; return; } up->delaysched = 0; splhi(); /* statistics */ m->cs++; procsave(up); if(setlabel(&up->sched)){ procrestore(up); spllo(); return; } gotolabel(&m->sched); } p = runproc(); if(p->edf == nil){ updatecpu(p); p->priority = reprioritize(p); } if(p != m->readied) m->schedticks = m->ticks + HZ/10; m->readied = nil; up = p; up->state = Running; up->mach = MACHP(m->machno); m->proc = up; mmuswitch(up); gotolabel(&up->sched); }
/* * If changing this routine, look also at sleep(). It * contains a copy of the guts of sched(). */ void sched(void) { Mach *m = machp(); Proc *p; if(m->ilockdepth) panic("cpu%d: ilockdepth %d, last lock %#p at %#p, sched called from %#p", m->machno, m->ilockdepth, m->externup? m->externup->lastilock: nil, (m->externup && m->externup->lastilock)? m->externup->lastilock->_pc: 0, getcallerpc(&p+2)); kstackok(); if(m->externup){ /* * Delay the sched until the process gives up the locks * it is holding. This avoids dumb lock loops. * Don't delay if the process is Moribund. * It called sched to die. * But do sched eventually. This avoids a missing unlock * from hanging the entire kernel. * But don't reschedule procs holding palloc or procalloc. * Those are far too important to be holding while asleep. * * This test is not exact. There can still be a few * instructions in the middle of taslock when a process * holds a lock but Lock.p has not yet been initialized. */ if(m->externup->nlocks) if(m->externup->state != Moribund) if(m->externup->delaysched < 20 || pga.Lock.p == m->externup || procalloc.Lock.p == m->externup){ m->externup->delaysched++; run.delayedscheds++; return; } m->externup->delaysched = 0; splhi(); /* statistics */ if(m->externup->nqtrap == 0 && m->externup->nqsyscall == 0) m->externup->nfullq++; m->cs++; procsave(m->externup); mmuflushtlb(m->pml4->pa); if(setlabel(&m->externup->sched)){ procrestore(m->externup); spllo(); return; } /*debug*/gotolabel(&m->sched); } m->inidle = 1; p = runproc(); /* core 0 never returns */ m->inidle = 0; if(!p->edf){ updatecpu(p); p->priority = reprioritize(p); } if(nosmp){ if(p != m->readied) m->schedticks = m->ticks + HZ/10; m->readied = 0; } m->externup = p; m->qstart = m->ticks; m->externup->nqtrap = 0; m->externup->nqsyscall = 0; m->externup->state = Running; //m->externup->mach = m; m->externup->mach = sys->machptr[m->machno]; m->proc = m->externup; // iprint("m->externup->sched.sp %p * %p\n", up->sched.sp, // *(void **) m->externup->sched.sp); mmuswitch(m->externup); assert(!m->externup->wired || m->externup->wired == m); if (0) hi("gotolabel\n"); /*debug*/gotolabel(&m->externup->sched); }