--- previous/src/host.c 2018/04/24 19:31:26 1.1.1.1 +++ previous/src/host.c 2018/04/24 19:33:20 1.1.1.2 @@ -12,10 +12,11 @@ #include "host.h" #include "configuration.h" #include "main.h" +#include "log.h" /* NeXTdimension blank handling, see nd_sdl.c */ -void nd_display_blank(void); -void nd_video_blank(void); +void nd_display_blank(int num); +void nd_video_blank(int num); #define NUM_BLANKS 3 static const char* BLANKS[] = { @@ -28,7 +29,7 @@ static Uint64 perfCounterStart; static Sint64 cycleCounterStart; static double cycleSecsStart; static bool isRealtime; -static bool oldIsRealtime; +static bool currentIsRealtime; static double cycleDivisor; static lock_t timeLock; static Uint32 ticksStart; @@ -38,10 +39,16 @@ static Uint64 hardClockActual; static time_t unixTimeStart; static double unixTimeOffset = 0; static double perfFrequency; -static double realTimeOffset; static Uint64 pauseTimeStamp; static bool osDarkmatter; +static inline double real_time() { + double rt = (SDL_GetPerformanceCounter() - perfCounterStart); + rt /= perfFrequency; + return rt; +} + + void host_reset() { perfCounterStart = SDL_GetPerformanceCounter(); pauseTimeStamp = perfCounterStart; @@ -51,11 +58,10 @@ void host_reset() { cycleCounterStart = 0; cycleSecsStart = 0; isRealtime = false; - oldIsRealtime = false; + currentIsRealtime = false; hardClockExpected = 0; hardClockActual = 0; enableRealtime = ConfigureParams.System.bRealtime; - realTimeOffset = 0; osDarkmatter = false; for(int i = NUM_BLANKS; --i >= 0;) { @@ -65,32 +71,32 @@ void host_reset() { cycleDivisor = ConfigureParams.System.nCpuFreq * 1000 * 1000; - SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); + SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH); } void host_blank(int slot, int src, bool state) { - slot = 1 << slot; + int bit = 1 << slot; if(state) { - blank[src] |= slot; + blank[src] |= bit; vblCounter[src]++; } else - blank[src] &= ~slot; + blank[src] &= ~bit; switch (src) { - case ND_DISPLAY: nd_display_blank(); break; - case ND_VIDEO: nd_video_blank(); break; + case ND_DISPLAY: nd_display_blank(slot); break; + case ND_VIDEO: nd_video_blank(slot); break; } } bool host_blank_state(int slot, int src) { - slot = 1 << slot; - return blank[src] & slot; + int bit = 1 << slot; + return blank[src] & bit; } void host_hardclock(int expected, int actual) { - if(abs(actual-expected) > 1000) - fprintf(stderr, "[Hardclock] expected:%dus actual:%dus\n", expected, actual); - else { + if(abs(actual-expected) > 1000) { + Log_Printf(LOG_WARN, "[Hardclock] expected:%dus actual:%dus\n", expected, actual); + } else { hardClockExpected += expected; hardClockActual += actual; } @@ -103,51 +109,47 @@ void host_realtime(bool state) { } double host_time_sec() { - double rt; - double vt; - host_time(&rt, &vt); - return vt; -} - -void host_time(double* realTime, double* hostTime) { - host_lock(&timeLock); + double hostTime; - *realTime = (SDL_GetPerformanceCounter() - perfCounterStart); - *realTime /= perfFrequency; + host_lock(&timeLock); - if(oldIsRealtime) { - *hostTime = *realTime; + if(currentIsRealtime) { + hostTime = real_time(); } else { - *hostTime = nCyclesMainCounter - cycleCounterStart; - *hostTime /= cycleDivisor; - *hostTime += cycleSecsStart; + hostTime = nCyclesMainCounter - cycleCounterStart; + hostTime /= cycleDivisor; + hostTime += cycleSecsStart; } bool state = (isRealtime || osDarkmatter) && enableRealtime; - if(oldIsRealtime != state) { - if(oldIsRealtime) { + if(currentIsRealtime != state) { + double realTime = real_time(); + + if(currentIsRealtime) { // switching from real-time to cycle-time - cycleSecsStart = *realTime; + cycleSecsStart = realTime; cycleCounterStart = nCyclesMainCounter; } else { // switching from cycle-time to real-time - realTimeOffset = *hostTime - *realTime; + double realTimeOffset = hostTime - realTime; if(realTimeOffset > 0) { // if hostTime is in the future, wait until realTime is there as well if(realTimeOffset > 0.01) host_sleep_sec(realTimeOffset); else - while(*realTime < *hostTime) { - *realTime = (SDL_GetPerformanceCounter() - perfCounterStart); - *realTime /= perfFrequency; - } + while(real_time() < hostTime) {} } } - oldIsRealtime = state; + currentIsRealtime = state; } - realTimeOffset = *hostTime - *realTime; - host_unlock(&timeLock); + + return hostTime; +} + +void host_time(double* realTime, double* hostTime) { + *hostTime = host_time_sec(); + *realTime = real_time(); } // Return current time as micro seconds @@ -169,10 +171,10 @@ void host_set_unix_time(time_t now) { } double host_real_time_offset() { - host_lock(&timeLock); - double result = realTimeOffset; - host_unlock(&timeLock); - return result; + double rt; + double vt; + host_time(&rt, &vt); + return vt-rt; } void host_pause_time(bool pausing) { @@ -185,31 +187,30 @@ void host_pause_time(bool pausing) { /*-----------------------------------------------------------------------*/ /** - * Sleep for a given number of micro seconds. We burn cycles by running - * the event loop. + * Sleep for a given number of micro seconds. */ void host_sleep_us(Uint64 us) { #if HAVE_NANOSLEEP struct timespec ts; int ret; - ts.tv_sec = us / 1000000; - ts.tv_nsec = (us % 1000000) * 1000; /* micro sec -> nano sec */ + ts.tv_sec = us / 1000000LL; + ts.tv_nsec = (us % 1000000LL) * 1000; /* micro sec -> nano sec */ /* wait until all the delay is elapsed, including possible interruptions by signals */ do { errno = 0; ret = nanosleep(&ts, &ts); } while ( ret && ( errno == EINTR ) ); /* keep on sleeping if we were interrupted */ #else - Uint64 timeout = host_time_us() + us; - host_sleep_ms(( (Uint32)(ticks_micro / 1000) ) ; /* micro sec -> milli sec */ - while(host_time_us() < timeout) {} + double timeout = us; + timeout /= 1000000.0; + timeout += real_time(); + host_sleep_ms(( (Uint32)(us / 1000LL)) ); + while(real_time() < timeout) {} #endif } void host_sleep_ms(Uint32 ms) { - Uint64 sleep = ms; - sleep *= 1000; - host_sleep_us(sleep); + SDL_Delay(ms); } void host_sleep_sec(double sec) { @@ -230,7 +231,7 @@ void host_unlock(lock_t* lock) { } thread_t* host_thread_create(thread_func_t func, void* data) { - return SDL_CreateThread(func, "[ND] Thread", data); + return SDL_CreateThread(func, "Thread", data); } int host_thread_wait(thread_t* thread) { @@ -267,4 +268,4 @@ const char* host_report(double realTime, lastVT = hostTime; return report; -} \ No newline at end of file +}