Use MONOTONIC_RAW clock for vblank timing

``gettimeofday`` is expensive and suffers from NTP drift which means
we could miss vblank on time updates.
This commit is contained in:
Joshua Ashton 2020-09-02 09:13:24 +01:00 committed by Pierre-Loup A. Griffais
parent 5954361cc3
commit c57eb1bf28

View file

@ -32,6 +32,7 @@
#include <thread>
#include <condition_variable>
#include <mutex>
#include <atomic>
#include <vector>
#include <assert.h>
@ -404,14 +405,18 @@ get_time_in_milliseconds (void)
return tv.tv_sec * 1000 + tv.tv_usec / 1000;
}
struct timeval lastvblankmsgtv;
std::mutex lastvblankmsgtv_lock;
uint64_t get_time_in_nanos()
{
timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
return ts.tv_sec * 1000000000ul + ts.tv_nsec;
}
static std::atomic<uint64_t> g_lastvblank = { 0lu };
void mark_vblank_message_time ( void )
{
std::lock_guard<std::mutex> lock( lastvblankmsgtv_lock );
gettimeofday( &lastvblankmsgtv, NULL );
g_lastvblank = get_time_in_nanos();
}
static void
@ -2828,18 +2833,12 @@ steamcompmgr_main (int argc, char **argv)
if ( ev.xclient.data.l[0] == 24 && ev.xclient.data.l[1] == 8 )
{
// Message from vblankmanager
std::lock_guard<std::mutex> lock( lastvblankmsgtv_lock );
struct timeval vblankmsgreceivedtv = {};
gettimeofday( &vblankmsgreceivedtv, nullptr );
struct timeval timediff = {};
timersub( &vblankmsgreceivedtv, &lastvblankmsgtv, &timediff );
uint64_t vblanktime = g_lastvblank;
uint64_t vblankreceived = get_time_in_nanos();
uint64_t diff = vblankreceived - vblanktime;
// give it 1 ms of slack.. maybe too long
if ( timediff.tv_sec != 0 || timediff.tv_usec > 1000 )
if ( diff > 1000000ul )
{
gpuvis_trace_printf( "ignored stale vblank\n" );
}