Annotation of previous_trunk/src/host.c, revision 1.1

1.1     ! root        1: #include "config.h"
        !             2: 
        !             3: #if HAVE_NANOSLEEP
        !             4: #ifdef __MINGW32__
        !             5: #include <unistd.h>
        !             6: #else
        !             7: #include <sys/time.h>
        !             8: #endif
        !             9: #endif
        !            10: #include <errno.h>
        !            11: 
        !            12: #include "host.h"
        !            13: #include "configuration.h"
        !            14: #include "main.h"
        !            15: 
        !            16: /* NeXTdimension blank handling, see nd_sdl.c */
        !            17: void nd_display_blank(int num);
        !            18: void nd_video_blank(int num);
        !            19: 
        !            20: #define NUM_BLANKS 3
        !            21: static const char* BLANKS[] = {
        !            22:   "main","nd_main","nd_video"  
        !            23: };
        !            24: 
        !            25: static volatile Uint32 blank[NUM_BLANKS];
        !            26: static Uint32       vblCounter[NUM_BLANKS];
        !            27: static Uint64       perfCounterStart;
        !            28: static Sint64       cycleCounterStart;
        !            29: static double       cycleSecsStart;
        !            30: static bool         isRealtime;
        !            31: static bool         oldIsRealtime;
        !            32: static double       cycleDivisor;
        !            33: static lock_t       timeLock;
        !            34: static Uint32       ticksStart;
        !            35: static bool         enableRealtime;
        !            36: static Uint64       hardClockExpected;
        !            37: static Uint64       hardClockActual;
        !            38: static time_t       unixTimeStart;
        !            39: static double       unixTimeOffset = 0;
        !            40: static double       perfFrequency;
        !            41: static double       realTimeOffset;
        !            42: static Uint64       pauseTimeStamp;
        !            43: static bool         osDarkmatter;
        !            44: 
        !            45: void host_reset() {
        !            46:     perfCounterStart  = SDL_GetPerformanceCounter();
        !            47:     pauseTimeStamp    = perfCounterStart;
        !            48:     perfFrequency     = SDL_GetPerformanceFrequency();
        !            49:     ticksStart        = SDL_GetTicks();
        !            50:     unixTimeStart     = time(NULL);
        !            51:     cycleCounterStart = 0;
        !            52:     cycleSecsStart    = 0;
        !            53:     isRealtime        = false;
        !            54:     oldIsRealtime     = false;
        !            55:     hardClockExpected = 0;
        !            56:     hardClockActual   = 0;
        !            57:     enableRealtime    = ConfigureParams.System.bRealtime;
        !            58:     realTimeOffset    = 0;
        !            59:     osDarkmatter      = false;
        !            60:     
        !            61:     for(int i = NUM_BLANKS; --i >= 0;) {
        !            62:         vblCounter[i] = 0;
        !            63:         blank[i]      = 0;
        !            64:     }
        !            65:     
        !            66:     cycleDivisor = ConfigureParams.System.nCpuFreq * 1000 * 1000;
        !            67:     
        !            68:     SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH);
        !            69: }
        !            70: 
        !            71: void host_blank(int slot, int src, bool state) {
        !            72:     int bit = 1 << slot;
        !            73:     if(state) {
        !            74:         blank[src] |=  bit;
        !            75:         vblCounter[src]++;
        !            76:     }
        !            77:     else
        !            78:         blank[src] &= ~bit;
        !            79:     switch (src) {
        !            80:         case ND_DISPLAY:   nd_display_blank(slot); break;
        !            81:         case ND_VIDEO:     nd_video_blank(slot);   break;
        !            82:     }
        !            83: }
        !            84: 
        !            85: bool host_blank_state(int slot, int src) {
        !            86:     int bit = 1 << slot;
        !            87:     return blank[src] & bit;
        !            88: }
        !            89: 
        !            90: void host_hardclock(int expected, int actual) {
        !            91:     if(abs(actual-expected) > 1000)
        !            92:         fprintf(stderr, "[Hardclock] expected:%dus actual:%dus\n", expected, actual);
        !            93:     else {
        !            94:         hardClockExpected += expected;
        !            95:         hardClockActual   += actual;
        !            96:     }
        !            97: }
        !            98: 
        !            99: extern Sint64 nCyclesMainCounter;
        !           100: 
        !           101: void host_realtime(bool state) {
        !           102:     isRealtime = state;
        !           103: }
        !           104: 
        !           105: double host_time_sec() {
        !           106:     double rt;
        !           107:     double vt;
        !           108:     host_time(&rt, &vt);
        !           109:     return vt;
        !           110: }
        !           111: 
        !           112: void host_time(double* realTime, double* hostTime) {
        !           113:     host_lock(&timeLock);
        !           114:     
        !           115:     *realTime  = (SDL_GetPerformanceCounter() - perfCounterStart);
        !           116:     *realTime /= perfFrequency;
        !           117:     
        !           118:     if(oldIsRealtime) {
        !           119:         *hostTime = *realTime;
        !           120:     } else {
        !           121:         *hostTime  = nCyclesMainCounter - cycleCounterStart;
        !           122:         *hostTime /= cycleDivisor;
        !           123:         *hostTime += cycleSecsStart;
        !           124:     }
        !           125:     bool state = (isRealtime || osDarkmatter) && enableRealtime;
        !           126:     if(oldIsRealtime != state) {
        !           127:         if(oldIsRealtime) {
        !           128:             // switching from real-time to cycle-time
        !           129:             cycleSecsStart = *realTime;
        !           130:             cycleCounterStart = nCyclesMainCounter;
        !           131:         } else {
        !           132:             // switching from cycle-time to real-time
        !           133:             realTimeOffset = *hostTime - *realTime;
        !           134:             if(realTimeOffset > 0) {
        !           135:                 // if hostTime is in the future, wait until realTime is there as well
        !           136:                 if(realTimeOffset > 0.01)
        !           137:                     host_sleep_sec(realTimeOffset);
        !           138:                 else
        !           139:                     while(*realTime < *hostTime) {
        !           140:                         *realTime  = (SDL_GetPerformanceCounter() - perfCounterStart);
        !           141:                         *realTime /= perfFrequency;
        !           142:                     }
        !           143:             }
        !           144:         }
        !           145:         oldIsRealtime = state;
        !           146:     }
        !           147:     
        !           148:     realTimeOffset = *hostTime - *realTime;
        !           149: 
        !           150:     host_unlock(&timeLock);
        !           151: }
        !           152: 
        !           153: // Return current time as micro seconds
        !           154: Uint64 host_time_us() {
        !           155:     return host_time_sec() * 1000.0 * 1000.0;
        !           156: }
        !           157: 
        !           158: // Return current time as milliseconds
        !           159: Uint32 host_time_ms() {
        !           160:     return  host_time_us() / 1000LL;
        !           161: }
        !           162: 
        !           163: time_t host_unix_time() {
        !           164:     return unixTimeStart + unixTimeOffset + host_time_sec();
        !           165: }
        !           166: 
        !           167: void host_set_unix_time(time_t now) {
        !           168:     unixTimeOffset += difftime(now, host_unix_time());
        !           169: }
        !           170: 
        !           171: double host_real_time_offset() {
        !           172:     host_lock(&timeLock);
        !           173:     double result = realTimeOffset;
        !           174:     host_unlock(&timeLock);
        !           175:     return result;
        !           176: }
        !           177: 
        !           178: void host_pause_time(bool pausing) {
        !           179:     if(pausing) {
        !           180:         pauseTimeStamp = SDL_GetPerformanceCounter();
        !           181:     } else {
        !           182:         perfCounterStart += SDL_GetPerformanceCounter() - pauseTimeStamp;
        !           183:     }
        !           184: }
        !           185: 
        !           186: /*-----------------------------------------------------------------------*/
        !           187: /**
        !           188:  * Sleep for a given number of micro seconds. We burn cycles by running
        !           189:  * the event loop.
        !           190:  */
        !           191: void host_sleep_us(Uint64 us) {
        !           192: #if HAVE_NANOSLEEP
        !           193:     struct timespec    ts;
        !           194:     int                ret;
        !           195:     ts.tv_sec = us / 1000000;
        !           196:     ts.tv_nsec = (us % 1000000) * 1000;        /* micro sec -> nano sec */
        !           197:     /* wait until all the delay is elapsed, including possible interruptions by signals */
        !           198:     do {
        !           199:         errno = 0;
        !           200:         ret = nanosleep(&ts, &ts);
        !           201:     } while ( ret && ( errno == EINTR ) );             /* keep on sleeping if we were interrupted */
        !           202: #else
        !           203:     Uint64 timeout = host_time_us() + us;
        !           204:     host_sleep_ms(( (Uint32)(ticks_micro / 1000) ) ;   /* micro sec -> milli sec */
        !           205:     while(host_time_us() < timeout) {}
        !           206: #endif
        !           207: }
        !           208: 
        !           209: void host_sleep_ms(Uint32 ms) {
        !           210:     Uint64 sleep = ms;
        !           211:     sleep *= 1000;
        !           212:     host_sleep_us(sleep);
        !           213: }
        !           214: 
        !           215: void host_sleep_sec(double sec) {
        !           216:     sec *= 1000 * 1000;
        !           217:     host_sleep_us((Uint64)sec);
        !           218: }
        !           219: 
        !           220: void host_lock(lock_t* lock) {
        !           221:   SDL_AtomicLock(lock);
        !           222: }
        !           223: 
        !           224: int host_trylock(lock_t* lock) {
        !           225:   return SDL_AtomicTryLock(lock);
        !           226: }
        !           227: 
        !           228: void host_unlock(lock_t* lock) {
        !           229:   SDL_AtomicUnlock(lock);
        !           230: }
        !           231: 
        !           232: thread_t* host_thread_create(thread_func_t func, void* data) {
        !           233:   return SDL_CreateThread(func, "Thread", data);
        !           234: }
        !           235: 
        !           236: int host_thread_wait(thread_t* thread) {
        !           237:   int status;
        !           238:   SDL_WaitThread(thread, &status);
        !           239:   return status;
        !           240: }
        !           241:                 
        !           242: int host_num_cpus() {
        !           243:   return  SDL_GetCPUCount();
        !           244: }
        !           245:  
        !           246: void host_darkmatter(bool state) {
        !           247:     osDarkmatter = state;
        !           248: }
        !           249:                   
        !           250: static double lastVT;
        !           251: static char   report[512];
        !           252: 
        !           253: const char* host_report(double realTime, double hostTime) {
        !           254:     double dVT = hostTime - lastVT;
        !           255: 
        !           256:     double hardClock = hardClockExpected;
        !           257:     hardClock /= hardClockActual == 0 ? 1 : hardClockActual;
        !           258:     
        !           259:     char* r = report;
        !           260:     r += sprintf(r, "[%s] hostTime:%.1f hardClock:%.3fMHz", enableRealtime ? "Max.speed" : "CycleTime", hostTime, hardClock);
        !           261: 
        !           262:     for(int i = NUM_BLANKS; --i >= 0;) {
        !           263:         r += sprintf(r, " %s:%.1fHz", BLANKS[i], (double)vblCounter[i]/dVT);
        !           264:         vblCounter[i] = 0;
        !           265:     }
        !           266:     
        !           267:     lastVT = hostTime;
        !           268: 
        !           269:     return report;
        !           270: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.