mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-26 12:53:43 +02: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:
parent
9e1f717d9b
commit
46626030b2
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user