From 46626030b2043ba3a45f416f04525b37cdc3a072 Mon Sep 17 00:00:00 2001 From: Maarten ter Huurne Date: Fri, 9 Aug 2013 03:58:09 +0200 Subject: [PATCH] Clock: Update current time atomically Writing hours and minutes separately while the string representation is being constructed could lead to an incorrect result on an hour boundary. Avoid this by using an atomic timestamp. With GCC 4.8.1 on MIPS this atomic timestamp is lock free. --- src/clock.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/clock.cpp b/src/clock.cpp index c422ebc..e496b3d 100644 --- a/src/clock.cpp +++ b/src/clock.cpp @@ -4,6 +4,7 @@ #include "inputmanager.h" #include +#include #include @@ -19,7 +20,8 @@ private: unsigned int update(); SDL_TimerID timerID; - int minutes, hours; + struct Timestamp { unsigned char hours, minutes; }; + std::atomic timestamp; }; static std::weak_ptr globalTimer; @@ -91,8 +93,9 @@ void Clock::Timer::start() void Clock::Timer::getTime(unsigned int &hours, unsigned int &minutes) { - hours = this->hours; - minutes = this->minutes; + struct Timestamp ts = timestamp.load(); + hours = ts.hours; + minutes = ts.minutes; } unsigned int Clock::Timer::update() @@ -101,10 +104,12 @@ unsigned int Clock::Timer::update() struct tm result; gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &result); - // TODO: Store both in a single 32-bit write? - minutes = result.tm_min; - hours = result.tm_hour; - DEBUG("Time updated: %02i:%02i:%02i\n", hours, minutes, result.tm_sec); + timestamp.store({ + static_cast(result.tm_hour), + static_cast(result.tm_min) + }); + DEBUG("Time updated: %02i:%02i:%02i\n", + result.tm_hour, result.tm_min, result.tm_sec); // Compute number of milliseconds to next minute boundary. // We don't need high precision, but it is important that any deviation is