Annotation of previous_trunk/src/host.c, revision 1.1.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.