1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-07-04 21:28:54 +03:00

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.
This commit is contained in:
Maarten ter Huurne 2013-08-09 03:58:09 +02:00
parent 9e1f717d9b
commit 46626030b2

View File

@ -4,6 +4,7 @@
#include "inputmanager.h" #include "inputmanager.h"
#include <SDL.h> #include <SDL.h>
#include <atomic>
#include <sys/time.h> #include <sys/time.h>
@ -19,7 +20,8 @@ private:
unsigned int update(); unsigned int update();
SDL_TimerID timerID; SDL_TimerID timerID;
int minutes, hours; struct Timestamp { unsigned char hours, minutes; };
std::atomic<Timestamp> timestamp;
}; };
static std::weak_ptr<Clock::Timer> globalTimer; static std::weak_ptr<Clock::Timer> globalTimer;
@ -91,8 +93,9 @@ void Clock::Timer::start()
void Clock::Timer::getTime(unsigned int &hours, unsigned int &minutes) void Clock::Timer::getTime(unsigned int &hours, unsigned int &minutes)
{ {
hours = this->hours; struct Timestamp ts = timestamp.load();
minutes = this->minutes; hours = ts.hours;
minutes = ts.minutes;
} }
unsigned int Clock::Timer::update() unsigned int Clock::Timer::update()
@ -101,10 +104,12 @@ unsigned int Clock::Timer::update()
struct tm result; struct tm result;
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
localtime_r(&tv.tv_sec, &result); localtime_r(&tv.tv_sec, &result);
// TODO: Store both in a single 32-bit write? timestamp.store({
minutes = result.tm_min; static_cast<unsigned char>(result.tm_hour),
hours = result.tm_hour; static_cast<unsigned char>(result.tm_min)
DEBUG("Time updated: %02i:%02i:%02i\n", hours, minutes, result.tm_sec); });
DEBUG("Time updated: %02i:%02i:%02i\n",
result.tm_hour, result.tm_min, result.tm_sec);
// Compute number of milliseconds to next minute boundary. // Compute number of milliseconds to next minute boundary.
// We don't need high precision, but it is important that any deviation is // We don't need high precision, but it is important that any deviation is