Annotation of previous/src/host.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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