diff --git a/app/src/fps_counter.c b/app/src/fps_counter.c index bbf71887..f82c00ce 100644 --- a/app/src/fps_counter.c +++ b/app/src/fps_counter.c @@ -1,7 +1,6 @@ #include "fps_counter.h" #include -#include #include "util/log.h" @@ -82,11 +81,11 @@ run_fps_counter(void *data) { sc_cond_wait(&counter->state_cond, &counter->mutex); } while (!counter->interrupted && is_started(counter)) { - uint32_t now = SDL_GetTicks(); + sc_tick now = sc_tick_now(); check_interval_expired(counter, now); assert(counter->next_timestamp > now); - uint32_t remaining = counter->next_timestamp - now; + sc_tick remaining = counter->next_timestamp - now; // ignore the reason (timeout or signaled), we just loop anyway sc_cond_timedwait(&counter->state_cond, &counter->mutex, remaining); @@ -99,7 +98,7 @@ run_fps_counter(void *data) { bool fps_counter_start(struct fps_counter *counter) { sc_mutex_lock(&counter->mutex); - counter->next_timestamp = SDL_GetTicks() + FPS_COUNTER_INTERVAL_MS; + counter->next_timestamp = sc_tick_now() + FPS_COUNTER_INTERVAL_MS; counter->nr_rendered = 0; counter->nr_skipped = 0; sc_mutex_unlock(&counter->mutex); @@ -165,7 +164,7 @@ fps_counter_add_rendered_frame(struct fps_counter *counter) { } sc_mutex_lock(&counter->mutex); - uint32_t now = SDL_GetTicks(); + sc_tick now = sc_tick_now(); check_interval_expired(counter, now); ++counter->nr_rendered; sc_mutex_unlock(&counter->mutex); @@ -178,7 +177,7 @@ fps_counter_add_skipped_frame(struct fps_counter *counter) { } sc_mutex_lock(&counter->mutex); - uint32_t now = SDL_GetTicks(); + sc_tick now = sc_tick_now(); check_interval_expired(counter, now); ++counter->nr_skipped; sc_mutex_unlock(&counter->mutex); diff --git a/app/src/fps_counter.h b/app/src/fps_counter.h index de252586..9609c814 100644 --- a/app/src/fps_counter.h +++ b/app/src/fps_counter.h @@ -24,7 +24,7 @@ struct fps_counter { bool interrupted; unsigned nr_rendered; unsigned nr_skipped; - uint32_t next_timestamp; + sc_tick next_timestamp; }; bool diff --git a/app/src/util/thread.c b/app/src/util/thread.c index de05365d..72e48e3b 100644 --- a/app/src/util/thread.c +++ b/app/src/util/thread.c @@ -2,6 +2,7 @@ #include #include +#include #include "log.h" @@ -123,8 +124,12 @@ sc_cond_wait(sc_cond *cond, sc_mutex *mutex) { } bool -sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, uint32_t ms) { - int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, ms); +sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick ms) { + if (ms < 0) { + return false; // timeout + } + + int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, (uint32_t) ms); #ifndef NDEBUG if (r < 0) { LOGC("Could not wait on condition with timeout: %s", SDL_GetError()); @@ -163,3 +168,11 @@ sc_cond_broadcast(sc_cond *cond) { (void) r; #endif } + +sc_tick +sc_tick_now(void) { + // SDL ticks is an unsigned 32 bits, but this is an implementation detail. + // It wraps if the program runs for more than ~49 days, but in practice we + // can assume it does not. + return (sc_tick) SDL_GetTicks(); +} diff --git a/app/src/util/thread.h b/app/src/util/thread.h index dd3a630e..b3471975 100644 --- a/app/src/util/thread.h +++ b/app/src/util/thread.h @@ -16,6 +16,8 @@ typedef int sc_thread_fn(void *); typedef unsigned sc_thread_id; typedef atomic_uint sc_atomic_thread_id; +typedef int64_t sc_tick; + typedef struct sc_thread { SDL_Thread *thread; } sc_thread; @@ -72,7 +74,7 @@ sc_cond_wait(sc_cond *cond, sc_mutex *mutex); // return true on signaled, false on timeout bool -sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, uint32_t ms); +sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick ms); void sc_cond_signal(sc_cond *cond); @@ -80,4 +82,7 @@ sc_cond_signal(sc_cond *cond); void sc_cond_broadcast(sc_cond *cond); +sc_tick +sc_tick_now(void); + #endif