void CalcTics() { myint newtime; myint ticcount; #ifdef ENABLE_DEMO if (demoplayback || demorecord) ticcount = DEMOTICS - 1; /* [70/4] 17.5 Hz */ else #endif ticcount = 0 + 1; /* 35 Hz */ newtime = sleepuntil(lasttimecount + ticcount); tics = newtime - lasttimecount; lasttimecount = newtime; #ifdef ENABLE_DEMO if (demoplayback || demorecord) tics = DEMOTICS; else #endif if (tics > MAXTICS) tics = MAXTICS; #ifdef LUMINARY /* Start screensaver after 30 seconds. */ if (newtime - LastEventTime > 70 * 30) { VL_ScreenSaver(); } #endif }
void timingwaitframe(struct frametimingstate *state) { state->framecounter++; uint64_t targettime = state->starttime + state->framecounter * state->timeperframe; if(targettime < getcurrenttime() - state->resetthreshold) { // we've overshot and are running too slow, reset timing state->framecounter = 0; state->starttime = getcurrenttime(); } else { // things are going fine, sleep until the target time sleepuntil(targettime, state->slop); } }
static int mklock(char *file) { int fd, try; Dir *dir; fd = openlock(file); if (fd >= 0) { /* make it a lock file if it wasn't */ dir = dirfstat(fd); if (dir == nil) error("%s vanished: %r", file); dir->mode |= DMEXCL; dir->qid.type |= QTEXCL; dirfwstat(fd, dir); free(dir); /* reopen in case it wasn't a lock file at last open */ close(fd); } for (try = 0; try < 65 && (fd = openlock(file)) < 0; try++) sleep(10*1000); return fd; } void main(int argc, char *argv[]) { Job *j; Tm tm; Time t; ulong now, last; /* in seconds */ int i, lock; debug = 0; ARGBEGIN{ case 'c': createuser(); exits(0); case 'd': debug = 1; break; default: usage(); }ARGEND if(debug){ readalljobs(); printjobs(); exits(0); } initcap(); /* do this early, before cpurc removes it */ switch(fork()){ case -1: fatal("can't fork: %r"); case 0: break; default: exits(0); } /* * it can take a few minutes before the file server notices that * we've rebooted and gives up the lock. */ lock = mklock("/cron/lock"); if (lock < 0) fatal("cron already running: %r"); argv0 = "cron"; srand(getpid()*time(0)); last = time(0); for(;;){ readalljobs(); /* * the system's notion of time may have jumped forward or * backward an arbitrary amount since the last call to time(). */ now = time(0); /* * if time has jumped backward, just note it and adapt. * if time has jumped forward more than a day, * just execute one day's jobs. */ if (now < last) { clog("time went backward"); last = now; } else if (now - last > Day) { clog("time advanced more than a day"); last = now - Day; } now = minute(now); for(last = minute(last); last <= now; last += Minute){ tm = *localtime(last); t.min = 1ULL << tm.min; t.hour = 1 << tm.hour; t.wday = 1 << tm.wday; t.mday = 1 << tm.mday; t.mon = 1 << (tm.mon + 1); for(i = 0; i < nuser; i++) for(j = users[i].jobs; j; j = j->next) if(j->time.min & t.min && j->time.hour & t.hour && j->time.wday & t.wday && j->time.mday & t.mday && j->time.mon & t.mon) rexec(&users[i], j); } seek(lock, 0, 0); write(lock, "x", 1); /* keep the lock alive */ /* * if we're not at next minute yet, sleep until a second past * (to allow for sleep intervals being approximate), * which synchronises with minute roll-over as a side-effect. */ sleepuntil(now + Minute + 1); } /* not reached */ }