static void pass1(int pass, volatile Diag *dp) { int i; if(m->machno == 0) iprint(" %d", pass); for (i = 1000*1000; --i > 0; ) { ainc(&dp->cnt); adec(&dp->cnt); } synccpus(&dp->sync, navailcpus); /* all cpus are now here */ ilock(dp); if(dp->cnt != 0) panic("cpu%d: diag: failed w count %ld", m->machno, dp->cnt); iunlock(dp); synccpus(&dp->sync, 2 * navailcpus); /* all cpus are now here */ adec(&dp->sync); adec(&dp->sync); }
void unlock(Lock *l) { Proc *up = externup(); uint64_t x; if(LOCKCYCLES){ cycles(&x); l->lockcycles = x - l->lockcycles; if(l->lockcycles > maxlockcycles){ maxlockcycles = l->lockcycles; maxlockpc = l->_pc; } } if(l->key == 0) print("unlock: not locked: pc %#p\n", getcallerpc()); if(l->isilock) print("unlock of ilock: pc %#p, held by %#p\n", getcallerpc(), l->_pc); if(l->p != up) print("unlock: up changed: pc %#p, acquired at pc %#p, lock p %#p, unlock up %#p\n", getcallerpc(), l->_pc, l->p, up); l->m = nil; l->key = 0; coherence(); if(up && adec(&up->nlocks) == 0 && up->delaysched && islo()){ /* * Call sched if the need arose while locks were held * But, don't do it from interrupt routines, hence the islo() test */ sched(); } }
void unlock(Lock *l) { if(adec(&l->key) == 0) return; /* changed from 1 -> 0: no contention */ semrelease(&l->sem, 1); }
void Collision::RenderTree(){ static let path = "C:\\Users\\master8\\Documents\\Visual Studio 2013\\Projects\\assimptest\\assimptest\\result"; if (verts){ let len = verts->size(); for (size_t i = 0; i < len; i+=6) { let el = verts[i]; //初めの3要素は座標、後ろがextent glTranslatef(adec(el,0)); glScalef (adec(el,3)); glutWireCube(1); } } else{ verts = &readResult("C:\\"); RenderTree(); } }
int canlock(Lock *l) { if(ainc(&l->key) == 1) return 1; /* changed from 0 -> 1: success */ /* Undo increment (but don't miss wakeup) */ if(adec(&l->key) == 0) return 0; /* changed from 1 -> 0: no contention */ semrelease(&l->sem, 1); return 0; }
int canlock(Lock *l) { Proc *up = externup(); if(up) ainc(&up->nlocks); if(TAS(&l->key)){ if(up) adec(&up->nlocks); return 0; } if(up) up->lastlock = l; l->_pc = getcallerpc(); l->p = up; l->isilock = 0; if(LOCKCYCLES) cycles(&l->lockcycles); return 1; }
static void shutdown(int ispanic) { Mach *m = machp(); int ms, once; lock(&active); if(ispanic) active.ispanic = ispanic; else if(m->machno == 0 && m->online == 0) active.ispanic = 0; once = m->online; m->online = 0; adec(&active.nonline); active.exiting = 1; unlock(&active); if(once) iprint("cpu%d: exiting\n", m->machno); spllo(); for(ms = 5*1000; ms > 0; ms -= TK2MS(2)){ delay(TK2MS(2)); if(active.nonline == 0) break; } if(active.ispanic && m->machno == 0){ if(cpuserver) delay(30000); else for(;;) halt(); } else delay(1000); }
void squidboy(int apicno) { char *n[] = { [NIXAC] "AC", [NIXTC] "TC", [NIXKC] "KC" }; vlong hz; sys->machptr[m->machno] = m; setmachsched(m); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; m->perf.period = 1; m->nixtype = NIXAC; DBG("Hello Squidboy %d %d\n", apicno, m->machno); vsvminit(MACHSTKSZ, m->nixtype); /* * Beware the Curse of The Non-Interruptable Were-Temporary. */ hz = archhz(); if(hz == 0) ndnr(); m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; mmuinit(); if(!apiconline()) ndnr(); fpuinit(); acmodeset(m->nixtype); m->splpc = 0; m->online = 1; /* * CAUTION: no time sync done, etc. */ DBG("Wait for the thunderbirds!\n"); while(!active.thunderbirdsarego) ; wrmsr(0x10, sys->epoch); m->rdtsc = rdtsc(); print("cpu%d color %d role %s tsc %lld\n", m->machno, corecolor(m->machno), n[m->nixtype], m->rdtsc); switch(m->nixtype){ case NIXAC: acmmuswitch(); acinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ acsched(); panic("squidboy"); break; case NIXTC: /* * We only need the idt and syscall entry point actually. * At boot time the boot processor might set our role after * we have decided to become an AC. */ vsvminit(MACHSTKSZ, NIXTC); /* * Enable the timer interrupt. */ apicpri(0); timersinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ schedinit(); break; } panic("squidboy returns (type %d)", m->nixtype); }
int lock(Lock *l) { Proc *up = externup(); int i; uintptr_t pc; uint64_t t0; pc = getcallerpc(); lockstats.locks++; if(up) ainc(&up->nlocks); /* prevent being scheded */ if(TAS(&l->key) == 0){ if(up) up->lastlock = l; l->_pc = pc; l->p = up; l->isilock = 0; if(LOCKCYCLES) cycles(&l->lockcycles); return 0; } if(up) adec(&up->nlocks); cycles(&t0); lockstats.glare++; for(;;){ lockstats.inglare++; i = 0; while(l->key){ if(sys->nmach < 2 && up && up->edf && (up->edf->flags & Admitted)){ /* * Priority inversion, yield on a uniprocessor; on a * multiprocessor, the other processor will unlock */ print("inversion %#p pc %#p proc %d held by pc %#p proc %d\n", l, pc, up ? up->pid : 0, l->_pc, l->p ? l->p->pid : 0); up->edf->d = todget(nil); /* yield to process with lock */ } if(i++ > 100000000){ i = 0; lockloop(l, pc); } } if(up) ainc(&up->nlocks); if(TAS(&l->key) == 0){ if(up) up->lastlock = l; l->_pc = pc; l->p = up; l->isilock = 0; if(LOCKCYCLES) cycles(&l->lockcycles); if(l != &waitstatslk) addwaitstat(pc, t0, WSlock); return 1; } if(up) adec(&up->nlocks); } }
/* * try to confirm coherence of l1 caches. * assume that all available cpus will be started. */ void l1diag(void) { int pass; volatile Diag *dp; if (!Debug) return; l1cache->wb(); /* * synchronise and print */ dp = &diag; ilock(dp); if (m->machno == 0) iprint("l1: waiting for %d cpus... ", navailcpus); iunlock(dp); synccpus(&dp->sync, navailcpus); ilock(dp); if (m->machno == 0) iprint("cache coherency pass"); iunlock(dp); synccpus(&dp->sync, 2 * navailcpus); adec(&dp->sync); adec(&dp->sync); /* * cpus contend */ for (pass = 0; pass < 3; pass++) pass1(pass, dp); /* * synchronise and check sanity */ synccpus(&dp->sync, navailcpus); if(dp->sync < navailcpus || dp->sync >= 2 * navailcpus) panic("cpu%d: diag: failed w dp->sync %ld", m->machno, dp->sync); if(dp->cnt != 0) panic("cpu%d: diag: failed w dp->cnt %ld", m->machno, dp->cnt); ilock(dp); iprint(" cpu%d ok", m->machno); iunlock(dp); synccpus(&dp->sync, 2 * navailcpus); adec(&dp->sync); adec(&dp->sync); l1cache->wb(); /* * all done, print */ ilock(dp); if (m->machno == 0) iprint("\n"); iunlock(dp); }
long decref(Ref *r) { return adec(&r->ref); }
void squidboy(int apicno, Mach *m) { // FIX QEMU. extern int64_t hz; int64_t hz; sys->machptr[m->machno] = m; /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; m->perf.period = 1; m->nixtype = NIXAC; // no NIXAC for now. m->nixtype = NIXTC; // NOTE: you can't do ANYTHING here before vsvminit. // PRINT WILL PANIC. So wait. vsvminit(MACHSTKSZ, m->nixtype, m); //DBG("Hello squidboy %d %d\n", apicno, m->machno); /* * Beware the Curse of The Non-Interruptable Were-Temporary. */ hz = archhz(); /* Intel cpu's in archk10 must be reviewed */ if(hz == 0) hz = 2000000000ll; m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; mmuinit(); if(!apiconline()) ndnr(); fpuinit(); acmodeset(m->nixtype); m->splpc = 0; m->online = 1; /* * CAUTION: no time sync done, etc. * Stupid print to avoid up = nil or * last cpu couldn't start in nixquids. */ DBG("Wait for the thunderbirds!\n"); while(!active.thunderbirdsarego) ; wrmsr(0x10, sys->epoch); m->rdtsc = rdtsc(); print("cpu%d color %d role %s tsc %lld\n", m->machno, corecolor(m->machno), rolename[m->nixtype], m->rdtsc); switch(m->nixtype){ case NIXAC: acmmuswitch(); acinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ acsched(); panic("squidboy"); break; case NIXTC: /* * We only need the idt and syscall entry point actually. * At boot time the boot processor might set our role after * we have decided to become an AC. */ vsvminit(MACHSTKSZ, NIXTC, m); /* * Enable the timer interrupt. */ apictimerenab(); apicpri(0); timersinit(); adec(&active.nbooting); ainc(&active.nonline); /* Ready? steady? going to timer */ ndnr(); schedinit(); break; } panic("squidboy returns (type %d)", m->nixtype); }